diff --git a/shaders/light_common.glsl b/shaders/light_common.glsl index 56be0ae1..3bfd1066 100644 --- a/shaders/light_common.glsl +++ b/shaders/light_common.glsl @@ -256,17 +256,29 @@ vec3 EnvBRDFApprox(vec3 F0, float roughness, float NoV) return F0 * AB.x + AB.y; } +// Diffuse colour of the submodel (t3d/e3d) or shape, used as the albedo multiplier: +// untextured materials take it as their colour, textured ones multiply the base texture by it +// (same as the legacy renderer's GL_MODULATE). param[0].rgb holds the authored sRGB colour, +// param[1].x its intensity (HSV value unless a material overrides it). +vec3 material_diffuse() +{ + vec3 diffusecolor = pow(max(param[0].rgb, vec3(0.0)), vec3(2.2)); + float value = max(param[0].r, max(param[0].g, param[0].b)); + return (value > 0.0 ? diffusecolor * (param[1].x / value) : vec3(0.0)); +} + // [0] - diffuse, [1] - specular // do magic here vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) { - vec3 basecolor = param[0].rgb; - // Scale ambient before it gets tinted by basecolor / texture. + // Diffuse colour is applied once, to the albedo; the light terms below are not scaled by it again + texturecolor *= material_diffuse(); + // Scale ambient before it gets tinted by the 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; + fragcolor *= AMBIENT_SCALE; - vec3 emissioncolor = basecolor * emission; + vec3 emissioncolor = vec3(emission); vec3 view_dir = normalize(-f_pos.xyz); float NdotV = max(dot(fragnormal, view_dir), 0.0); @@ -302,7 +314,7 @@ vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float refl // panels, vehicle bodies and terrain reads as a clear edge rather // 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 diffuseamount = sun_NdotL * lights[0].intensity; float shadow1 = 0.0; if (shadowtone < 1.0) @@ -317,7 +329,7 @@ vec3 apply_lights(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float refl { light_s light = lights[i]; vec2 part = calc_headlights(light, fragnormal); - fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; + fragcolor += light.color * (part.x + part.y * param[1].y) * light.intensity; } float specularamount = sunlight.y * param[1].y * specularity * lights[0].intensity diff --git a/shaders/mat_colored.frag b/shaders/mat_colored.frag index 80d1d546..620ec43c 100644 --- a/shaders/mat_colored.frag +++ b/shaders/mat_colored.frag @@ -24,7 +24,8 @@ layout(location = 1) out vec4 out_motion; void main() { - vec4 tex_color = vec4(pow(param[0].rgb, vec3(2.2)), param[0].a); + // no texture: the diffuse colour alone makes the albedo, apply_lights() applies it to the white base + vec4 tex_color = vec4(1.0, 1.0, 1.0, param[0].a); // if (tex_color.a < opacity) // discard; @@ -32,7 +33,7 @@ void main() vec3 fragcolor = ambient; vec3 fragnormal = normalize(f_normal); float reflectivity = param[1].z; - float specularity = (tex_color.r + tex_color.g + tex_color.b) * 0.5; + float specularity = dot(pow(param[0].rgb, vec3(2.2)), vec3(0.5)); glossiness = abs(param[1].w); fragcolor = apply_lights(fragcolor, fragnormal, tex_color.rgb, reflectivity, specularity, shadow_tone); diff --git a/shaders/mat_sunlessnormalmap.frag b/shaders/mat_sunlessnormalmap.frag index c0f20f5f..0b3fc7f6 100644 --- a/shaders/mat_sunlessnormalmap.frag +++ b/shaders/mat_sunlessnormalmap.frag @@ -32,14 +32,15 @@ uniform sampler2D normalmap; vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) { - vec3 basecolor = param[0].rgb; + // diffuse colour applied once, to the albedo (see material_diffuse() in light_common.glsl) + texturecolor *= material_diffuse(); // 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; + fragcolor *= 0.80; - vec3 emissioncolor = basecolor * emission; + vec3 emissioncolor = vec3(emission); vec3 envcolor = envmap_color(fragnormal); // yuv path @@ -60,7 +61,7 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl // Sharpen N.L for stronger contrast between lit and shaded cab // 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 diffuseamount = sun_NdotL * lights[0].intensity; fragcolor += envcolor * reflectivity; float specularamount = (sunlight.y * param[1].y * specularity) * lights[0].intensity; glossiness = abs(param[1].w); @@ -79,7 +80,7 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl // else if (light.type == LIGHT_HEADLIGHTS) part = calc_headlights(light, fragnormal); - fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; + fragcolor += light.color * (part.x + part.y * param[1].y) * light.intensity; } if (shadowtone < 1.0) diff --git a/shaders/mat_sunlessnormalmap_specgloss.frag b/shaders/mat_sunlessnormalmap_specgloss.frag index 48e71435..21cc9f6e 100644 --- a/shaders/mat_sunlessnormalmap_specgloss.frag +++ b/shaders/mat_sunlessnormalmap_specgloss.frag @@ -36,12 +36,13 @@ uniform sampler2D specgloss; vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, float reflectivity, float specularity, float shadowtone) { - vec3 basecolor = param[0].rgb; + // diffuse colour applied once, to the albedo (see material_diffuse() in light_common.glsl) + texturecolor *= material_diffuse(); // 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; + fragcolor *= 0.80; - vec3 emissioncolor = basecolor * emission; + vec3 emissioncolor = vec3(emission); vec3 view_dir = normalize(-f_pos.xyz); float NdotV = max(dot(fragnormal, view_dir), 0.0); @@ -71,7 +72,7 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl // Sharpen N.L for stronger contrast between lit and shaded cab // 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 diffuseamount = sun_NdotL * lights[0].intensity; float specularamount = sunlight.y * param[1].y * specularity * lights[0].intensity; @@ -79,7 +80,7 @@ vec3 apply_lights_sunless(vec3 fragcolor, vec3 fragnormal, vec3 texturecolor, fl { light_s light = lights[i]; vec2 part = calc_headlights(light, fragnormal); - fragcolor += light.color * (part.x * param[1].x + part.y * param[1].y) * light.intensity; + fragcolor += light.color * (part.x + part.y * param[1].y) * light.intensity; } if (shadowtone < 1.0)