How to use hardware accelerated shadows with DirectX?

Started by
5 comments, last by MrSparkle 17 years, 9 months ago
Hi, is it possible to use hardware shadows (like NVidia's UltraShadow technologie) in DirectX game engines? Thanks, Christian
Advertisement
Check out developer.nvidia.com for various papers about exploiting Nvidia specific technologies.

Generally, via Direct3D (less receptive to IHV "extensions") you need to specifiy a proprietary texture format (see MAKEFOURCC() macro) or various other API hacks. None of them are particularly intuitive.

Alternatively, if you enable shadowing via a common method then the driver will recognise what you're doing and enable the appropriate hardware acceleration.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Hi Jack,
thanks for your tips, I read some of the papers at the Nvidia website and I tried to find some information on the ATI website. But it seems that ATI doesn't provide any hardware shadow support. The documentation at NVidia is very poor and some links are broken, too, so I guess it is more interesting what you said last:

> Alternatively, if you enable shadowing via a common
> method then the driver will recognise what you're
> doing and enable the appropriate hardware
> acceleration.

What do you mean with a common method? I create shadow maps in a pre-pass by rendering a depth map from the light's point of view and project the shadow map by the pixelshader. How could this be even more accelerated by the hardware?
Quote:Original post by MrSparkle
Hi Jack,
thanks for your tips, I read some of the papers at the Nvidia website and I tried to find some information on the ATI website. But it seems that ATI doesn't provide any hardware shadow support.
It does, but it's weaker. With X1300 and beyond, they just catched up (feature wise) with NV20 providing Fetch4 (that is, PCF).
Quote:Original post by MrSparkle
> Alternatively, if you enable shadowing via a common
> method then the driver will recognise what you're
> doing and enable the appropriate hardware
> acceleration.

What do you mean with a common method? I create shadow maps in a pre-pass by rendering a depth map from the light's point of view and project the shadow map by the pixelshader. How could this be even more accelerated by the hardware?

Take what I say with some salt because I'm still transitioning to D3D by now, but here's what I got from the GL docs (not guaranteed to apply):

For creating you need to have a depth-stencil surface (go for D24X8, I'm not sure other formats). To get double fill you also must disable color writes maybe a standard Depth compare function. The real limitations is badly HW dependant: as far as I remember this is for NV30, but I could be messing it up. More recent cards will probably just require D24X8 format. Texturing, as far as I remember, is not a problem.

For sampling with PCF, you need a texture comparison operator enabled (sorry, I don't know how to do that in D3D yet) and use SamplerShadow2D (I just overlooked at the HLSL docs so I didn't see a Sampler2DShadow: it's probably not needed in D3D).
This obviously, assuming you know about projective mapping.

Previously "Krohm"

First, let me say thank you for your detailed posting. But...hmmm it seems to me like you're speaking in tongues ;) I guess it's because I'm a very beginner to this DirectX stuff, but I didn't get your point. I mean, I know how to implement a shadow map with DirectX by the shaders and so on. Now, I want to implement some hardware acceleration to this (if available). Some documentation how to do this would help me a lot, but I couldn't find anything that goes into the details at the NVidia website.

I found a sample application, too. But unfortuately it's written in c++ (I write my programs with c#) and there's no documentation included at all.

This is probably not that easy but does anybody know a source where I can find a documentation, a tutorial or a c# sample application?
Quote:> Alternatively, if you enable shadowing via a common
> method then the driver will recognise what you're
> doing and enable the appropriate hardware
> acceleration.

What do you mean with a common method? I create shadow maps in a pre-pass by rendering a depth map from the light's point of view and project the shadow map by the pixelshader. How could this be even more accelerated by the hardware?
I've not tried it myself (using Nvidia hardware), but some (or all?) ATI hardware supports the DF16 texture format (MAKEFOURCC( 'D', 'F', '1', '6' );). Its not a standard Direct3D format (won't be listed in the D3DFORMAT documentation) but when queried/used via D3D the ATI driver will watch out for it and enable the appropriate hardware acceleration...

I've not got them to hand, but the ATI and Nvidia SDK's are going to be your best bet for sample code. Each IHV has an obvious incentive to try and promote their technology by educating developers on how to use it. They tend to put these examples in their SDK's.

Quote:Original post by MrSparkle
I found a sample application, too. But unfortuately it's written in c++ (I write my programs with c#) and there's no documentation included at all.
Many of the advanced techniques still tend to be C++ specific as its still the preferred professional language. However, if you can read C++ code (you dont have to understand every little detail) you can probably decode the necessary API/function calls. It'll usually boil down to setting particular combinations of states/parameters for standard API calls - these you can map to the C# equivalent.

If you find some sample code in C++ and need help converting it to C# you could post the relevant fragments of code here and see if someone can point you in the right direction [smile]

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by jollyjeffers
If you find some sample code in C++ and need help converting it to C# you could post the relevant fragments of code here and see if someone can point you in the right direction [smile]

Cheers,
Jack


Thank you for your offer (and for the information about ATI's approach of HW shadows), I'll get back to this later ;) First, I want to understand the overall concept of hardware accelerated shadows. I found a step-by-step explanation in the NVIDIA GPU Programming Guide (see http://download.nvidia.com/developer/GPU_Programming_Guide/GPU_Programming_Guide.pdf Section 6.2):

Quote:
1) Create a texture with usage D3DUSAGE_DEPTHSTENCIL

2) The format should be D3DFMT_D16, D3DFMT_D24X8 (or D3DFMT_D24S8 , but you can’t access the stencil bits in your shader)

3) Use GetSurfaceLevel(0) to get the IDirectDrawSurface9 Interface

4) Set the Surface pointer as the Z buffer in SetDepthStencilSurface()

5) DirectX requires that you set a color render target as well, but you can
disable color writes by setting D3DRS_COLORWRITEENABLE to zero.

6) Render your shadow-casting geometry into the shadow map z buffer

7) Save off the view-projection matrix used in this step.

8) Switch render targets and z buffer back to your main scene buffers

9) Bind the shadow map texture to a sampler, and set the texture coordinates to be
Bias(0.5, 0.5, 0) *
Scale(0.5,0.5,1) *
V’ = Bias(0.5/TexWidth, 0.5/TexHeight, 0) *
ViewProjsaved * World * Object * V
The matrices can be concatenated on the CPU, and the concatenated transformation can be applied in either a vertex shader or using the fixed-function pipeline’s texture matrices.

10) If using the fixed-function pipeline or ps_1.0-1.3, set the projection flags to be D3DTTFF_COUNT4 | D3DTTFF_PROJECTED .

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.

15) Use this value to modulate with your lighting


I'm going to try implement these steps to my c# graphics engine, if somebody has some hints for me, I'm looking forward to your comments!

Thanks,
Christian

This topic is closed to new replies.

Advertisement