Allow the server to control fog_distance and fog_start via the sky-api (#13448)

This commit is contained in:
lhofhansl 2023-06-30 19:11:17 -07:00 committed by GitHub
parent dde8f0e20a
commit 0ade097e99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 80 additions and 21 deletions

@ -3,6 +3,7 @@ uniform sampler2D baseTexture;
uniform vec3 dayLight; uniform vec3 dayLight;
uniform vec4 skyBgColor; uniform vec4 skyBgColor;
uniform float fogDistance; uniform float fogDistance;
uniform float fogShadingParameter;
uniform vec3 eyePosition; uniform vec3 eyePosition;
// The cameraOffset is the current center of the visible world. // The cameraOffset is the current center of the visible world.
@ -49,9 +50,6 @@ varying vec3 tsEyeVec;
varying vec3 lightVec; varying vec3 lightVec;
varying vec3 tsLightVec; varying vec3 tsLightVec;
const float fogStart = FOG_START;
const float fogShadingParameter = 1.0 / ( 1.0 - fogStart);
#ifdef ENABLE_DYNAMIC_SHADOWS #ifdef ENABLE_DYNAMIC_SHADOWS
// assuming near is always 1.0 // assuming near is always 1.0

@ -3,6 +3,7 @@ uniform sampler2D baseTexture;
uniform vec3 dayLight; uniform vec3 dayLight;
uniform vec4 skyBgColor; uniform vec4 skyBgColor;
uniform float fogDistance; uniform float fogDistance;
uniform float fogShadingParameter;
uniform vec3 eyePosition; uniform vec3 eyePosition;
// The cameraOffset is the current center of the visible world. // The cameraOffset is the current center of the visible world.
@ -48,9 +49,6 @@ varying float nightRatio;
varying float vIDiff; varying float vIDiff;
const float fogStart = FOG_START;
const float fogShadingParameter = 1.0 / (1.0 - fogStart);
#ifdef ENABLE_DYNAMIC_SHADOWS #ifdef ENABLE_DYNAMIC_SHADOWS
// assuming near is always 1.0 // assuming near is always 1.0

@ -7740,6 +7740,18 @@ child will follow movement and rotation of that bone.
abides by, `"custom"` uses `sun_tint` and `moon_tint`, while abides by, `"custom"` uses `sun_tint` and `moon_tint`, while
`"default"` uses the classic Minetest sun and moon tinting. `"default"` uses the classic Minetest sun and moon tinting.
Will use tonemaps, if set to `"default"`. (default: `"default"`) Will use tonemaps, if set to `"default"`. (default: `"default"`)
* `fog`: A table with following optional fields:
* `fog_distance`: integer, set an upper bound the client's viewing_range (inluding range_all).
By default, fog_distance is controlled by the client's viewing_range, and this field is not set.
Any value >= 0 sets the desired upper bound for the client's viewing_range and disables range_all.
Any value < 0, resets the behavior to being client-controlled.
(default: -1)
* `fog_start`: float, override the client's fog_start.
Fraction of the visible distance at which fog starts to be rendered.
By default, fog_start is controlled by the client's `fog_start` setting, and this field is not set.
Any value between [0.0, 0.99] set the fog_start as a fraction of the viewing_range.
Any value < 0, resets the behavior to being client-controlled.
(default: -1)
* `set_sky(base_color, type, {texture names}, clouds)` * `set_sky(base_color, type, {texture names}, clouds)`
* Deprecated. Use `set_sky(sky_parameters)` * Deprecated. Use `set_sky(sky_parameters)`
* `base_color`: ColorSpec, defaults to white * `base_color`: ColorSpec, defaults to white

@ -372,6 +372,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
bool m_fog_enabled; bool m_fog_enabled;
CachedPixelShaderSetting<float, 4> m_sky_bg_color; CachedPixelShaderSetting<float, 4> m_sky_bg_color;
CachedPixelShaderSetting<float> m_fog_distance; CachedPixelShaderSetting<float> m_fog_distance;
CachedPixelShaderSetting<float> m_fog_shading_parameter;
CachedVertexShaderSetting<float> m_animation_timer_vertex; CachedVertexShaderSetting<float> m_animation_timer_vertex;
CachedPixelShaderSetting<float> m_animation_timer_pixel; CachedPixelShaderSetting<float> m_animation_timer_pixel;
CachedVertexShaderSetting<float> m_animation_timer_delta_vertex; CachedVertexShaderSetting<float> m_animation_timer_delta_vertex;
@ -431,6 +432,7 @@ public:
m_fog_range(fog_range), m_fog_range(fog_range),
m_sky_bg_color("skyBgColor"), m_sky_bg_color("skyBgColor"),
m_fog_distance("fogDistance"), m_fog_distance("fogDistance"),
m_fog_shading_parameter("fogShadingParameter"),
m_animation_timer_vertex("animationTimer"), m_animation_timer_vertex("animationTimer"),
m_animation_timer_pixel("animationTimer"), m_animation_timer_pixel("animationTimer"),
m_animation_timer_delta_vertex("animationTimerDelta"), m_animation_timer_delta_vertex("animationTimerDelta"),
@ -496,7 +498,10 @@ public:
if (m_fog_enabled && !*m_force_fog_off) if (m_fog_enabled && !*m_force_fog_off)
fog_distance = *m_fog_range; fog_distance = *m_fog_range;
float fog_shading_parameter = 1.0 / ( 1.0 - m_sky->getFogStart());
m_fog_distance.set(&fog_distance, services); m_fog_distance.set(&fog_distance, services);
m_fog_shading_parameter.set(&fog_shading_parameter, services);
u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio(); u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
video::SColorf sunlight; video::SColorf sunlight;
@ -961,7 +966,6 @@ private:
f32 m_cache_joystick_frustum_sensitivity; f32 m_cache_joystick_frustum_sensitivity;
f32 m_repeat_place_time; f32 m_repeat_place_time;
f32 m_cache_cam_smoothing; f32 m_cache_cam_smoothing;
f32 m_cache_fog_start;
bool m_invert_mouse; bool m_invert_mouse;
bool m_enable_hotbar_mouse_wheel; bool m_enable_hotbar_mouse_wheel;
@ -2490,6 +2494,9 @@ void Game::increaseViewRange()
range_new = 4000; range_new = 4000;
std::wstring msg = fwgettext("Viewing range is at maximum: %d", range_new); std::wstring msg = fwgettext("Viewing range is at maximum: %d", range_new);
m_game_ui->showStatusText(msg); m_game_ui->showStatusText(msg);
} else if (sky->getFogDistance() >= 0 && range_new > sky->getFogDistance()) {
std::wstring msg = fwgettext("Viewing range changed to %d, but limited to %d set by server", range_new, sky->getFogDistance());
m_game_ui->showStatusText(msg);
} else { } else {
std::wstring msg = fwgettext("Viewing range changed to %d", range_new); std::wstring msg = fwgettext("Viewing range changed to %d", range_new);
m_game_ui->showStatusText(msg); m_game_ui->showStatusText(msg);
@ -2507,6 +2514,9 @@ void Game::decreaseViewRange()
range_new = 20; range_new = 20;
std::wstring msg = fwgettext("Viewing range is at minimum: %d", range_new); std::wstring msg = fwgettext("Viewing range is at minimum: %d", range_new);
m_game_ui->showStatusText(msg); m_game_ui->showStatusText(msg);
} else if (sky->getFogDistance() >= 0 && range_new > sky->getFogDistance()) {
std::wstring msg = fwgettext("Viewing range changed to %d, but limited to %d set by server", range_new, sky->getFogDistance());
m_game_ui->showStatusText(msg);
} else { } else {
std::wstring msg = fwgettext("Viewing range changed to %d", range_new); std::wstring msg = fwgettext("Viewing range changed to %d", range_new);
m_game_ui->showStatusText(msg); m_game_ui->showStatusText(msg);
@ -2518,10 +2528,15 @@ void Game::decreaseViewRange()
void Game::toggleFullViewRange() void Game::toggleFullViewRange()
{ {
draw_control->range_all = !draw_control->range_all; draw_control->range_all = !draw_control->range_all;
if (draw_control->range_all) if (draw_control->range_all) {
m_game_ui->showTranslatedStatusText("Enabled unlimited viewing range"); if (sky->getFogDistance() >= 0) {
else m_game_ui->showTranslatedStatusText("The server has disabled unlimited viewing range");
} else {
m_game_ui->showTranslatedStatusText("Enabled unlimited viewing range");
}
} else {
m_game_ui->showTranslatedStatusText("Disabled unlimited viewing range"); m_game_ui->showTranslatedStatusText("Disabled unlimited viewing range");
}
} }
@ -2996,6 +3011,20 @@ void Game::handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam)
// Orbit Tilt: // Orbit Tilt:
sky->setBodyOrbitTilt(event->set_sky->body_orbit_tilt); sky->setBodyOrbitTilt(event->set_sky->body_orbit_tilt);
// fog
// do not override a potentially smaller client setting.
sky->setFogDistance(event->set_sky->fog_distance);
// if the fog distance is reset, switch back to the client's viewing_range
if (event->set_sky->fog_distance < 0)
draw_control->wanted_range = g_settings->getS16("viewing_range");
if (event->set_sky->fog_start >= 0)
sky->setFogStart(rangelim(event->set_sky->fog_start, 0.0f, 0.99f));
else
sky->setFogStart(rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f));
delete event->set_sky; delete event->set_sky;
} }
@ -3915,7 +3944,10 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
Fog range Fog range
*/ */
if (draw_control->range_all) { if (sky->getFogDistance() >= 0) {
draw_control->wanted_range = MYMIN(draw_control->wanted_range, sky->getFogDistance());
}
if (draw_control->range_all && sky->getFogDistance() < 0) {
runData.fog_range = 100000 * BS; runData.fog_range = 100000 * BS;
} else { } else {
runData.fog_range = draw_control->wanted_range * BS; runData.fog_range = draw_control->wanted_range * BS;
@ -4006,12 +4038,11 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
/* /*
Fog Fog
*/ */
if (m_cache_enable_fog) { if (m_cache_enable_fog) {
driver->setFog( driver->setFog(
sky->getBgColor(), sky->getBgColor(),
video::EFT_FOG_LINEAR, video::EFT_FOG_LINEAR,
runData.fog_range * m_cache_fog_start, runData.fog_range * sky->getFogStart(),
runData.fog_range * 1.0, runData.fog_range * 1.0,
0.01, 0.01,
false, // pixel fog false, // pixel fog
@ -4284,15 +4315,12 @@ void Game::readSettings()
m_cache_enable_noclip = g_settings->getBool("noclip"); m_cache_enable_noclip = g_settings->getBool("noclip");
m_cache_enable_free_move = g_settings->getBool("free_move"); m_cache_enable_free_move = g_settings->getBool("free_move");
m_cache_fog_start = g_settings->getFloat("fog_start");
m_cache_cam_smoothing = 0; m_cache_cam_smoothing = 0;
if (g_settings->getBool("cinematic")) if (g_settings->getBool("cinematic"))
m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing"); m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing");
else else
m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing"); m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing");
m_cache_fog_start = rangelim(m_cache_fog_start, 0.0f, 0.99f);
m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f); m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f);
m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0); m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0);

@ -752,8 +752,6 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n"; shaders_header << "#define ENABLE_WAVING_PLANTS " << g_settings->getBool("enable_waving_plants") << "\n";
shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n"; shaders_header << "#define ENABLE_TONE_MAPPING " << g_settings->getBool("tone_mapping") << "\n";
shaders_header << "#define FOG_START " << core::clamp(g_settings->getFloat("fog_start"), 0.0f, 0.99f) << "\n";
if (g_settings->getBool("enable_dynamic_shadows")) { if (g_settings->getBool("enable_dynamic_shadows")) {
shaders_header << "#define ENABLE_DYNAMIC_SHADOWS 1\n"; shaders_header << "#define ENABLE_DYNAMIC_SHADOWS 1\n";
if (g_settings->getBool("shadow_map_color")) if (g_settings->getBool("shadow_map_color"))

@ -98,6 +98,7 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
m_directional_colored_fog = g_settings->getBool("directional_colored_fog"); m_directional_colored_fog = g_settings->getBool("directional_colored_fog");
m_sky_params.body_orbit_tilt = g_settings->getFloat("shadow_sky_body_orbit_tilt", -60., 60.); m_sky_params.body_orbit_tilt = g_settings->getFloat("shadow_sky_body_orbit_tilt", -60., 60.);
m_sky_params.fog_start = rangelim(g_settings->getFloat("fog_start"), 0.0f, 0.99f);
setStarCount(1000); setStarCount(1000);
} }

@ -114,6 +114,11 @@ public:
void addTextureToSkybox(const std::string &texture, int material_id, void addTextureToSkybox(const std::string &texture, int material_id,
ITextureSource *tsrc); ITextureSource *tsrc);
const video::SColorf &getCurrentStarColor() const { return m_star_color; } const video::SColorf &getCurrentStarColor() const { return m_star_color; }
void setFogDistance(s16 fog_distance) { m_sky_params.fog_distance = fog_distance; }
s16 getFogDistance() const { return m_sky_params.fog_distance; }
void setFogStart(float fog_start) { m_sky_params.fog_start = fog_start; }
float getFogStart() const { return m_sky_params.fog_start; }
private: private:
aabb3f m_box; aabb3f m_box;

@ -1395,9 +1395,13 @@ void Client::handleCommand_HudSetSky(NetworkPacket* pkt)
>> skybox.sky_color.indoors; >> skybox.sky_color.indoors;
} }
try { if (pkt->getRemainingBytes() >= 4) {
*pkt >> skybox.body_orbit_tilt; *pkt >> skybox.body_orbit_tilt;
} catch (PacketError &e) {} }
if (pkt->getRemainingBytes() >= 6) {
*pkt >> skybox.fog_distance >> skybox.fog_start;
}
ClientEvent *event = new ClientEvent(); ClientEvent *event = new ClientEvent();
event->type = CE_SET_SKY; event->type = CE_SET_SKY;

@ -1803,6 +1803,11 @@ int ObjectRef::l_set_sky(lua_State *L)
// pop "sky_color" table // pop "sky_color" table
lua_pop(L, 1); lua_pop(L, 1);
} }
lua_getfield(L, 2, "fog");
if (lua_istable(L, -1)) {
sky_params.fog_distance = getintfield_default(L, -1, "fog_distance", sky_params.fog_distance);
sky_params.fog_start = getfloatfield_default(L, -1, "fog_start", sky_params.fog_start);
}
} else { } else {
// Handle old set_sky calls, and log deprecated: // Handle old set_sky calls, and log deprecated:
log_deprecated(L, "Deprecated call to set_sky, please check lua_api.md"); log_deprecated(L, "Deprecated call to set_sky, please check lua_api.md");
@ -1923,7 +1928,6 @@ int ObjectRef::l_get_sky(lua_State *L)
lua_pushnumber(L, skybox_params.body_orbit_tilt); lua_pushnumber(L, skybox_params.body_orbit_tilt);
lua_setfield(L, -2, "body_orbit_tilt"); lua_setfield(L, -2, "body_orbit_tilt");
} }
lua_newtable(L); lua_newtable(L);
s16 i = 1; s16 i = 1;
for (const std::string &texture : skybox_params.textures) { for (const std::string &texture : skybox_params.textures) {
@ -1936,6 +1940,14 @@ int ObjectRef::l_get_sky(lua_State *L)
push_sky_color(L, skybox_params); push_sky_color(L, skybox_params);
lua_setfield(L, -2, "sky_color"); lua_setfield(L, -2, "sky_color");
lua_newtable(L); // fog
lua_pushinteger(L, skybox_params.fog_distance >= 0 ? skybox_params.fog_distance : -1);
lua_setfield(L, -2, "fog_distance");
lua_pushnumber(L, skybox_params.fog_start >= 0 ? skybox_params.fog_start : -1.0f);
lua_setfield(L, -2, "fog_start");
lua_setfield(L, -2, "fog");
return 1; return 1;
} }

@ -1846,6 +1846,7 @@ void Server::SendSetSky(session_t peer_id, const SkyboxParams &params)
} }
pkt << params.body_orbit_tilt; pkt << params.body_orbit_tilt;
pkt << params.fog_distance << params.fog_start;
} }
Send(&pkt); Send(&pkt);

@ -44,6 +44,8 @@ struct SkyboxParams
video::SColor fog_moon_tint; video::SColor fog_moon_tint;
std::string fog_tint_type; std::string fog_tint_type;
float body_orbit_tilt { INVALID_SKYBOX_TILT }; float body_orbit_tilt { INVALID_SKYBOX_TILT };
s16 fog_distance { -1 };
float fog_start { -1.0f };
}; };
struct SunParams struct SunParams