View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Sign up now

# Attenuation shader, correct or not correct?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

3 replies to this topic

### #1Shawn619  Members

Posted 27 April 2013 - 07:26 PM

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;

}

}


### #2Vilem Otte  GDNet+

Posted 28 April 2013 - 06:13 PM

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.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

### #3Shawn619  Members

Posted 29 April 2013 - 11:44 AM

Thanks, that makes sense!

### #4mhagain  Members

Posted 29 April 2013 - 11:56 AM

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.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.