Jump to content
  • Advertisement
Sign in to follow this  
KaiserJohan

Light attenuation not working correctly

This topic is 1929 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement

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

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

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!