diff --git a/src/rendering/hwrenderer/scene/hw_spritelight.cpp b/src/rendering/hwrenderer/scene/hw_spritelight.cpp index 866024653..557dcbeec 100644 --- a/src/rendering/hwrenderer/scene/hw_spritelight.cpp +++ b/src/rendering/hwrenderer/scene/hw_spritelight.cpp @@ -113,7 +113,7 @@ public: //========================================================================== -float inverseSquareAttenuation(FVector3 lightpos, float dist, float radius) +float inverseSquareAttenuation(float dist, float radius) { float strength = 1500.0; float a = dist / radius; @@ -178,7 +178,7 @@ void HWDrawInfo::GetDynSpriteLight(AActor *self, float x, float y, float z, FLig { if(level.info->lightattenuationmode == ELightAttenuationMode::INVERSE_SQUARE) { - frac = (inverseSquareAttenuation(L, std::max(dist, sqrt(radius) * 2), radius)); + frac = (inverseSquareAttenuation(std::max(dist, sqrt(radius) * 2), radius)); } else { diff --git a/wadsrc/static/shaders/scene/lightmodel_normal.glsl b/wadsrc/static/shaders/scene/lightmodel_normal.glsl index 553d5aadb..519b71afd 100644 --- a/wadsrc/static/shaders/scene/lightmodel_normal.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_normal.glsl @@ -1,22 +1,4 @@ -#ifdef LIGHT_ATTENUATION_INVERSE_SQUARE - -float distanceAttenuation(vec4 lightpos, float d) -{ - float strength = 1500.0; - 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; -} - -#else //elif defined(LIGHT_ATTENUATION_LINEAR) - -float distanceAttenuation(vec4 lightpos, float d) -{ - return clamp((lightpos.w - d) / lightpos.w, 0.0, 1.0); -} - -#endif +#include "shaders/scene/lightmodel_shared.glsl" vec3 lightContribution(int i, vec3 normal) { @@ -33,7 +15,7 @@ vec3 lightContribution(int i, vec3 normal) float dotprod = dot(normal, lightdir); if (dotprod < -0.0001) return vec3(0.0); // light hits from the backside. This can happen with full sector light lists and must be rejected for all cases. Note that this can cause precision issues. - float attenuation = distanceAttenuation(lightpos, lightdistance); + float attenuation = distanceAttenuation(lightdistance, lightpos.w); if (lightspot1.w == 1.0) attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y); diff --git a/wadsrc/static/shaders/scene/lightmodel_pbr.glsl b/wadsrc/static/shaders/scene/lightmodel_pbr.glsl index 603787df1..bd0573130 100644 --- a/wadsrc/static/shaders/scene/lightmodel_pbr.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_pbr.glsl @@ -1,24 +1,4 @@ -#ifdef LIGHT_ATTENUATION_INVERSE_SQUARE - -float distanceAttenuation(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; -} - -#else //elif defined(LIGHT_ATTENUATION_LINEAR) - -float distanceAttenuation(vec4 lightpos) -{ - float lightdistance = distance(lightpos.xyz, pixelpos.xyz); - return clamp((lightpos.w - lightdistance) / lightpos.w, 0.0, 1.0); -} - -#endif +#include "shaders/scene/lightmodel_shared.glsl" const float PI = 3.14159265359; @@ -101,7 +81,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight) vec3 L = normalize(lightpos.xyz - worldpos); vec3 H = normalize(V + L); - float attenuation = distanceAttenuation(lightpos); + float attenuation = distanceAttenuation(distance(lightpos.xyz, pixelpos.xyz), lightpos.w); if (lightspot1.w == 1.0) attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y); if (lightcolor.a < 0.0) @@ -141,7 +121,7 @@ vec3 ProcessMaterialLight(Material material, vec3 ambientLight) vec3 L = normalize(lightpos.xyz - worldpos); vec3 H = normalize(V + L); - float attenuation = distanceAttenuation(lightpos); + float attenuation = distanceAttenuation(distance(lightpos.xyz, pixelpos.xyz), lightpos.w); if (lightspot1.w == 1.0) attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y); if (lightcolor.a < 0.0) diff --git a/wadsrc/static/shaders/scene/lightmodel_shared.glsl b/wadsrc/static/shaders/scene/lightmodel_shared.glsl new file mode 100644 index 000000000..5af9136cb --- /dev/null +++ b/wadsrc/static/shaders/scene/lightmodel_shared.glsl @@ -0,0 +1,18 @@ +#ifdef LIGHT_ATTENUATION_INVERSE_SQUARE + +float distanceAttenuation(float dist, float radius) +{ + float strength = 1500.0; + float a = dist / radius; + float b = clamp(1.0 - a * a * a * a, 0.0, 1.0); + return (b * b) / (dist * dist + 1.0) * strength; +} + +#else //elif defined(LIGHT_ATTENUATION_LINEAR) + +float distanceAttenuation(float dist, float radius) +{ + return clamp((radius - dist) / radius, 0.0, 1.0); +} + +#endif diff --git a/wadsrc/static/shaders/scene/lightmodel_specular.glsl b/wadsrc/static/shaders/scene/lightmodel_specular.glsl index 721efee0d..cbebb7f3b 100644 --- a/wadsrc/static/shaders/scene/lightmodel_specular.glsl +++ b/wadsrc/static/shaders/scene/lightmodel_specular.glsl @@ -1,22 +1,4 @@ -#ifdef LIGHT_ATTENUATION_INVERSE_SQUARE - -float distanceAttenuation(vec4 lightpos, float d) -{ - float strength = 1500.0; - 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; -} - -#else //elif defined(LIGHT_ATTENUATION_LINEAR) - -float distanceAttenuation(vec4 lightpos, float d) -{ - return clamp((lightpos.w - d) / lightpos.w, 0.0, 1.0); -} - -#endif +#include "shaders/scene/lightmodel_shared.glsl" vec2 lightAttenuation(int i, vec3 normal, vec3 viewdir, float lightcolorA, float glossiness, float specularLevel) { @@ -28,7 +10,7 @@ vec2 lightAttenuation(int i, vec3 normal, vec3 viewdir, float lightcolorA, float if (lightpos.w < lightdistance) return vec2(0.0); // Early out lights touching surface but not this fragment - float attenuation = distanceAttenuation(lightpos, lightdistance); + float attenuation = distanceAttenuation(lightdistance, lightpos.w); if (lightspot1.w == 1.0) attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);