Smooth day-night transitions

master
Perttu Ahola 2012-12-02 18:02:04 +02:00
parent 041585a78e
commit 804a7875a2
7 changed files with 87 additions and 23 deletions

View File

@ -544,7 +544,7 @@ void Camera::wield(const ItemStack &item)
void Camera::drawWieldedTool() void Camera::drawWieldedTool()
{ {
// Set vertex colors of wield mesh according to light level // Set vertex colors of wield mesh according to light level
u8 li = decode_light(m_wieldlight); u8 li = m_wieldlight;
video::SColor color(255,li,li,li); video::SColor color(255,li,li,li);
setMeshColor(m_wieldnode->getMesh(), color); setMeshColor(m_wieldnode->getMesh(), color);

View File

@ -20,23 +20,49 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef DAYNIGHTRATIO_HEADER #ifndef DAYNIGHTRATIO_HEADER
#define DAYNIGHTRATIO_HEADER #define DAYNIGHTRATIO_HEADER
inline u32 time_to_daynight_ratio(u32 time_of_day) inline u32 time_to_daynight_ratio(float time_of_day, bool smooth)
{ {
s32 t = time_of_day%24000; float t = time_of_day;
if(t < 4500 || t >= 19500) if(t < 0)
return 150; t += ((int)(-t)/24000)*24000;
else if(t < 4750 || t >= 19250) if(t >= 24000)
return 250; t -= ((int)(t)/24000)*24000;
else if(t < 5000 || t >= 19000) if(t > 12000)
return 350; t = 24000 - t;
else if(t < 5250 || t >= 18750) float values[][2] = {
return 500; {4250+125, 150},
else if(t < 5500 || t >= 18500) {4500+125, 150},
return 675; {4750+125, 250},
else if(t < 5750 || t >= 18250) {5000+125, 350},
return 875; {5250+125, 500},
else {5500+125, 675},
{5750+125, 875},
{6000+125, 1000},
{6250+125, 1000},
};
if(!smooth){
float lastt = values[0][0];
for(u32 i=1; i<sizeof(values)/sizeof(*values); i++){
float t0 = values[i][0];
float switch_t = (t0 + lastt) / 2;
lastt = t0;
if(switch_t <= t)
continue;
return values[i][1];
}
return 1000; return 1000;
} else {
for(u32 i=0; i<sizeof(values)/sizeof(*values); i++){
if(values[i][0] <= t)
continue;
if(i == 0)
return values[i][1];
float td0 = values[i][0] - values[i-1][0];
float f = (t - values[i-1][0]) / td0;
return f * values[i][1] + (1.0 - f) * values[i-1][1];
}
return 1000;
}
} }
#endif #endif

View File

@ -203,7 +203,8 @@ void Environment::printPlayers(std::ostream &o)
u32 Environment::getDayNightRatio() u32 Environment::getDayNightRatio()
{ {
return time_to_daynight_ratio(m_time_of_day); bool smooth = (g_settings->getS32("enable_shaders") != 0);
return time_to_daynight_ratio(m_time_of_day_f*24000, smooth);
} }
void Environment::stepTimeOfDay(float dtime) void Environment::stepTimeOfDay(float dtime)
@ -2132,15 +2133,15 @@ void ClientEnvironment::step(float dtime)
} }
// Update lighting on all players on client // Update lighting on all players on client
u8 light = LIGHT_MAX; float light = 1.0;
try{ try{
// Get node at head // Get node at head
v3s16 p = player->getLightPosition(); v3s16 p = player->getLightPosition();
MapNode n = m_map->getNode(p); MapNode n = m_map->getNode(p);
light = n.getLightBlend(getDayNightRatio(), m_gamedef->ndef()); light = n.getLightBlendF1((float)getDayNightRatio()/1000, m_gamedef->ndef());
} }
catch(InvalidPositionException &e){ catch(InvalidPositionException &e){
light = blend_light(getDayNightRatio(), LIGHT_SUN, 0); light = blend_light_f1((float)getDayNightRatio()/1000, LIGHT_SUN, 0);
} }
player->light = light; player->light = light;
} }

View File

@ -2505,8 +2505,7 @@ void the_game(
Calculate general brightness Calculate general brightness
*/ */
u32 daynight_ratio = client.getEnv().getDayNightRatio(); u32 daynight_ratio = client.getEnv().getDayNightRatio();
float time_brightness = (float)decode_light( float time_brightness = decode_light_f((float)daynight_ratio/1000.0);
(daynight_ratio * LIGHT_SUN) / 1000) / 255.0;
float direct_brightness = 0; float direct_brightness = 0;
bool sunlight_seen = false; bool sunlight_seen = false;
if(g_settings->getBool("free_move")){ if(g_settings->getBool("free_move")){

View File

@ -85,6 +85,24 @@ inline u8 decode_light(u8 light)
return light_decode_table[light]; return light_decode_table[light];
} }
// 0.0 <= light <= 1.0
// 0.0 <= return value <= 1.0
inline float decode_light_f(float light_f)
{
s32 i = (u32)(light_f * LIGHT_MAX + 0.5);
if(i <= 0)
return (float)light_decode_table[0] / 255.0;
if(i >= LIGHT_MAX)
return (float)light_decode_table[LIGHT_MAX] / 255.0;
float v1 = (float)light_decode_table[i-1] / 255.0;
float v2 = (float)light_decode_table[i] / 255.0;
float f0 = (float)i - 0.5;
float f = light_f * LIGHT_MAX - f0;
return f * v2 + (1.0 - f) * v1;
}
// 0 <= daylight_factor <= 1000 // 0 <= daylight_factor <= 1000
// 0 <= lightday, lightnight <= LIGHT_SUN // 0 <= lightday, lightnight <= LIGHT_SUN
// 0 <= return value <= LIGHT_SUN // 0 <= return value <= LIGHT_SUN
@ -97,5 +115,15 @@ inline u8 blend_light(u32 daylight_factor, u8 lightday, u8 lightnight)
return l; return l;
} }
// 0.0 <= daylight_factor <= 1.0
// 0 <= lightday, lightnight <= LIGHT_SUN
// 0 <= return value <= 255
inline u8 blend_light_f1(float daylight_factor, u8 lightday, u8 lightnight)
{
u8 l = ((daylight_factor * decode_light(lightday) +
(1.0-daylight_factor) * decode_light(lightnight)));
return l;
}
#endif #endif

View File

@ -163,6 +163,16 @@ struct MapNode
return blend_light(daylight_factor, lightday, lightnight); return blend_light(daylight_factor, lightday, lightnight);
} }
// 0.0 <= daylight_factor <= 1.0
// 0 <= return value <= LIGHT_SUN
u8 getLightBlendF1(float daylight_factor, INodeDefManager *nodemgr) const
{
u8 lightday = 0;
u8 lightnight = 0;
getLightBanks(lightday, lightnight, nodemgr);
return blend_light_f1(daylight_factor, lightday, lightnight);
}
u8 getFaceDir(INodeDefManager *nodemgr) const; u8 getFaceDir(INodeDefManager *nodemgr) const;
u8 getWallMounted(INodeDefManager *nodemgr) const; u8 getWallMounted(INodeDefManager *nodemgr) const;
v3s16 getWallMountedDir(INodeDefManager *nodemgr) const; v3s16 getWallMountedDir(INodeDefManager *nodemgr) const;

View File

@ -3604,7 +3604,7 @@ private:
if(lua_isnumber(L, 3)) if(lua_isnumber(L, 3))
time_of_day = 24000.0 * lua_tonumber(L, 3); time_of_day = 24000.0 * lua_tonumber(L, 3);
time_of_day %= 24000; time_of_day %= 24000;
u32 dnr = time_to_daynight_ratio(time_of_day); u32 dnr = time_to_daynight_ratio(time_of_day, true);
MapNode n = env->getMap().getNodeNoEx(pos); MapNode n = env->getMap().getNodeNoEx(pos);
try{ try{
MapNode n = env->getMap().getNode(pos); MapNode n = env->getMap().getNode(pos);