Light attenuation not working correctly

Started by
4 comments, last by KaiserJohan 11 years ago

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

Advertisement

I think you should be using the 'length' function in CalcLightIntensity instead of the 'abs' function.

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

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.

So ? Is your problem solved or do you have no hair left debugging ? ^^

Yes I fixed it finally; I added the suggestions you made, in addition I also found out that 'LightAttenuation' variable was not uploaded correctly to the shader - it was set to 0.0, which wouldve removed any attenuation at all

This topic is closed to new replies.

Advertisement