mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Smooth day-night transitions
This commit is contained in:
		@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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; 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;
 | 
			
		||||
	} 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
 | 
			
		||||
 
 | 
			
		||||
@@ -203,7 +203,8 @@ void Environment::printPlayers(std::ostream &o)
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
@@ -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;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -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")){
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								src/light.h
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user