Jump to content
  • Advertisement
Sign in to follow this  
KaiserJohan

Shadowmaps with cubemaps

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

If you intended to correct an error in the post then please contact us.

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)
         renderIntoShadowMapFace(l, 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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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);
glBlendEquation(GL_FUNC_ADD);
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!