This topic is 2071 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Bear with me, probably not the last question on the subject.

I'm trying to implement shadowmapping using cube maps.

I'm using this guide http://http.developer.nvidia.com/GPUGems/gpugems_ch12.html, which is now almost 10 years old. From what I understand, this is the general alghoritm:

foreach (Light l)
{
bind framebuffer
foreach(cubemapface f)
unbind framebuffer

drawAllObjects(l);
}

1. When/where do you clear depth/color buffers?

2. For each light, do you have to draw all objects in the scene 7 times (6 for all cubemap faces + last pass)? Besides deferred renderering, is there any better alghoritm?

Edited by KaiserJohan

##### Share on other sites

1. You only need to use this technique for point lights. Spots and directional light have a single shadow map.

2. Clear the shadow cube map before rendering into it. The color buffer should be cleared outside the light loop.

3. You have to draw all the geometry 6 times per light + 1 global final pass. You can do all shadowing from all lights in this final pass at once, but that means you have to allocate a cube-map per light - depending on your number of shadow-casting-light, this can either no-issue or force you to do multiple passes.

4. If you are using DX10+, which have GS support, you can draw the geometry once per light, than use GS to route the primitives to the correct face.

##### Share on other sites

Thanks, it does clear things up.

As for 3), if I want to use only one shadowmap I have (numLights * (6 + 1)) passes while if I use one shadowmap per light I get (numLights  6) + 1 passes?

When renderering to the shadowmap, do I have to change my viewport to the dimensions of the shadowmap(1024x1024), and then back again for the final drawing(1900x1020)?

##### Share on other sites

As for 3), if I want to use only one shadowmap I have (numLights * (6 + 1)) passes while if I use one shadowmap per light I get (numLights 6) + 1 passes?

When renderering to the shadowmap, do I have to change my viewport to the dimensions of the shadowmap(1024x1024), and then back again for the final drawing(1900x1020)?

Yes and yes.

##### Share on other sites

Do I also need to enable some sort of blend-function between the passes? (using OpenGL 3.3) I figure, since I am writing to the default framebuffer once per light the output between the passes needs to be added together somehow? If so, what kind of blending?

Should I also clear the Depthbuffer for the default framebuffer for each light pass in the loop?

Edited by KaiserJohan

##### Share on other sites

Do I also need to enable some sort of blend-function between the passes? (using OpenGL 3.3) I figure, since I am writing to the default framebuffer once per light the output between the passes needs to be added together somehow? If so, what kind of blending?

Yes you need additive blending, where the src and dst factors are 1. Note that I set the alpha factors differently the RGB - this is to ensure that the alpha value will always be one. It will work without it, but then your alpha value will not make sense.

glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ZERO);
glEnable(GL_BLEND);


Should I also clear the Depthbuffer for the default framebuffer for each light pass in the loop?

You should only clear it once before the first light pass. Using pre-initialized depth buffer for the rest of the passes will potentially increase your performance, since it will now depth-cull pixels faster.

Edited by N.I.B.

##### Share on other sites

I'm trying to figure out how to actually get the correct vector to sample the cubemap with in the shading pass. I realise the light position is important, but not sure what to do with it - any pointers?

##### Share on other sites

Use the vector between the pixel WorldPos and the light WorldPos.

GPU Gems has a nice chapter on omnidirectional shadow-mapping.

##### Share on other sites

I've found an example here https://github.com/cforfang/opengl-shadowmapping/blob/master/src/vsmcube/fragmentShader.glsl which seems to calculate the distance between the fragment and the light position in eye space. Why is this needed? Can't this be done in world space instead and save some matrix multiplications?

Also, when providing the vector to the cubemap, why would you negate it?

Edited by KaiserJohan

##### Share on other sites

Local space is unique per object.  The value stored in the shadow map should have the same frame-of-reference for all objects. The specific issue is that since local->world can potentially scale the objects, it also scales distances between objects(distance of 1 in local space in not necessarily distance of 1 in world space). Light position is usually represented in world space, and it's the most common space for lighting calculations. That's how it's calculated in the GPU Gems book. The code you sent does Variance Shadow Map with cube-mapping, which is a fairly advanced shadow map technique. I recommended you figure our regular shadow map before tackling it.

Also, when providing the vector to the cubemap, why would you negate it?

The vector they calculate is (LightPos-PixelPos). You need the opposite vector to access the cube-map. Think of it as a ray shot from the light in the direction of the object. The cube-map holds the depth value of the closest object along this ray, and if the pixel value is larger than the cube-map value - the ray doesn't hit the object. This ray's direction is (PixelPos-LightPos).

• 13
• 18
• 29
• 11