Sign in to follow this  
KaiserJohan

Light attenuation not working correctly

Recommended Posts

Hello,

 

I have the vertex shader like this:

 

const std::string gVertexShader =	"#version 330								                            \n	\
                                                                                                                \n  \
                                        layout(std140) uniform DefaultUniform                                   \n  \
                                        {                                                                       \n  \
                                            vec4 Color;                                                         \n  \
                                            mat4 WVPMatrix;                                                     \n  \
                                            mat4 WorldMatrix;                                                   \n  \
                                                                                                                \n  \
                                            vec4  AmbientLight;                                                 \n  \
                                            vec4  LightIntensity;                                               \n  \
                                            vec3  LightPosition;                                                \n  \
                                            float LightAttenuation;                                             \n  \
                                        };                                                                      \n  \
                                                                                                                \n	\
                                        layout(location = 0) in vec3 vert_position;				                \n	\
                                        layout(location = 1) in vec3 vert_normal;					            \n	\
                                                                                                                \n	\
                                        out vec4 frag_color;                                                    \n	\
                                        out vec4 frag_position;                                                 \n	\
                                        out vec4 frag_normal;                                                   \n	\
                                                                                                                \n	\
                                        out vec4  frag_ambientLight;                                            \n	\
                                        out vec4  frag_lightIntensity;                                          \n	\
                                        out vec4  frag_lightPosition;                                           \n	\
                                        out float frag_lightAttenuation;                                        \n	\
                                                                                                                \n	\
                                        void main()									                            \n	\
                                        {											                            \n	\
                                            gl_Position = WVPMatrix * vec4(vert_position, 1.0);                 \n  \
                                                                                                                \n  \
                                            frag_color    = Color;                                              \n  \
                                            frag_position = WorldMatrix * vec4(vert_position, 1.0);             \n  \
                                            frag_normal   = normalize(WorldMatrix * vec4(vert_normal, 1.0));    \n  \
                                                                                                                \n  \
                                            frag_ambientLight     = AmbientLight;                               \n  \
                                            frag_lightIntensity   = LightIntensity;                             \n  \
                                            frag_lightPosition    = vec4(LightPosition, 1.0);                   \n  \
                                            frag_lightAttenuation = LightAttenuation;                           \n  \
                                        }											                            \n";

 

 

I have a fragment shader defined like this:

 

const std::string gFragmentShader =	"#version 330									                                            \n \
                                                                                                                                    \n \
                                        in vec4 frag_color;                                                                         \n \
                                        in vec4 frag_position;                                                                      \n \
                                        in vec4 frag_normal;                                                                        \n \
                                                                                                                                    \n \
                                        in vec4  frag_ambientLight;                                                                 \n \
                                        in vec4  frag_lightIntensity;                                                               \n \
                                        in vec4  frag_lightPosition;                                                                \n \
                                        in float frag_lightAttenuation;                                                             \n \
                                                                                                                                    \n \
                                        out vec4 finalColor;						                                                \n \
                                                                                                                                    \n \
                                        vec4 CalcLightIntensity()                                                                   \n \
                                        {                                                                                           \n \
                                            vec4 positionDiff = frag_lightPosition - frag_position;                                 \n \
                                                                                                                                    \n \
                                            return frag_lightIntensity * (1 / (1.0 + frag_lightAttenuation * abs(positionDiff)));   \n \
                                        }                                                                                           \n \
                                                                                                                                    \n \
                                                                                                                                    \n \
                                        void main()										                                            \n \
                                        {												                                            \n \
                                            vec4 attenIntensity = CalcLightIntensity();                                             \n \
                                                                                                                                    \n \
                                            vec4 lightDir      = normalize(frag_position - frag_lightPosition);                     \n \
                                            float angIncidence = dot(frag_normal, lightDir);                                        \n \
                                            angIncidence       = clamp(angIncidence, 0, 1);                                         \n \
                                                                                                                                    \n \
                                            finalColor = (frag_color * attenIntensity * angIncidence) +                             \n \
                                                         (frag_color * frag_ambientLight);                                          \n \
                                        }												                                            \n";

 

I have a single positional light, and I want to apply light attenuation so the intensity fades over distance. But, for some reason, the attenuation does not work at all - the light does not decrease on distance. Can someone spot what the problem is? I'm pulling my hair out trying to debug it

Edited by KaiserJohan

Share this post


Link to post
Share on other sites

I tried it; same result.

 

For example, when I move the light in Z direction, everything at the current Z position and 'down' (-Z) gets fully lit while everything directly 'behind' (+Z) is not lit at all. 

 

In case it matters the 'LightIntensity' is Vec4(1.0f), 'LightAttenuation' is 1.0f

Share this post


Link to post
Share on other sites

In your vertex shader, you are computing the vertex normal with

  frag_normal = normalize(WorldMatrix * vec4(vert_normal, 1.0)); 

In homogenous coordinates, the last "w" scalar value set to 1.0 means that vert_normal is a point. As it is a mere unpositioned vector, i think using 0.0 should fix your bug.

 

 

Moreover, normalizing the interpolation variable frag_normal (set as "smooth out" and "smooth in" by default) will lead to incorrect normal vectors as they won't stay normed during their interpolation across vertices. You should normalize it in the fragment shader.

Edited by PixelSmasher

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this