Skip to main content
gamedev.net
🔒 Locked

Depth Cube Shadow Mapping

Started by ninjarat Mar 21, 2011 at 8:40 AM 15 replies 7.8k views
Original Post
ninjarat
ninjarat
Hello, this is my first post on gamedev.net. I am new here, and as such, I feel kind of bad that my first post is a plea for help, but after struggling to find some information on google, I decided I'd ask some seasoned graphics programmers directly.

My rendering engine is coming along nicely, and now supports a simple scene graph with special light and camera nodes, and the light node supports any number of shadowing techniques. Calling render on the light node will do something like generate and render shadow volumes, render a depth map for shadow mapping, or six depth maps for omnidirectional shadow mapping using cube shadow mapping. Shadow mapping is now working perfectly with a single depth texture for spotlights, but my problem is this. After the six faces are rendered to the unrolled cube map (done with six 2D textures), I am having a lot of trouble with face selection.

I understand how it should work theoretically, but for some reason just can't get it working. But instead of asking you to fix my code, I'd just like to ask for a snippet or two of GLSL code from someone who's been there and done that. So assuming that my cube can be rotated arbitrarily, and I can get the vector from the object to the light (per vertex as a varying), about how should the code for face selection look in GLSL? I am something of a newcomer to GLSL.

Another small question too, would it be okay to just pass the view matrix of the camera for the rotation of my shadow cube, and extract the 3x3 rotation matrix in the shader? How would this be done in GLSL?

Sorry for being such a GLSL newbie, but anything concrete would really help me wrap my head around this problem.

Thanks in advance.
IvicaKolic
IvicaKolic
You can use trapezoidal projection and pack everything into one regular texture (avoid cube texture altogether).
Or you can use Camera Space Shadow Mapping.
Sample is here: http://free-zg.t-com.hr/cssm/
Geometrian
Geometrian
After the six faces are rendered to the unrolled cube map (done with six 2D textures), I am having a lot of trouble with face selection.
This is probably a bad idea; cubemaps exist for just this purpose and support a number of nice features that can't be emulated with 2D textures. Most notably, filtering across seams and faster lookup times than figuring out the proper face and then sampling from a 2D texture. It's actually easier to use a cubemap as well, because you only need to keep track of one texture object and state.

Once you've gotten a depth cubemap set up, the shadowmap lookup is fairly elementary; see my post on OpenGL.org.

-G
[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]
ninjarat
ninjarat

You can use trapezoidal projection and pack everything into one regular texture (avoid cube texture altogether).


Thanks for the input, man. I am not using deferred shading because of the diversity of the material shaders I want in my engine as it's being used in a space game with many strange materials used for exotic cosmic objects like magnetars and such (deferred shading is a tad too rigid for me now, plus transparency of any kind rapidly becomes very complicated). My engine does a Doom 3 like Z Pre Pass deal, with an ambient pass, a pass for each light visibly effecting the scene, and finally a generic pass for all objects outside the main lighting model (stars, planets, etc). So I think that maybe trapezoidal shadow maps could be the way to go. Could you give me the low down on exactly how the projection works and how it should be used for omnidirectional lights? It sounds interesting.

Once again, for me, something concrete is almost always the deal clincher. In the meantime, I'll see what kind of papers and examples I can dig up. Thanks again.
ninjarat
ninjarat

[quote name='billium' timestamp='1300696816' post='4788561']After the six faces are rendered to the unrolled cube map (done with six 2D textures), I am having a lot of trouble with face selection.
This is probably a bad idea; cubemaps exist for just this purpose and support a number of nice features that can't be emulated with 2D textures. Most notably, filtering across seams and faster lookup times than figuring out the proper face and then sampling from a 2D texture. It's actually easier to use a cubemap as well, because you only need to keep track of one texture object and state.
[/quote]


Hmm, well, I was just trying to avoid using a real depth cubemap for simple compatibility reasons, to be honest, but I suppose I could just bite the bullet and try it. I guess point lights with omnidirectional shadows will be kind of an eye candy thing when you fire thrusters or dock with a space station. The thing is, I have not really been jumping on the forward compatible only bandwagon, so the GLSL version I am compiling with is just 1.4. I definitely have a soft spot for the old school demo in me, I like to make stuff as compatible as possible.

Geometrian
Geometrian
Hmm, well, I was just trying to avoid using a real depth cubemap for simple compatibility reasons, to be honest, but I suppose I could just bite the bullet and try it. I guess point lights with omnidirectional shadows will be kind of an eye candy thing when you fire thrusters or dock with a space station. The thing is, I have not really been jumping on the forward compatible only bandwagon, so the GLSL version I am compiling with is just 1.4. I definitely have a soft spot for the old school demo in me, I like to make stuff as compatible as possible.[/quote]Cubemap textures have been core around since GL 1.3, I believe. GLSL, since GL 2.0. If your target platform supports GLSL, then it most definitely will support cubemaps.
[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]
IvicaKolic
IvicaKolic
Sorry,
I've said trapezoidal projection, but I actually meant tetrahedron projection - projection on four sides of a tetrahedron.

However, you've said that you have space stations and stuff - if you want big omni-lights Camera Space Shadow Mapping is the way to go - it is the only algorithm that can handle big omni-lights (and all that with one standard shadow map texture in a single pass - and free of wastage too).
It also works with infinitely large scenes (that are not far clipped) which is something you need.
Vilem Otte
Vilem Otte
There is also possiblity of using dual paraboloid or dual hemispherical projection. Although dual paraboloid is in fact a bit better. Anyway I'd first implement cube map shadow mapping and leave tweaking to future.

Camera space shadow mapping sounds interesting, is there any paper describing this method? For me it seems like balancing shadow map matrix for light in some way to fit whole viewport, am I right? (lots of math involved though).

I'm solving big lights in a different way (with physically plausible soft shadows) - through visibility and radiosity (instant realtime radiosity, e.g. with lots of smaller lights with blurry shadows). As a side product I get instant global illumination ... even though this solution is a bit heavy (though I do scenes that really need it to look good, and due to size, precomputing is NOT a good idea ... anyway ray tracing involved in this solution, for acceleration ).

Although recently I did some successful experimenting with fully ray traced shadows, but I can't afford spending that much CPU/GPU power on computing just shadows. But in future...
ninjarat
ninjarat

Hmm, well, I was just trying to avoid using a real depth cubemap for simple compatibility reasons, to be honest, but I suppose I could just bite the bullet and try it. I guess point lights with omnidirectional shadows will be kind of an eye candy thing when you fire thrusters or dock with a space station. The thing is, I have not really been jumping on the forward compatible only bandwagon, so the GLSL version I am compiling with is just 1.4. I definitely have a soft spot for the old school demo in me, I like to make stuff as compatible as possible.
Cubemap textures have been core around since GL 1.3, I believe. GLSL, since GL 2.0. If your target platform supports GLSL, then it most definitely will support cubemaps.
[/quote]

Well, forgive my ignorance, but I was pretty sure that _depth_ cubemap texture samplers were a much newer deal. Are you talking about just faking it with an R32F format? Could I see an example of how that works? I'll check out your post in a minute.
Geometrian
Geometrian
Well, forgive my ignorance, but I was pretty sure that _depth_ cubemap texture samplers were a much newer deal.
Depth is just a texture format, so although it's possible I'm incorrect, I'd imagine that depth cubemaps were supported as soon as other types of cubemaps were available. In any case, depth cubemaps are far more widely supported than shaders and floating point textures.
[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]
ninjarat
ninjarat
[font=arial, verdana, tahoma, sans-serif][size=2]Alright, so I've read through this whole thread really carefully, and I think I've figured out that camera space shadow mapping could be the way to go, mostly because of how universal of a solution it is. My only question is this: Right now I'm using a Z Pre Pass architecture, which just means separating each light and surface coloration in to different passes after laying down the depth and ambient color in a pre pass, which I'm doing for flexibility purposes. The problem is that deferred shading is therefore out of the question, as intriguing and cool as it is. So I guess what I'm asking is, how feasible is doing camera space shadow mapping without deferred shading? I think I can see a way... but I would like to know for sure if it's been done or could be done.

And if it will work, could I please see a more OpenGL friendly example? Nothing fancy or super complete, just the absolute bare minimum would be nice.[/font]

Thanks for all the input, guys.
ninjarat
ninjarat
Hmmm, looks very... closed source, and "producty". :/

I don't like the looks of it. I think I'd rather just go for the tried and true cube, I'm halfway there anyhow. So could anyone possibly show me a good working GLSL example of that?
Geometrian
Geometrian
Hmmm, looks very... closed source, and "producty". :/
Agreed. I'm immediately suspicious of an algorithm that touts its features but not its method. If it were specified how it worked, then I might be more inclined to take it seriously--but until then, it could be anything.
[size="1"]And a Unix user said rm -rf *.* and all was null and void...|There's no place like 127.0.0.1|The Application "Programmer" has unexpectedly quit. An error of type A.M. has occurred.
[size="2"]
IvicaKolic
IvicaKolic
CSSM paper is in the process of being published (as of last week).
Once it's published, details and the code will be open to the public.
And yes, it will be free

Paper also discusses some common misconceptions about shadow mapping. Everyone is expecting some magical matrix that will warp the shadow map so well but the truth is that won't happen because of limitations of linear projection. Instead of that, alternative ways of warping are applied. Some are not even in the API because of DX9 limitations, but they are discussed ether way. In fact, completely new way of doing non-linear transformations is described (without tessellation) - it can be used for great many things, and warping shadow map is one of them.
DarkChris
DarkChris

CSSM paper is in the process of being published (as of last week).
Once it's published, details and the code will be open to the public.
And yes, it will be free

Paper also discusses some common misconceptions about shadow mapping. Everyone is expecting some magical matrix that will warp the shadow map so well but the truth is that won't happen because of limitations of linear projection. Instead of that, alternative ways of warping are applied. Some are not even in the API because of DX9 limitations, but they are discussed ether way. In fact, completely new way of doing non-linear transformations is described (without tessellation) - it can be used for great many things, and warping shadow map is one of them.



Why don't you just explain how it works? Maybe you should post some images of how the shadow map looks like (and the resulting image). This would make it way easier to understand how it works. And why does it take so long to upload a paper? Couldn't you just copy the important parts of it into this thread?
IvicaKolic
IvicaKolic
Chris,
If you are really interested, I can send you a paper, but don't distribute it until it gets published.
DarkChris
DarkChris

Chris,
If you are really interested, I can send you a paper, but don't distribute it until it gets published.


Ok, I'm actually incredibly interested... You don't know how much I thought about how it might be working yesterday
I won't release it, I just want to know how it works. I'd really appreciate it.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.