point light - shadow mapping

I use a forward rendering and I try to implement a shadow mapping for a point light. I have one fbo and a cube map to store 6 depth textures. I'm not sure how to render a depth to textures when using a cube map (for a directional light and a single depth texture everything works fine in my program). An initialization code looks like this:

Then when rendering I bind the fbo and I render a scene 6 times. I set perspective matrix and appropriate view matrix. I assume that when I render the scene first time, then depth values are sending to the positive_x part of cube map (when I render second time to negative_x and so on). When I render the scene first time a view matrix looks like this:

Not doing any rendering between these has no effect AFAIK. A framebuffer has one depth attachment.

Then when rendering I bind the fbo and I render a scene 6 times. ... I assume that when I render the scene first time, then depth values are sending to the positive_x part of cube map (when I render second time to negative_x and so on).

Also seem to remember you can instead use a geometry shader to render to all the faces at once (layered rendering) if you so desire.

Yes, you can bind the entire cubemap using glFramebufferTexture( fbo, GL_DEPTH_ATTACHMENT, cubeTex, 0), and use a geometry shader that emits 18 vertices for each triangle - 3 to each gl_Layer, transformed by the appropriate view matrix for that face. This works well if you're only drawing triangles, but I'd recommend getting the simple version (6 passes) working first.

A warning about this. Some developers say this back-face casting works well for volumetric objects and avoids the need for any biasing tricks. And it seems to work ...some of the time, so you can actually be tricked into doing this.

But beware... it fails miserably (with often-blatent light leaks) when you apply it to objects that are not 1) closed (watertight), 2) convex, and 3) impenetrable (i.e. never rendered intersecting another object). When you have a light-space back face adjacent to a light-space front-face that's supposed to be in-shadow right next to each other in the shadow map (even across different objects in your scene), you get a light leak.

On the edge of an object this is usually OK. But in the middle of what's supposed to be an in-shadow region, this can be really objectionable. This artifact is more visible when you don't employ shadow filtering that's better than ordinary PCF. Having a large contrast between in-shadow and out-of-shadow colors/luminances and/or using a lower resolution shadow map helps highlight this artifact as well.

The depth values stored in the cube map are typically not going to be radial EYE-SPACE distances (or WORLD-SPACE distances -- same thing here) for the light as your code is assuming but WINDOW-SPACE depth values for the light (think EYE-SPACE Z values mapped through CLIP-SPACE and NDC to WINDOW-SPACE).

See the working point-light shadow casting code I posted a link to for details. In fact, I'd suggest you compile and run it. That gives you something to test against and binary-search your problems toward.

and that is in fact vertexWorldSpacePosition - pointLightWorldSpacePosition.

Next I guess that glsl 120 doesn't have overloaded texture functions which are executed based on a sampler type. There is no something like textureCubeShadow function so the extension must be included when using a samplerCubeShadow sampler. Without using the extension I can write the code this way:

The second computes the WORLD-SPACEvector from the light to the position of the fragment (assuming that light_position is the camera's EYE-SPACE position of the light). And then just tacks on a .w=1 as if this was a position in some space (it's not).

Draw a simple 2D diagram or plug in some real numbers to see why these are not equivalent.

The first takes into account the change in basis from WORLD-SPACE to light's EYE-SPACE. The second does not.

Next I guess that glsl 120 doesn't have overloaded texture functions which are executed based on a sampler type. There is no something like textureCubeShadow function

Yeah. In GLSL 1.2 and earlier, to do a shadow texture cubemap lookup with depth comparison, you'd use shadowCube() on samplerCubeShadow sampler type. In 1.3 and later, use simply texture() on a samplerCubeShadow.

First line gives you the light's EYE-SPACE position of the fragment (for the forward face of the cubemap).

The next two lines find the component of that position that is largest in absolute magnitude. The largest one determines which pair of cubemap faces you're going to be looking up into (largest == Z implies front or back cubemap face, largest = X implies left or right cubemap face, etc.). On whichever face it is, you know the light's EYE-SPACE position for that cubemap face specifically is going to have a Z value == -largest_value.

And so...

The fourth line transforms that light's EYE-SPACE depth value on that face to light's CLIP-SPACE on that face, and then...

The fifth line takes that on through light's NDC (-1..1) to light's WINDOW-SPACE (0..1).

Note that this operation just plugs in a light's EYE-SPACE X and Y value of 0,0 for the fragment because X and Y make absolutely no difference in the computation of the light's WINDOW-SPACE Z value for the fragment.

Is it the only way to calculate vec4 clip ?

Not sure what you mean.

Implicit in this math is that this is a point light source casting shadows, which uses a perspective projection to map space to the cube map. You could just expand terms from the projection matrix (hint: you only need the last 2 columns, since X,Y=0,0), simplify, and come up with a simple expression to compute the light's WINDOW-SPACE Z value from the light's EYE-SPACE Z value. Same operation but avoids a full matrix-vector multiply.