PDA

View Full Version : why no shadow cubemaps?



zed
08-03-2005, 03:42 PM
one thing thats bothered me for ages is why we dont have shadow cubemaps
ok maybe todays cards cant do it, that doesnt explain why in eg glsl theres no shadowCube sampler.

aint shadowcubemaps a logical feature?

Hlz
08-03-2005, 10:58 PM
How would they work?

Overmind
08-04-2005, 10:05 AM
Shadow textures work by doing a texture lookup with the (s,t) coordinate pair and comparing this to the r value of the texcoords. But for cubemaps and 3D textures you need the (s,t,r) coordinates for doing the lookup, so you're running out of texcoord components ;)

Of course you can use a standard texture target and do the comparison yourself.

Hlz
08-04-2005, 10:50 AM
I understand the general motivation for such a thing, but I was guessing that Zed was hoping for an oppotunity dazzle us with the details ;)

I imaging there are some practical reasons why we haven't seen such a thing. A good understanding of how something like this might be implemented may shed some light on things. Hardware, cost, spec, interactions, usage models, advantages, disadvantages... the devil is in the details.

I really haven't given it much thought.

zed
08-04-2005, 12:28 PM
why not add (s,t,r) q in as well surely that should work,
the reasoning behind having cubeshadowmaps is i believe some hardware (nvidia cards for example render twice as quick if they just render the depth info)
why this is good is cause, at the moment im doing shadows with cubemaps but doing the comparison in the colorbuffer, effectively working at halfspeed (or even slightly yes than that)

Jan
08-04-2005, 03:20 PM
God, didn't we have this conversation often enough??

1) R-Coordinate is in use already
2) you can do it by using float-textures and compare it manually in a shader

Now to the more important stuff:
Shadowcubemaps are not efficient, because

3) all sides are sized equally
4) you can't easily change the detail of the cubemap (or individual faces of the cubemap), because you would need several differently sized cubemaps, which burns memory
5) you need to recreate the cubemap every frame, because there is not enough memory to store each shadow-cubemap => you really really don't want to do more work to create it, as necessary
6) use 6 2D textures instead, that's more space-efficient (several sizes possible), you can use lower detail on less important faces
7) actually you don't even need 6 textures, but only 1, which you reuse several times
8) you get the full speed of traditional 2D shadow-mapping, without additional extensions
9) you can cull each face individually
10) some other stuff i can't explain properly in english

Did i forget something?

Good night,
Jan.

zed
08-04-2005, 07:21 PM
God, didn't we have this conversation often enough??sorry ive missed it before

jan youre a smart guy but your points 3-10 aint really valid
have u implemented both methods? (i have btw)

3/ ok this is true but really is anyone actually using different sized textures for the different viewpoints, at the moment i measure the light area onscreen and then pick the approriate sized (preexisting) cubemap to fill
4/what memory? a 256pixel sized cubemap aint exactlly expensive, esp when considered in the effect it produces ie shadows, compare that with a lot of games that use maybe a 1024x1024sized texture for a characters head
5/memory again? if your lights are dynamic (or include moving objects) yes u need to recreate the cubemap each frame.
6/ditto
7/huh? doesnt seem efficent
9/nothing stops u from doing this with cubemaps
at the moment im only rendering into the cubemap faces that contain shadowcaster polygons, ie u might only update one side of the cubemap

Jan
08-05-2005, 01:34 AM
Will shadow-cubemaps be used in professional games?

The thing is, nVidia and ATI won't waste resources on implementing something, that is not important.

And, no, professional games won't use shadow-cubemaps. They will all use the 2D texture approach. Stalker does (see GPU Gems 2). The next id-engine almost certainly does (see John Carmacks video interview). And if the Unreal 3 engine uses shadow-mapping at all (which i don't know), then it will use this approach, too.

And all the others? Well, everybody who wants to use omnidirectional shadow-mapping, can do it with 2D texturing. Even, if they don't use advanced culling or lod techniques. So, there is no MISSING feature. But the moment a programmer wants to heavily optimize their shadows, he will use the 2D approach.

Therefore the decision is simple. There will be no shadow-cubemaps. Ever. Well - at least not in the "near" future.

That's it. And therefore it does not make sense to discuss about it any further.

BTW: You want to use 256^2 sized shadow-maps? Ok, i agree, in that case memory is not such a big concern. However, i don't know what kind of application you are doing. In a first-person engine a 256^2 sized shadow-map will, in most cases, not give very pleasing results. I was thinking about using 1024^2 sized textures, at least for important lights (i know, that costs a lot of processing power). However, one single cubemap would then take 18 MB (24 Bit).

With 2D textures you could use 2 1024^2 sized textures (6 MB) and first render to texture A and do shadow-mapping with texture A, then use texture B, and then use texture A again - to address the issue, that frequently reusing the SAME texture for rendering and texturing might not be efficient, as you stated above.

Jan.

Slang
08-05-2005, 02:06 AM
Hey, what about Dual-Paraboloid Shadow Mapping, by the way?
http://www.doomiii.jp/slang/archives/flx_demo_pa_1_0.htm

It's nonlinear though. :p

knackered
08-05-2005, 05:06 AM
what's the difference between that method and using standard shadow mapping for two 180degreeFOV spot lights pointing in opposite directions?

Vexator
08-05-2005, 05:07 AM
i'd love to see the source for this.. was totally stunned when i saw it the first time.

ZbuffeR
08-05-2005, 05:38 AM
@knackered: standard linear projection (3D to 2D plane) can't do 180 fov.
http://wouter.fov120.com/gfxengine/fisheyequake/compare.html

Slang
08-05-2005, 06:51 AM
knackered,

As ZbuffeR already mentioned, it is not possible to make a 180 degree fov shadow map using linear projections like gluPerspective(). So, in order to do that, you have to take a nonlinear method such as the parabolic projection. (i.e. making a paraboloid map)

Nonlinear projections can be achieved by vertex shaders. In the case of the Dual-Paraboloid, you can see my GLSL shaders of the demo that you can download from the webpage I linked above.

However, by the way, the result of the paraboloid shadow map will be pretty bad if meshes are not tessellated enough. It is because the precision of the fragment depth linear-interpolation is be decided on the numbers of vertices. Consequently, this is gonna be a big problem in games and this is why the Dual-Paraboloid is not used in today's games. (Certainly, the numbers of vertices in games are still increasing though)

...

Vexator,

I'm sorry that I don't release the source code of the Dual-Paraboloid Shadow Mapping demo. But as I said, the shader source files used in the demo is included in "data\shaders".

Korval
08-05-2005, 12:22 PM
6) use 6 2D textures instead, that's more space-efficient (several sizes possible), you can use lower detail on less important faces
7) actually you don't even need 6 textures, but only 1, which you reuse several times
8) you get the full speed of traditional 2D shadow-mapping, without additional extensions
9) you can cull each face individuallyConsidering that this rendering methadology utterly strips away from shadow mapping 100% of its advantages over shadow volumes, why would you bother? The principle advantages of shadow mapping are that it only requires N + 1 passes, while shadow volumes require 2N + 1 passes. The only way to retain this for point lights is to either use cube maps, or use 6 independent textures.

zed
08-05-2005, 12:30 PM
Hey, what about Dual-Paraboloid Shadow Mapping, by the waynot good, the geometry has be tesselated quite well


Therefore the decision is simple. There will be no shadow-cubemaps. Ever. Well - at least not in the "near" future2 major points in favour of cubemaps over 2shadowmaps (from my testing even with cubeshadowmaps being 2x slower than rendering just the depth, they still are a lot quicker than emulating a pointlight with standard 2d shadowmaps

A/ they do NOT suffer from backprojection, the this allows them to run faster

B/with standard SMs when u draw the shadow recievers what do u do when the meshes straddle the SMs frustums eg in the down+left directions.
u either have to bind 2(or more) SMs and draw the geometry or draw the shadow reciever multiple times
this is obviously slower than cubemaps method of 1 texture bind and one reciving rendering pass


BTW: You want to use 256^2 sized shadow-maps? Ok, i agree, in that case memory is not such a big concern. However, i don't know what kind of application you are doing. In a first-person engine a 256^2 sized shadow-map will, in most cases, not give very pleasing results. I was thinking about using 1024^2 sized textures, at least for important lights (i know, that costs a lot of processing power). However, one single cubemap would then take 18 MB (24 Bit)ok this is true in my case im using smaller SM sizes than the majority of ppl cause A/ mine is a fast action game + B/ there are a lot of lights (btw im also using 8bit lights for extra speed), but i think youre overestimating the memory importance

knackered
08-05-2005, 02:52 PM
Thanks for the pointer, slang.


Originally posted by Korval:
[QUOTE]The principle advantages of shadow mapping are that it only requires N + 1 passes, while shadow volumes require 2N + 1 passes.I always thought it was that they didn't require the huge amounts of fill as stencil volumes, and virtually no scene processing on either the CPU or GPU, unlike stencil volumes. There's also the fact that you can use decently tesselated meshes for your dynamic objects....and they also enable cookie cut textures to correctly cast shadows.
I can't remember the number of passes ever being signalled as a significant issue, not considering the other overwhelming disadvantages of stencil volumes anyhow.

Korval
08-05-2005, 04:20 PM
they didn't require the huge amounts of fill as stencil volumesThe hardware takes care of that by running at greater speeds when not drawing colors.


I can't remember the number of passes ever being signalled as a significant issue, not considering the other overwhelming disadvantages of stencil volumes anyhow.Signalled out by whom?

And you can't deny that being able to go from 2n + 1 to n + 1 passes is an incredible performance boost in and of itself. It may as well be a 2x performance increase. Yes, you could stick with 2n+1 for shadow maps, and you would still get some performance increase. But the increase from an n+1 approach is still greater than what you get with 2n+1. Not only that, you get far fewer shader swaps with n+1 vs. 2n+1.

cass
08-06-2005, 06:04 AM
In terms of data plumbing and coordinate math, there are enough differences between cube maps and shadow cube maps to have delayed their direct hardware implementation. That much is obvious.

I am sure there will eventually be direct hardware support though, because it's obviously useful and not all that difficult to support.

Edit: I should preview and proofread my posts, but I never do.

knackered
08-06-2005, 10:41 AM
Originally posted by Korval:
The hardware takes care of that by running at greater speeds when not drawing colors.I'll take that as a joke at the expense of scalability.


Originally posted by Korval:
Signalled out by whom?By every single person that has ever done a comparison between the two techniques, including myself, john carmack, charles bloom, etc.etc.

dorbie
08-07-2005, 02:10 AM
Cass, the problem is quite interesting though. You have the classic comparrison of texture vs r with a depth map but with a shadow cube map you have the comparrison against the major axis. It seems like this isn't such a big hurdle; the per fragment selection of the test interpolant, because the major axis interpolant is selected prior to the coordinate divide with a cube map per pixel anyway. I don't think cubemaps per se are the issue but that classic depth test texture doesn't fit neatly into that spec. Specifically the major axis instead of the r coordinate used in the texture unit comparrison, but it is always known prior to the fetch, it would seem that the right design could support this for 'free'. The required hardware support seems trivial requiring only some forethought, whether you handle cube edges correctly or not (multiple separate Ma per pixel offers its own solution).

The most significant issue is mapping linear Ma coordinates to frustum depth with suitable precision, or more realistically rendering the individual cube face depth maps with matching axis linear z (as opposed to screen linear z) and something like a vertex shader to asign a perspective correct varying of suitable precision linearly in eye z would do it. You could zbuffer the shadow map face rendering as normal but the depth texture would come from the axis linear perspective correct varying.

That's probably the biggest reason they aren't currently supported, the lack of projection support to get from linear cube map Ma coord to frustum Z on a cube face, and it's not as trivial as it first seems, although I think my workaround could get us there, it's not a huge departure from what's been done by others before.

cass
08-07-2005, 07:23 AM
Hi Dorbie,

I think both things can be critical, but the extra math is required if you want to match the 2D shadowmap model (which I think is a worthwhile goal).

You need to do the extra math to compute window space z for the face (which is (A * |ma| + B) / |ma|), and it can be a little tricky because it can run afoul of perspective correction optimizations if you're not careful.

The plumbing issue is more subtle and implementation dependent, but it can certainly be a real impediment to adding this kind of feature.

At any rate, my purpose for posting was to clarify that I think shadow cubemaps are useful and interesting and will eventually be supported directly in hardware. There are just some quirks about them that make them more complicated to implement than you'd think at first blush.

If they were trivial, we'd already have done them. :-)

Thanks -
Cass

dorbie
08-07-2005, 08:32 PM
That's pretty much what I was saying, but you can't match z without implicit knowledge about the projection matrix that rendered the cube faces, hence my alternative approach; renering shadow depth in linear space to match the Ma projection.

SirKnight
08-07-2005, 10:33 PM
What I don't get is that right now we can simulate a shadow cubemap by rendering our own depth values from a vertex program into a normal renderable color cubemap, then in a shadow fragment program do some multiplies and a comparison to see if a fragment is in shadow or not. If we can so easily do this, why is it so hard to do that in hardware? What we do now with a color cubemap works pretty darn well as far as I'm concerned, what the "hard" issuses are I don't know. The GPU is already capable of doing MUCH more complicated tasks than this. I don't think that it's not implemented b/c it's not trivial, but rather, most well known developers (like Carmack in particular) isn't crying for them. If I'm wrong let me know, I just don't see what the big deal is.

-SirKnight

cass
08-08-2005, 08:08 AM
SirKnight, all I can say is that it "just is" more complicated than you'd think. If you've ever wanted to make a "small change" to a big piece of software, and found yourself dealing with tons of side effects, you'll know what I mean. The same thing often happens with "simple" OpenGL extensions. Quite often, even small changes have broad implications.

Certainly if demand was higher, that would have accelerated things.

SirKnight
08-08-2005, 01:28 PM
You know I just thought of something that would be interesting. Take the MESA code and try to implement (unofficially of course) shadow cubemap support to see what it would take to do it right. Then surely designing the hardware to take care most of that would be easier I would think. Of course it would be slow since it's all software but this would be a nice proof-of-concept.

-SirKnight

Jan
08-08-2005, 02:56 PM
Originally posted by SirKnight:
You know I just thought of something that would be interesting. Take the MESA code and try to implement (unofficially of course) shadow cubemap support to see what it would take to do it right. Then surely designing the hardware to take care most of that would be easier I would think. Of course it would be slow since it's all software but this would be a nice proof-of-concept.

-SirKnightI might be wrong, but i am pretty sure ATI and nVidia DO have their own software renderers just to try out all new ideas, before they try to build the hardware. I mean, surely they didn't just implement shaders and stuff, without testing their usefulness in real life before.

Jan.

Korval
08-08-2005, 03:10 PM
Then surely designing the hardware to take care most of that would be easier I would think.No.

Writing C++ code and writing hardware are two wildly different things. Oh, they're both programming (to a degree), but hardware works using entirely different primitives. And doing it efficiently in hardware is completely different from doing something efficiently in C++.

We know what cubemap shadowmapping means; that's easy enough. The hard part is getting hardware to play along.

Of course, you could always do it the ATi way, where you don't actually implement shadowmapping in hardware at all, instead relying on the fragment shader to do the shadow computations.

One last thing, about the coordinate that specifies the test value. Is it so difficult to just make it so that the texture unit takes another parameter to its shadow processing? Rather than trying to overload the largest magnitude coordinate or some other thing.

cass
08-08-2005, 03:48 PM
Originally posted by Korval:
One last thing, about the coordinate that specifies the test value. Is it so difficult to just make it so that the texture unit takes another parameter to its shadow processing? Rather than trying to overload the largest magnitude coordinate or some other thing.It's not too hard to do what you suggest, and that is a reasonable (even desirable) implementation approach given the right underlying microarchitecture.