diff --git a/src/engine/renderer/glsl_source/lightMapping_fp.glsl b/src/engine/renderer/glsl_source/lightMapping_fp.glsl index dc1dda0208..a420c61b3c 100644 --- a/src/engine/renderer/glsl_source/lightMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_fp.glsl @@ -88,8 +88,25 @@ void main() vec3 lightDir = normalize(2.0 * deluxe.xyz - 1.0); + // Lightmaps generated by q3map2 don't store the raw light value, but + // they store light premultiplied with the dot product of the light + // direction and surface normal. The line is just an attempt to reverse + // that and get the original light values. + // The lightmap stores the light in this way because for the diffuse + // lighting formula the outgoing light is equal to the incoming light + // multiplied by the above dot product multiplied by the surface albedo. + // So this premultiplication means that the diffuse lighting value can + // be calculated with a single multiply operation. + // But specular lighting and/or normal mapping formulas are more complex, + // and so you need the true light value to get correct lighting. + // Obviously the data is not good enough to recover the original color + // in all cases. The lower bound was an arbitrary chose factor to + // prevent too small divisors resulting in too bright lights. Increasing + // the value should reduce these artifacts. -- gimhael + // https://github.com/DaemonEngine/Daemon/issues/299#issuecomment-606186347 + // divide by cosine term to restore original light color - lightColor /= clamp(dot(normalize(var_Normal), lightDir), 0.004, 1.0); + lightColor /= clamp(dot(normalize(var_Normal), lightDir), 0.3, 1.0); computeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color); #else // !USE_DELUXE_MAPPING