Quote: ...instead of returning a texture color, tex2Dproj returns a value representing shadow coverage. The underlying hardware implementation automatically recognizes when a texture is a depth texture (instead of a color texture) and performs the shadow map comparison instead of an ordinary texture fetch.I'm trying to change my shaders. But I still cannot work out what to pass as the second argument of the tex2Dproj function do make the depth comparison and shadow value computation. Could somebody please be so kind and try to explain it to me? Which light related matrices I must multiply with what etc. I've searched the web a lot, my head is going to explode soon, but I found only some articles about this, never fully complete (no FULL example code), each of them different and I didnt manage to work it out as it's hard to guess anything from a matrix name like matShadow etc. Thank you very much in advance With respect, Tom PS: Dunno if this is important but I'm using directional light so my light camera projection matrix is orthogonal.
Using tex2Dproj for shadows
Hello,
I have working shadow mapping in my application, using the tex2D HLSL function. But as I'm still hearing everywhere that there is something like a HW PCF on nVidia cards, which is applied when you use tex2Dproj function, and that this function automatically does the depth comparison as well, for example (http://www.mpi-inf.mpg.de/departments/irg3/ws0405/cg/rcomp/23/index.html):
I guess I got the projective texturing working, but as you can see on the picture it just simply projects the shadow map on the scene while it should automatically do the depth comparing (and a small PCF which of course is there neither although I use bilinear filtering).
How do I "tell" the GC that I'm doing shadow mapping and not just normal texture projection?
I know how to do the depth comparing myself, also how to do PCF, but I would like to see the GC do it for me using its HW soft shadows ;) (I don't care that it works only on nVidia cards.)
This is a screenshot from a simple testing application and the ground box is the only one who receives shahows (or better said "should receive shadows")
How do I "tell" the GC that I'm doing shadow mapping and not just normal texture projection?
I know how to do the depth comparing myself, also how to do PCF, but I would like to see the GC do it for me using its HW soft shadows ;) (I don't care that it works only on nVidia cards.)
This is a screenshot from a simple testing application and the ground box is the only one who receives shahows (or better said "should receive shadows")
tex2Dproj doesn't do anything like what you are trying to get it to do. It simply projects the texture. You need to write a shader that does the comparison yourself, it will use tex2Dproj but you'll do some sort of depth comparison manually.
Are you really sure?
Also look at the code fragments on this GPU Gems page chapter 11
they also use tex2Dproj and there is no mark of any comparison in the code.
And also here:
which is from another GPU Gems page chapter 10 (this one actually has a more complete code and it was my best reference, but it still doesn't say everything).
There can be found many other remarks about this feature on the internet
(link), most of them are about OpenGL tho.
Quote:
quote from link
When we do a projective texture lookup on a shadow map, the hardware automatically takes care of the comparison for you: the tex2Dproj function returns a value that represents how "lit" the current pixel would he. That is, the tex2Dproj function returns a four-component vector of the form (c, c, c, 1), where c is 0 if the pixel is in shadow, and 1 if the pixel is lit. You can then treat this vector as a color. If bilinear texture filtering is enabled, c will range from 0 to 1 instead of being restricted to just the two values. Filtering is useful along the shadow boundaries, where the transition between being fully occluded to fully lit takes place. In these situations, the filtering helps make the shadow look softer, and reduces edge aliasing (jaggedness).
Also look at the code fragments on this GPU Gems page chapter 11
they also use tex2Dproj and there is no mark of any comparison in the code.
And also here:
float shadow = tex2Dproj(Shadow, ShadowUV).x;// Modify the light color so that it blends with the shadow color// in the shadow areasfloat3 mixedLightColor = lerp(ShadowColor, Light.color, shadow);
which is from another GPU Gems page chapter 10 (this one actually has a more complete code and it was my best reference, but it still doesn't say everything).
There can be found many other remarks about this feature on the internet
(link), most of them are about OpenGL tho.
Yes. That article is wrong. And in the GPU gems article, they aren't technically using shadow maps, they are using textures that look like shadows when projected. What you have is a depth map, not a shadow texture, so to turn it into a shadow texture that you can project onto the scene you need to do a comparison with the real depth to see whether the pixel is in shadow.
If you want soft shadows you have to compute your shadow texture (not depth map) and then use a sampling pattern larger than one pixel.
If you want soft shadows you have to compute your shadow texture (not depth map) and then use a sampling pattern larger than one pixel.
Quote:Original post by AnAss
Yes. That article is wrong.
You mean all those articles all over the internet are wrong?
Quote:Original post by AnAss
And in the GPU gems article, they aren't technically using shadow maps, they are using textures that look like shadows when projected.
Did you look at both the GPU Gems articles? This one ch11 is IMHO (but only IMHO) clearly about shadow maps with depth comparison. The code fragments are not very clear, but there is no "manual" depth comparison and it doesn't seem it would be possible to use it in any corresponding unshown code as it produces a shadowCoef computed from multiple samples (which would mean they would be comparing average of multiple depths and that would not work). :O
Quote:Original post by AnAss
What you have is a depth map, not a shadow texture, so to turn it into a shadow texture that you can project onto the scene you need to do a comparison with the real depth to see whether the pixel is in shadow.
If you want soft shadows you have to compute your shadow texture (not depth map) and then use a sampling pattern larger than one pixel.
Yep, I know this, as I said in the very first sentence, I've already implemented shadow map shadows with some filtering to soften them, I'm just using tex2D function to do the shadow map lookup (as it is in the Shadowmap example in DX SDK).
This is actually quite weird, on one hand I'm still finding notes about something like HW soft map shadows which work only on nVidia cards (including gamedev.net forums, that's btw where I first found it) with "built-in" PCF enabled just by using bilinear sampling, while on the other hand there seems to be nobody really using it :)
Looks more and more like a myth to me :D
The first article I found mentions nothing of this automatic tex2Dproj shit:
http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series3/Shadow_mapping.php
However, also on the very first page of results for "shadow mapping HLSL", was what you are looking for: On nvidia hardware, create the depth map with D24S8_SHADOWMAP: http://developer.nvidia.com/forums/index.php?=&showtopic=34
I've never used that format before, and it sounds like it still doesn't do what you want (automatic depth comparison), just that it does the filtered sampling for you.
The Gpu gems chapter 10 is not using shadow maps as you think. Those textures are simply textures they project into the scene to look like shadows. There is no shadow mapping involved. In chapter 11, they do the sampling I mentioned if you want soft shadows and don't use the D24S8_SHADOWMAP format. But they are doing the sampling AFTER they have compared the shadow map with the scene and produced a shadow texture.
http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series3/Shadow_mapping.php
However, also on the very first page of results for "shadow mapping HLSL", was what you are looking for: On nvidia hardware, create the depth map with D24S8_SHADOWMAP: http://developer.nvidia.com/forums/index.php?=&showtopic=34
I've never used that format before, and it sounds like it still doesn't do what you want (automatic depth comparison), just that it does the filtered sampling for you.
The Gpu gems chapter 10 is not using shadow maps as you think. Those textures are simply textures they project into the scene to look like shadows. There is no shadow mapping involved. In chapter 11, they do the sampling I mentioned if you want soft shadows and don't use the D24S8_SHADOWMAP format. But they are doing the sampling AFTER they have compared the shadow map with the scene and produced a shadow texture.
Tom KQT is right, the depth comparison and filtering ARE done automatically if you use hardware shadow mapping..and yes tex2DProj is the way to do it. (it only works on Nvidia GPUS unfortunately..I dont know how ATI does it)
Get the Nvidia GPU programming guide (its downloadable and packed with lots of useful info) and see page 52..this explains it in detail..the basic thing is this:
In DirectX, you can create a hardware shadow map in the following way:
1) Create a texture with usage D3DUSAGE_DEPTHSTENCIL
2) The format should be D3DFMT_D16, D3DFMT_D24X8
then you just make your texture projection matrix like this
V’ = Bias(0.5/TexWidth, 0.5/TexHeight,
Bias(0.5, 0.5, 0) *
Scale(0.5,0.5,1) *
ViewProjsaved * World * Object * V
then...
11) If using pixel shaders 1.4 or higher, perform a projected texture fetch from the shadow map sampler.
12) The hardware will use the shadow map texture coordinate’s projected x and y coordinates to look up into the texture.
13) It will compare the shadow map’s depth value to the texture coordinate’s projected z value. If the texture coordinate depth is greater than the shadow map depth, the result returned for the fetch will be 0 (in shadow); otherwise, the result will be 1.
14) If you turn on D3DFILTER_LINEAR for the shadow map sampler, the hardware will perform 4 depth comparisons, and bilinearly filter the results for the same cost as one sample—this just makes things look better.
Get the Nvidia GPU programming guide (its downloadable and packed with lots of useful info) and see page 52..this explains it in detail..the basic thing is this:
In DirectX, you can create a hardware shadow map in the following way:
1) Create a texture with usage D3DUSAGE_DEPTHSTENCIL
2) The format should be D3DFMT_D16, D3DFMT_D24X8
then you just make your texture projection matrix like this
V’ = Bias(0.5/TexWidth, 0.5/TexHeight,
Bias(0.5, 0.5, 0) *
Scale(0.5,0.5,1) *
ViewProjsaved * World * Object * V
then...
11) If using pixel shaders 1.4 or higher, perform a projected texture fetch from the shadow map sampler.
12) The hardware will use the shadow map texture coordinate’s projected x and y coordinates to look up into the texture.
13) It will compare the shadow map’s depth value to the texture coordinate’s projected z value. If the texture coordinate depth is greater than the shadow map depth, the result returned for the fetch will be 0 (in shadow); otherwise, the result will be 1.
14) If you turn on D3DFILTER_LINEAR for the shadow map sampler, the hardware will perform 4 depth comparisons, and bilinearly filter the results for the same cost as one sample—this just makes things look better.
I've never seen that behavior, and the link earlier to a post by an admin on nvidia's site contradicts what you said (you need to use D24S8_SHADOWMAP to get PCF filtering, unless you meant straight up bilinear filtering, which doesn't smooth the results much...)
I suppose this could have been happening to me all along and I never would have noticed because a depth comparison would still result in the right answer, but it would obviously be unnecessary. Sorry Tom, this is quite a suprise to me after using this for several years now... Luckily I never wanted the actual depth value, I would have been seriously pissed if this would happen automatically and I couldn't stop it without copying the depth map to a non-depth stencil texture.
To answer your original question, to get hardware PCF, use D24S8_SHADOWMAP.
I suppose this could have been happening to me all along and I never would have noticed because a depth comparison would still result in the right answer, but it would obviously be unnecessary. Sorry Tom, this is quite a suprise to me after using this for several years now... Luckily I never wanted the actual depth value, I would have been seriously pissed if this would happen automatically and I couldn't stop it without copying the depth map to a non-depth stencil texture.
To answer your original question, to get hardware PCF, use D24S8_SHADOWMAP.
Thx God, I was slowly starting to feel like an idiot :) as those GPU Gems articles really smells of real shadow mapping, there are few sentences which point to that, for example a mention that you cannot simply blur the shadow map (which would be possible with no problem for projected shadows).
About the format D24S8_SHADOWMAP, I found something about it too, but DirectX doesn't know this format :O
It really seems to me that what Matt Aufderheide said should work (formats without _SHADOWMAP), I'll give it a try. Currently I'm creating the shadow map differently, I'm writing the depth in a pixel shader to a D3DFMT_R32F texture (as in DX SDK sample), not simply employing a depth stencil. That can be why GC doesn't know I would like to make shadows and not just projection.
Thx everybody so far. I'll let you know when I test it.
Tom
About the format D24S8_SHADOWMAP, I found something about it too, but DirectX doesn't know this format :O
It really seems to me that what Matt Aufderheide said should work (formats without _SHADOWMAP), I'll give it a try. Currently I'm creating the shadow map differently, I'm writing the depth in a pixel shader to a D3DFMT_R32F texture (as in DX SDK sample), not simply employing a depth stencil. That can be why GC doesn't know I would like to make shadows and not just projection.
Thx everybody so far. I'll let you know when I test it.
Tom
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement