Reputation: 33
I want to put a positional light in my scene. I expect distant objects to take less light, but opengl just care about angle between surface normal and light. Am I doing something wrong or do I have to add another function?
GLfloat lightIntensity=1.0;
GLfloat main_position[] = {0.0, 0.0, 1.0, 1.0};
GLfloat light_ambient[] = {0.2, 0.2, 0.2, 0.0};
GLfloat light_diffuse[] = {lightIntensity, lightIntensity, lightIntensity, 1.0};
GLfloat light_specular[] = {0.0, 0.0, 0.0, 0.0};
/* Enable a single OpenGL light. */
glLightfv(GL_LIGHT0, GL_POSITION, main_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
When I run the code, 2 object with same surface normal have same lighting even though they have different distance from the light source
Upvotes: 2
Views: 368
Reputation: 210948
For a distance dependent light you've to set the attenuation parameters GL_CONSTANT_ATTENUATION
, GL_LINEAR_ATTENUATION
respectively GL_QUADRATIC_ATTENUATION
. See glLight
. By default the light is constant independent on the distance.
The light attenuation is specified in OpenGL 2.0 Specification - 2.14.1 Lighting, page 62.
The light attenuation factor is defiend as:
att = 1 / (kc + kl * d + kq * d * d)
d ... distance from the light source to the fragment
kc ... constant attenuation
kl ... linear attenuation
kq ... quadratic attenuation
The default value for the constant attenuation is 1, for the linear and quadratic attenuation it is 0. This leads to a distance independent factor of 1.
e.g. In the following a attenuation is set, where the attenuation factor is <= 1.0/255.0
at a distance of max_dist
:
float max_dist = ...;
float threshold = 1.0f/255.0f;
float kc = 0.0f;
float kq = 0.0f;
float kl = (1.0f/threshold - kc - kq*max_dist*max_dist) / max_dist;
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, kc);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, kl);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, kq);
For quadratic attenuation the same can be achieved by
float kc = 0.0f;
float kl = 0.0f;
float kq = (1.0f/threshold - kc - kl*max_dist) / (max_dist*max_dist);
Upvotes: 2