PDA

View Full Version : Starting with cascaded shadow maps...



Leadwerks
02-19-2008, 03:57 PM
I want to implement cascaded shadow maps like STALKER and Crysis have. I want the same quality and detail those engines allow. I understand the basic idea behind CSM.

My immediate thoughts are on how to allocate the shadow area. If we start from a top-down area in front of the camera it is easy enough to visualize. You could shear the rendering matrix to give a tilt to the light direction.

But once you start thinking about arbitrary geometry instead of just shadowing a flat plane, it gets very complicated. Shearing the matrix would cause errors on tall vertical walls. The only proper way to do it would be to render the scene from the point of view of the light, with the frustum stretched out to enclose the whole camera frustum (or the part of it the shadow map covers). This would result in a lot of wasted space, maybe 35% of the shadow map texture wouldn't even get used.

The simplest to visualize would be a series of squares around the camera, with the camera at the center. Each square uses the same resolution, but they cover more and more area. Shearing this matrix to tilt the light would be a little more reliable, since there would be a lot more room for error, but so much of the texture would be wasted, especially if the shadowmap was updated every frame. And if we are doing dynamic lighting, I think it should be.

Your thoughts?

Leadwerks
02-20-2008, 12:47 AM
Okay, I think the proper way to do this is first decide what distance you want to draw a shadowmap to. Then you split the camera frustum up into this volume, which has a center and a maximum possible radius. You use the volume radius as the width and height of the area you render to the shadow map, and the scale will never change on you, and it will always include everything in the frustum. It's incredibly wasteful, but works consistently.

My next question is about texture formats. Below is my code for creating projected shadow textures. What should this look like if I want to create a shadow map?


Method CreateShadowmap()
shadowmap=CreateTexture()
shadowmap.setfilter TEXTUREFILTER_SMOOTH
shadowmap.bind()
glTexImage2D GL_TEXTURE_2D,0,GL_RGBA8,shadowMapResolution,shado wMapResolution,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
glGenFramebuffersEXT 1,Varptr shadowmap.framebuffer[0]
glGenRenderBuffersEXT 1,Varptr shadowmap.renderbuffer[0]
glBindFramebufferEXT GL_FRAMEBUFFER_EXT,shadowmap.framebuffer[0]
glFramebufferTexture2DEXT GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEX TURE_2D,shadowmap.index(),0

//glBindRenderbufferEXT GL_RENDERBUFFER_EXT,shadowmap.renderbuffer[0]
//glRenderbufferStorageEXT GL_RENDERBUFFER_EXT,GL_DEPTH_COMPONENT,shadowMapRe solution,shadowMapResolution
//glFramebufferRenderbufferEXT GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_REND ERBUFFER_EXT,shadowmap.renderbuffer[0]

Select glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)
Case GL_FRAMEBUFFER_COMPLETE_EXT' ok!
Case GL_FRAMEBUFFER_UNSUPPORTED_EXT
Notify "FBO configuration unsupported",1
End
Default
Notify "FBO error",1
End
EndSelect
glBindFramebufferEXT GL_FRAMEBUFFER_EXT,0
EndMethod

Leadwerks
02-20-2008, 03:02 PM
This is what I am trying now, but it says "incomplete attachment":

shadowmap=CreateTexture(shadowMapResolution,shadow MapResolution, GL_DEPTH_COMPONENT24)
shadowmap.setfilter TEXTUREFILTER_SMOOTH
shadowmap.bind()
glGenFramebuffersEXT 1,Varptr shadowmap.framebuffer[0]
glBindFramebufferEXT GL_FRAMEBUFFER_EXT,shadowmap.framebuffer[0]
glFramebufferTexture2DEXT GL_FRAMEBUFFER_EXT,GL_DEPTH_ATTACHMENT_EXT,GL_TEXT URE_2D,shadowmap.index(),0
glDrawBuffer GL_FALSE
glReadBuffer GL_FALSE
Select glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)
Case GL_FRAMEBUFFER_COMPLETE_EXT' ok!
Case GL_FRAMEBUFFER_UNSUPPORTED_EXT
Notify "FBO configuration unsupported",1
End
Case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
Notify "Incomplete FBO attachment.",1
End
Default
Notify "FBO error"+glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT),1
End
EndSelect
glBindFramebufferEXT GL_FRAMEBUFFER_EXT,0