# Thread: SpotLight, attenuation factors and Backfaces

1. Hi,

I showed both cases, with Shader and No Shader (fixed fucntion OpenGL) to show that both cases gives the same result: a little lighting on the backface.

In the case with the Shader the effect is more visible because I'm doing illumination at fragment level instead of vertex level (fixed function).

But if you look at the image "bottom no shader.jpg" you can see the little illumination I'm taking about towards the top right corner of my quad.

This was with ConstantAttenuation 0.1.

The 2 images I posted in my reply #6 use the ConstantAttenuation 0.01 and the illumination on the backface is much more visible, and they are done with fixed function OpenGL.

I wouldn't expect any illumination on the backface... am I missing something?

2. Make sure fog is off. Disable distance and angle attenuation effects (i.e. const atten = 1, lin/quad = 0). And verify you're multiplying by clamped cos term. Specular should also be 0 if N*L < 0. Note that this clamp doesn't make physical sense but it is nonetheless there in the old FFP lighting equation.

3. Hi Dark Photon,

In the shader I'm doing this:

Code :
```void ComputeSpotPointParameters( in int i,
in vec3 eye,
in vec3 ecPosition3,
in vec3 normal,
out vec3 VP,
out float nDotVP,
out float pf,
out float attenuation)
{

float nDotHV;
float d;
vec3 halfVector;

VP = vec3(gl_LightSource[i].position) - ecPosition3;

d = length(VP);

VP = normalize(VP);

attenuation = 1.0 / (gl_LightSource[i].constantAttenuation +
gl_LightSource[i].linearAttenuation * d +

halfVector = normalize(VP + eye);

nDotVP = max(0.0, dot(normal, VP));
nDotHV = max(0.0, dot(normal, halfVector));

if (nDotVP == 0.0)
pf = 0.0;
else
pf = pow(nDotHV, gl_FrontMaterial.shininess);
}

void SpotLight(in int i,
in vec3 eye,
in vec3 ecPosition3,
in vec3 normal,
inout vec4 ambient,
inout vec4 diffuse,
inout vec4 specular)
{

vec3 VP;
float nDotVP, pf;
float spotAttenuation;
float attenuation;

ComputeSpotPointParameters( i,
eye,
ecPosition3,
normal,
VP, nDotVP, pf,
attenuation);

float spotDot = dot(-VP, normalize(gl_LightSource[i].spotDirection));

if (spotDot < gl_LightSource[i].spotCosCutoff)
spotAttenuation = 0.0;
else
spotAttenuation = pow(spotDot, gl_LightSource[i].spotExponent);

attenuation *= spotAttenuation;

ambient  = gl_LightSource[i].ambient * attenuation;
diffuse  = gl_LightSource[i].diffuse * nDotVP * attenuation;
specular = gl_LightSource[i].specular * pf * attenuation;
}```

I guess the clamp you refer to is done in these lines:

Code :
```    nDotVP = max(0.0, dot(normal, VP));
nDotHV = max(0.0, dot(normal, halfVector));```

But I would like to solve the problem with the Fixed Function OpenGL first.
Why do I have the illumination on the backface even without shaders?

4. Why do I have the illumination on the backface even without shaders?
With your current settings you shouldn't - at least I didn't spot the error yet. However, did you verify that the normal points into the right direction, i.e. parallel to -y in world-coordinates?

5. Yes,

the normal is pointing towards the upper (front) side of the Quad.

6. Ok, are you properly position the light source when you rotate the scene? Do you orient the normal correctly? Please post your full shader code. For fixed function we can't really help you unless you post the fixed code.

7. I found out the following things studying my Shader and playing with it in RenderMonkey:

1. The illumination on the backface is given by the ambient component of the spotlight:

Code :
`   ambient  = gl_LightSource[i].ambient * attenuation;`

When I'm looking at the backface nDotVP is 0, so if I multiplicate even the ambient factor by nDotVP, like the diffuse does, the backface is no longer illuminated.

Code :
`   ambient  = gl_LightSource[i].ambient * attenuation * nDotVP;`

Is that right, or is it better to just put "attenuation" to 0 if nDotVP is 0?

I guess the same applies for PointLights.

2. If I clamp the ambient factor to [0,1] I don't get an over-exposed illumination with small values of the ConstantAttenuation term.

8. Is that right, or is it better to just put "attenuation" to 0 if nDotVP is 0?
In general, if the diffuse term (nDotVP) is 0 and you have a solid, non-transmitting surface, then there can be no reflection of any light since no photons actually hit the surface your illuminating. However, the ambient term is usually independent of the diffuse and specular terms. The point of light-specific ambient terms is to be able to mix the global ambient color and the light-specific ambient colors for all light sources in the scene. However, if you move the light source further away, also interreflected radiance will decrease, that's why there is a light-specific attenuation. The global ambient term is never attenuated.

In short: If you don't want any lighting at all if the diffuse term is zero, simply set the global and light-specific ambient terms to zero (fixed function) or simply don't use them in your calculation in the shader.

9. Originally Posted by thokra
In short: If you don't want any lighting at all if the diffuse term is zero, simply set the global and light-specific ambient terms to zero (fixed function) or simply don't use them in your calculation in the shader.

But the fixed function is not setting the ambient terms to zero (as my pictures without the shader showed)...

10. The default value for global ambient color is (0.2, 0.2, 0.2, 1.0) so I think it's no wonder why there's something that's not black.

Code :
```float globalAmbient[] = {0.f, 0.f, 0.f, 1.f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbient);```

Edit: BTW, I'd strongly advise against implementing a fixed-function lighting solution. Even with GLSL 1.10 you get much more flexibility and don't have to cope with stuff like the above.

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•