The division by w
by itself will not clamp it to [0,1]. Technically what you have are clip-space coordinates, and then division by w
transforms them into NDC space. Any point x, y, or z that is < -w or > w is clipped when this operation is performed on geometry. However, when you do it on your texture coordinates you still need to provide an appropriate texture wrap mode (usually GL_CLAMP_TO_EDGE
), because the coordinates are not clamped automatically.
Note that all points that project beyond your shadow map's far plane will exhibit the same behavior since the coordinates are clamped. Usually this manifests itself as everything beyond a certain distance being fully in shadow. This is why you want to match your shadow map's frustum more closely with your attenuated light volume.
Also, in this situation a sampler2DShadow
makes a lot of sense...
This whole thing:
float depthValue = texture(unifShadowTexture, projCoords.xy).x;
float visibilty = 1.0;
if (depthValue < (projCoords.z))
visibilty = 0.0;
Can be simplified to this:
float visibility = texture (unifShadowTexture, projCoords);
Provided you do two things:
- Declare
unifShadowTexture
assampler2DShadow
- Set
GL_TEXTURE_COMPARE_MODE
toGL_COMPARE_R_TO_TEXTURE
for your depth texture
This works because for sampler2DShadow
, it requires 3D texture coordinates. s
and t
work as usual, and r
is the value it uses for comparison. The default comparison function is GL_LESS
, so you do not have to change anything in your code. Given a GL_NEAREST
texture function, the return of this will be either 1.0 or 0.0. It will produce exactly the same as your code snippet above, but using a hardware feature for the actual depth test and will often improve performance and get you inexpensive PCF if you enable GL_LINEAR
.
I woud suggest, however, that you add a bias to the Z component of your texture coordinates. Something like (0.001) or you will get a lot of "shadow acne", too high a bias and you will get "peter panning" (shadows seem to hover slightly above whatever they are attached to).