From: Perttu Ahola Date: Sun, 2 Dec 2012 16:02:04 +0000 (+0200) Subject: Smooth day-night transitions X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=804a7875a2018f3d8cb3fbe917c11ecc1666d25a;p=zefram%2Fminetest%2Fminetest_engine.git Smooth day-night transitions --- diff --git a/src/camera.cpp b/src/camera.cpp index ca2a6eb5..1b9a8c76 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -544,7 +544,7 @@ void Camera::wield(const ItemStack &item) void Camera::drawWieldedTool() { // 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); setMeshColor(m_wieldnode->getMesh(), color); diff --git a/src/daynightratio.h b/src/daynightratio.h index 9b31ecdd..96c6729e 100644 --- a/src/daynightratio.h +++ b/src/daynightratio.h @@ -20,23 +20,49 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef 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; - if(t < 4500 || t >= 19500) - return 150; - else if(t < 4750 || t >= 19250) - return 250; - else if(t < 5000 || t >= 19000) - return 350; - else if(t < 5250 || t >= 18750) - return 500; - else if(t < 5500 || t >= 18500) - return 675; - else if(t < 5750 || t >= 18250) - return 875; - else + float t = time_of_day; + if(t < 0) + t += ((int)(-t)/24000)*24000; + if(t >= 24000) + t -= ((int)(t)/24000)*24000; + if(t > 12000) + t = 24000 - t; + float values[][2] = { + {4250+125, 150}, + {4500+125, 150}, + {4750+125, 250}, + {5000+125, 350}, + {5250+125, 500}, + {5500+125, 675}, + {5750+125, 875}, + {6000+125, 1000}, + {6250+125, 1000}, + }; + if(!smooth){ + float lastt = values[0][0]; + for(u32 i=1; igetS32("enable_shaders") != 0); + return time_to_daynight_ratio(m_time_of_day_f*24000, smooth); } void Environment::stepTimeOfDay(float dtime) @@ -2132,15 +2133,15 @@ void ClientEnvironment::step(float dtime) } // Update lighting on all players on client - u8 light = LIGHT_MAX; + float light = 1.0; try{ // Get node at head v3s16 p = player->getLightPosition(); 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){ - light = blend_light(getDayNightRatio(), LIGHT_SUN, 0); + light = blend_light_f1((float)getDayNightRatio()/1000, LIGHT_SUN, 0); } player->light = light; } diff --git a/src/game.cpp b/src/game.cpp index fc780a80..5c3805c3 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2505,8 +2505,7 @@ void the_game( Calculate general brightness */ u32 daynight_ratio = client.getEnv().getDayNightRatio(); - float time_brightness = (float)decode_light( - (daynight_ratio * LIGHT_SUN) / 1000) / 255.0; + float time_brightness = decode_light_f((float)daynight_ratio/1000.0); float direct_brightness = 0; bool sunlight_seen = false; if(g_settings->getBool("free_move")){ diff --git a/src/light.h b/src/light.h index 218af348..f1c458ad 100644 --- a/src/light.h +++ b/src/light.h @@ -85,6 +85,24 @@ inline u8 decode_light(u8 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 <= lightday, lightnight <= LIGHT_SUN // 0 <= return value <= LIGHT_SUN @@ -97,5 +115,15 @@ inline u8 blend_light(u32 daylight_factor, u8 lightday, u8 lightnight) 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 diff --git a/src/mapnode.h b/src/mapnode.h index a95497ef..de2529e4 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -163,6 +163,16 @@ struct MapNode 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 getWallMounted(INodeDefManager *nodemgr) const; v3s16 getWallMountedDir(INodeDefManager *nodemgr) const; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index e5815c46..e26e880a 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -3604,7 +3604,7 @@ private: if(lua_isnumber(L, 3)) time_of_day = 24000.0 * lua_tonumber(L, 3); 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); try{ MapNode n = env->getMap().getNode(pos);