From 7923f7d85700f3efa04596b4a282c595110506df Mon Sep 17 00:00:00 2001 From: Hirek193 Date: Sun, 26 Apr 2026 00:49:45 +0200 Subject: [PATCH] improve shaders once more --- shaders/light_common.glsl | 39 ++++++++++++++++----- shaders/mat_sunlessnormalmap.frag | 9 +++-- shaders/mat_sunlessnormalmap_specgloss.frag | 8 +++-- shaders/tonemapping.glsl | 2 +- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/shaders/light_common.glsl b/shaders/light_common.glsl index b217250a..bee46be9 100644 --- a/shaders/light_common.glsl +++ b/shaders/light_common.glsl @@ -10,6 +10,27 @@ uniform sampler2D headlightmap; float glossiness = 1.0; float metalic = 0.0; +// --------------------------------------------------------------------- +// Lighting balance tunables - tweak these to control overall scene +// exposure without touching tonemapping.glsl. +// +// AMBIENT_SCALE: brightness of SHADED faces (indirect/sky term). +// Lower -> deeper shadows, less burn under bright +// textures. Higher -> flatter / brighter shading. +// +// SUN_DIFFUSE_SCALE: brightness of UNSHADED (sun-lit) faces. Lower +// this to dim hot surfaces in direct sunlight +// without affecting shaded areas. Was 3.5; 2.5 +// calmly fits the ACES tonemap shoulder. +// +// SUN_NDOTL_SHARPNESS: N.L curve on the sun. 1.0 = pure Lambert, higher +// = sharper terminator (more contrast between +// lit and shaded faces of the same surface). +// --------------------------------------------------------------------- +const float AMBIENT_SCALE = 0.65; +const float SUN_DIFFUSE_SCALE = 2.5; +const float SUN_NDOTL_SHARPNESS = 1.25; + float length2(vec3 v) { return dot(v, v); @@ -135,7 +156,10 @@ vec2 calc_headlights(light_s light, vec3 fragnormal) vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) { vec3 basecolor = param[0].rgb; - fragcolor *= basecolor; + // Scale ambient before it gets tinted by basecolor / texture. + // Sun, headlights and emission are added afterwards so they are NOT + // attenuated by AMBIENT_SCALE - this only dims the indirect term. + fragcolor *= basecolor * AMBIENT_SCALE; vec3 emissioncolor = basecolor * emission; @@ -161,19 +185,18 @@ vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float refl vec2 sunlight = calc_dir_light(lights[0], fragnormal); // Sharpen sun N.L falloff so the lit-to-shaded terminator on cab // panels, vehicle bodies and terrain reads as a clear edge rather - // than a soft Lambertian ramp. Stays close to physical Lambert. - float sun_NdotL = pow(sunlight.x, 1.25); + // than a soft Lambertian ramp. Tunable via SUN_NDOTL_SHARPNESS. + float sun_NdotL = pow(sunlight.x, SUN_NDOTL_SHARPNESS); float diffuseamount = sun_NdotL * param[1].x * lights[0].intensity; float shadow1 = 0.0; if (shadowtone < 1.0) shadow1 = (1.0 - shadowtone) * clamp(calc_shadow(), 0.0, 1.0); - // Sun HDR scale lowered from 5.0 -> 3.5: with the previous broken - // identity-Reinhard tonemap the 5x boost just clipped at 1.0; with - // ACES tonemapping in place 3.5 keeps lit areas strong but leaves - // real headroom for spec highlights instead of crushing to white. - fragcolor += lights[0].color * 3.5 * (1.0 - shadow1) * diffuseamount; + // Sun HDR scale -> SUN_DIFFUSE_SCALE (default 2.5). Controls how + // bright sun-lit (unshaded) faces get. Lower this if surfaces in + // direct sun read as too hot/burnt; raise it for more punch. + fragcolor += lights[0].color * SUN_DIFFUSE_SCALE * (1.0 - shadow1) * diffuseamount; for (uint i = 1U; i < lights_count; i++) { diff --git a/shaders/mat_sunlessnormalmap.frag b/shaders/mat_sunlessnormalmap.frag index d5d27702..c0f20f5f 100644 --- a/shaders/mat_sunlessnormalmap.frag +++ b/shaders/mat_sunlessnormalmap.frag @@ -34,7 +34,10 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl { vec3 basecolor = param[0].rgb; - fragcolor *= basecolor; + // Cab interior: dim ambient less than the exterior path because + // ambient is the dominant indoor illumination. 0.80 trims the + // brightest faces without making the cab feel under-lit. + fragcolor *= basecolor * 0.80; vec3 emissioncolor = basecolor * emission; vec3 envcolor = envmap_color(fragnormal); @@ -55,8 +58,8 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl vec2 sunlight = calc_dir_light(lights[0], fragnormal); // Sharpen N.L for stronger contrast between lit and shaded cab - // surfaces (matches light_common.glsl apply_lights). - float sun_NdotL = pow(sunlight.x, 1.25); + // surfaces (uses SUN_NDOTL_SHARPNESS from light_common.glsl). + float sun_NdotL = pow(sunlight.x, SUN_NDOTL_SHARPNESS); float diffuseamount = (sun_NdotL * param[1].x) * lights[0].intensity; fragcolor += envcolor * reflectivity; float specularamount = (sunlight.y * param[1].y * specularity) * lights[0].intensity; diff --git a/shaders/mat_sunlessnormalmap_specgloss.frag b/shaders/mat_sunlessnormalmap_specgloss.frag index aa081379..3da46808 100644 --- a/shaders/mat_sunlessnormalmap_specgloss.frag +++ b/shaders/mat_sunlessnormalmap_specgloss.frag @@ -37,7 +37,9 @@ uniform sampler2D specgloss; vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) { vec3 basecolor = param[0].rgb; - fragcolor *= basecolor; + // Cab interior: dim ambient less than the exterior path - ambient + // is the dominant indoor illumination, but it was still too bright. + fragcolor *= basecolor * 0.80; vec3 emissioncolor = basecolor * emission; @@ -61,8 +63,8 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl vec2 sunlight = calc_dir_light(lights[0], fragnormal); // Sharpen N.L for stronger contrast between lit and shaded cab - // surfaces (matches light_common.glsl apply_lights). - float sun_NdotL = pow(sunlight.x, 1.25); + // surfaces (uses SUN_NDOTL_SHARPNESS from light_common.glsl). + float sun_NdotL = pow(sunlight.x, SUN_NDOTL_SHARPNESS); float diffuseamount = sun_NdotL * param[1].x * lights[0].intensity; float specularamount = sunlight.y * param[1].y * specularity * lights[0].intensity; diff --git a/shaders/tonemapping.glsl b/shaders/tonemapping.glsl index 793e87d6..27fff21b 100644 --- a/shaders/tonemapping.glsl +++ b/shaders/tonemapping.glsl @@ -47,5 +47,5 @@ vec4 tonemap(vec4 x) // just clips HDR>1.0 at the framebuffer -> washed-out / burnt look. // ACES gives a smooth highlight shoulder + slight toe contrast. return FBOUT(vec4(ACESFilm(x.rgb), x.a)); -// return FBOUT(vec4(reinhard(x.rgb), x.a)); + //return FBOUT(vec4(reinhard(x.rgb), x.a)); }