• Advertisement
Sign in to follow this  

Attenuation shader, correct or not correct?

This topic is 1728 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

Is this the correct way of calculating and applying attenuation?

 

This is my basic diffuse shader with attenuation:

 

.vert

varying vec3 vertex_light_position;

varying vec3 vertex_light_half_vector;

varying vec4 color;

varying vec3 N;

varying vec3 v;
 void main(void)

{

    v = vec3(gl_ModelViewMatrix * gl_Vertex);

    N = normalize(gl_NormalMatrix * gl_Normal);
    color = gl_Color;

    vertex_light_position = normalize(gl_LightSource[0].position.xyz);
    vertex_light_half_vector = normalize(gl_LightSource[0].halfVector.xyz);



    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}

 

.frag

varying vec3 vertex_light_position;

varying vec3 vertex_light_half_vector;

varying vec4 color;

varying vec3 N;

varying vec3 v;
void main()

{ 

   float constantAttenuation=1.0;

   float linearAttenuation=1.0;

   float quadraticAttenuation=0.02;
   float dist = length(gl_LightSource[0].position - v);

   float att = 1.0/(constantAttenuation + (linearAttenuation * dist) + (quadraticAttenuation * dist * dist));


   vec3 L = normalize(gl_LightSource[0].position.xyz - v);

   vec3 E = normalize(-v);

   vec3 R = normalize(reflect(-L,N));

  

   vec4 diffuse_color = vec4(0.0,1.0,0.0,0.0);

   float diffuse_value = max(dot(N,L), 0.0);

  

   if (gl_FrontFacing){

       gl_FragColor = color + (((diffuse_color-color) * (diffuse_value))*att);

   }else{

       gl_FragColor = color;

   }

  

}

Share this post


Link to post
Share on other sites
Advertisement

The attenuation equation is 1/(k_c + k_l * d + k_q * d * d) so apparently in your code you got it right (d is distance, k_c constant coef., k_l linear coef., k_q quadratic coef.).

 

The thing is, that distance can grow quite fast, and at mere distance of 10 points your light intensity (in your case) is 1 / (1.0 + 1.0 * 10 + 0.02 * 10 * 10) = 1/13 ... so everything at distance of 10 will be quite dark (intensity less than 0.1).

 

So if you're getting dark image, just try to fine tune attenuation factors - linear should be just a fraction of constant attenuation and quadratic should be just a fraction of linear attenuation. For example: using 1.0 as constant coefficient, 0.007 as linear coefficient and 0.00003 as quadratic coefficient yields half intensity at distance of 100.

Share this post


Link to post
Share on other sites

Should be noted that there is no "correct" way of calculating attenuation in the shader-based world; the constant/linear/quadratic equation is consistent with old-school fixed-pipeline attenuation formulae, but with shaders you can use any attenuation formula you wish.

 

For a physically "correct" formula for light attenuation, you just need inverse-square (i.e. the quadratic portion of the formula you're currently using) but, once again, if using a different formula looks better with your source data or otherwise meets your requirements better, then by all means use it.

Share this post


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

  • Advertisement