From b06649097f9b403f3e8cc5d9c565b84c214affae Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 3 Oct 2024 16:55:01 +0200 Subject: [PATCH] Use inverse square distance attenuation for PBR materials --- .../static/shaders/scene/lightmodel_pbr.glsl | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/wadsrc/static/shaders/scene/lightmodel_pbr.glsl b/wadsrc/static/shaders/scene/lightmodel_pbr.glsl index 317aaf6a2..7c7f252a8 100644 --- a/wadsrc/static/shaders/scene/lightmodel_pbr.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_pbr.glsl @@ -45,23 +45,22 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0); } -float quadraticDistanceAttenuation(vec4 lightpos) -{ - float strength = (1.0 + lightpos.w * lightpos.w * 0.25) * 0.5; - - vec3 distVec = lightpos.xyz - pixelpos.xyz; - float attenuation = strength / (1.0 + dot(distVec, distVec)); - if (attenuation <= 1.0 / 256.0) return 0.0; - - return attenuation; -} - float linearDistanceAttenuation(vec4 lightpos) { float lightdistance = distance(lightpos.xyz, pixelpos.xyz); return clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0); } +float inverseSquareDistanceAttenuation(vec4 lightpos) +{ + float strength = 1500.0; + float d = distance(lightpos.xyz, pixelpos.xyz); + float r = lightpos.w; + float a = d / r; + float b = clamp(1.0 - a * a * a * a, 0.0, 1.0); + return (b * b) / (d * d + 1.0) * strength; +} + vec3 ProcessMaterialLight(Material material, vec3 ambientLight) { vec3 worldpos = pixelpos.xyz; @@ -97,7 +96,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight) vec3 L = normalize(lightpos.xyz - worldpos); vec3 H = normalize(V + L); - float attenuation = linearDistanceAttenuation(lightpos); + float attenuation = inverseSquareDistanceAttenuation(lightpos); if (lightspot1.w == 1.0) attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y); if (lightcolor.a < 0.0)