From 321edfcf10ad998c8773b748a6de360778ddfacb Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 30 Jun 2026 00:20:38 +0200 Subject: [PATCH 1/6] tonemapping: Fix up AgX application We're supposed to output linear values there, as sRGB transfer function gets applied either by GL framebuffer or FBOUT later on. min_ev and max_ev also need to be adjusted, as they're tweaked for a pipeline with exposure compensation. The current values lead to a very washed-out image, which was "hidden" by subsequently applying gamma twice. It may make sense to revisit these values in the future to better match the rendering pipeline. --- shaders/tonemapping.glsl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/shaders/tonemapping.glsl b/shaders/tonemapping.glsl index 6b7b1f88..c28a5969 100644 --- a/shaders/tonemapping.glsl +++ b/shaders/tonemapping.glsl @@ -69,12 +69,12 @@ vec3 Agx(vec3 val) 0.0423756549057051, 0.0784336, 0.879142973793104 ); - // DEFAULT_LOG2_MIN = -10.0 - // DEFAULT_LOG2_MAX = +6.5 + // DEFAULT_LOG2_MIN = -6.0 + // DEFAULT_LOG2_MAX = +4.5 // MIDDLE_GRAY = 0.18 // log2(pow(2, VALUE) * MIDDLE_GRAY) - const float min_ev = -12.47393; - const float max_ev = 0.526069; + const float min_ev = -8.47393; + const float max_ev = 2.026069; const float agx_eps = 1e-6; // Input transform (inset) @@ -99,10 +99,7 @@ vec3 AgxEotf(vec3 val) // Inverse input transform (outset) val = agx_mat_inv * val; - // sRGB IEC 61966-2-1 2.2 Exponent Reference EOTF Display. - // If your render target already applies sRGB conversion, replace this with: - // return max(val, vec3(0.0)); - return pow(max(val, vec3(0.0)), vec3(2.2)); + return max(val, vec3(0.0)); } vec3 AgxLook(vec3 val) From 473eae53d2be27eb7772ed61b196a2df89b172ca Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 30 Jun 2026 00:21:40 +0200 Subject: [PATCH 2/6] tonemapping: Reduce saturation boost in AgX 1.4 is quite extreme with our textures. Boost it up, but not as much. --- shaders/tonemapping.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shaders/tonemapping.glsl b/shaders/tonemapping.glsl index c28a5969..9dc74a72 100644 --- a/shaders/tonemapping.glsl +++ b/shaders/tonemapping.glsl @@ -121,7 +121,7 @@ vec3 AgxLook(vec3 val) // Punchy slope = vec3(1.0); power = vec3(1.35); - sat = 1.4; + sat = 1.1; #endif // ASC CDL From b323d78c34bda91c8c497e94742c25a48be96fd4 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 30 Jun 2026 01:37:47 +0200 Subject: [PATCH 3/6] light_common: Adjust ambient and sun diffuse scale Sun needs some oomph. --- shaders/light_common.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shaders/light_common.glsl b/shaders/light_common.glsl index ccaa3989..56be0ae1 100644 --- a/shaders/light_common.glsl +++ b/shaders/light_common.glsl @@ -27,8 +27,8 @@ float metalic = 0.0; // = sharper terminator (more contrast between // lit and shaded faces of the same surface). // --------------------------------------------------------------------- -const float AMBIENT_SCALE = 0.3; -const float SUN_DIFFUSE_SCALE = 0.4; +const float AMBIENT_SCALE = 0.65; +const float SUN_DIFFUSE_SCALE = 1.5; const float SUN_NDOTL_SHARPNESS = 1.25; float length2(vec3 v) From f2a7cc4f98b0d0a249532d92d87c76d5fd88136b Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 30 Jun 2026 01:38:32 +0200 Subject: [PATCH 4/6] opengl33renderer: Adjust sun intensity based on overcast --- rendering/opengl33renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index d06721f7..77ed82c3 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -1875,7 +1875,7 @@ void opengl33_renderer::setup_environment_light(TEnvironmentType const Environme void opengl33_renderer::setup_sunlight_intensity( float const Factor ) { m_sunlight.apply_intensity( Factor ); - light_ubs.lights[ 0 ].intensity = m_sunlight.factor; + light_ubs.lights[ 0 ].intensity = m_sunlight.factor * (1.0f - Global.Overcast * 0.33f); light_ubs.ambient = m_sunlight.ambient * m_sunlight.factor; light_ubo->update( light_ubs ); } From fdc9ea7099d32ad349857c6ba796d3b5a2bacb8a Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 30 Jun 2026 03:31:43 +0200 Subject: [PATCH 5/6] opengl33renderer: Brighten up the clouds With tonemapping, clouds need to stand out above 1.0 to reach proper white levels. Note that this should get disabled if tonemapping isn't used, in case it's made properly configurable in the future. --- rendering/opengl33renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 77ed82c3..e0f71d22 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -2047,7 +2047,7 @@ bool opengl33_renderer::Render(world_environment *Environment) // write cloud color into material TSubModel *mdl = Environment->m_clouds.mdCloud->Root; if (mdl->m_material != null_handle) - m_materials.material(mdl->m_material).params[0] = glm::vec4(color, 1.0f); + m_materials.material(mdl->m_material).params[0] = glm::vec4(color * 2.5f, 1.0f); // render Render(Environment->m_clouds.mdCloud, nullptr, 100.0); From 40c21bd4ba7e7789c35f0e17e27b4b6da9afe3f3 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 30 Jun 2026 05:47:57 +0200 Subject: [PATCH 6/6] skydome: Adjust for external tonemapping Skydome was applying its own tonemapping to look good. Get rid of it and adjust color corrections to look good with a HDR pipeline. --- environment/skydome.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/environment/skydome.cpp b/environment/skydome.cpp index 92cdbaa6..08bde1da 100644 --- a/environment/skydome.cpp +++ b/environment/skydome.cpp @@ -185,7 +185,7 @@ float CSkyDome::PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, void CSkyDome::RebuildColors() { float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f; - auto gammacorrection = glm::mix( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor ); + auto gammacorrection = glm::mix( glm::vec3( 1.0f ), glm::vec3( 0.45f ), twilightfactor ); // get zenith luminance float const chi = ( (4.0f / 9.0f) - (m_turbidity / 120.0f) ) * ( M_PI - (2.0f * m_thetasun) ); @@ -211,7 +211,7 @@ void CSkyDome::RebuildColors() { // trough all vertices glm::vec3 vertex; - glm::vec3 color, colorconverter, shiftedcolor; + glm::vec3 color, colorconverter; for ( unsigned int i = 0; i < m_vertices.size(); ++i ) { // grab it @@ -258,9 +258,7 @@ void CSkyDome::RebuildColors() { colorconverter.z = 1.0f - std::exp( -m_expfactor * colorconverter.z ); } - if( colorconverter.z > 0.85f ) { - colorconverter.z = 0.85f + ( colorconverter.z - 0.85f ) * 0.35f; - } + colorconverter.z = std::pow( std::max( colorconverter.z, 0.0f ), gammacorrection.x ); colorconverter.y = std::clamp( colorconverter.y * Global.m_skysaturationcorrection, 0.0f, 1.0f ); // desaturate sky colour, based on overcast level @@ -277,12 +275,10 @@ void CSkyDome::RebuildColors() { // this height-based factor is reduced the farther the sun is up in the sky float const shiftfactor = std::clamp( std::lerp(heightbasedphase, sunbasedphase, sunbasedphase), 0.0f, 1.0f ); // h = 210 makes for 'typical' sky tone - shiftedcolor = glm::vec3( 210.0f, colorconverter.y, colorconverter.z ); - shiftedcolor = colors::HSVtoRGB( shiftedcolor ); + glm::vec3 const skytonecolor = colors::HSVtoRGB( glm::vec3( 210.0f, 0.5f, colorconverter.z ) ); - color = colors::HSVtoRGB(colorconverter); - - color = glm::mix( color, shiftedcolor, shiftfactor * Global.m_skyhuecorrection ); + color = colors::HSVtoRGB( colorconverter ); + color = glm::mix( color, skytonecolor, shiftfactor * Global.m_skyhuecorrection ); // crude correction for the times where the model breaks (late night) // TODO: use proper night sky calculation for these times instead @@ -295,10 +291,15 @@ void CSkyDome::RebuildColors() { color.y = 0.65f * color.z; } // simple gradient, darkening towards the top - color *= std::clamp( ( 1.0f - vertex.y ), 0.2f, 1.f ); + color *= std::clamp( ( 1.0f - vertex.y * 0.75f ), 0.0f, 1.f ); + + float const horizonboost = 1.5f + m_overcast; + float const horizonbandwidth = 0.2f; // boost tapers to 0 by ~11.5 degrees elevation + float const horizonband = std::clamp( 1.0f - vertex.y / horizonbandwidth, 0.0f, 1.0f ); + + color *= std::lerp( 1.0, horizonboost, horizonband ); + //color *= ( 0.25f - vertex.y ); - // gamma correction - color = glm::pow( color, gammacorrection ); m_colours[ i ] = color; averagecolor += color; if( ( m_vertices.size() - i ) <= ( m_tesselation * 10 + 10 ) ) {