Nvidia's free PCF, how to get it

Hi,

I’m trying to get free PCF working on my shadows, something that I have heard and read about, but I can’t find any solid info on the specifics.
It seems that most solid info on it is hidden behind broken links (or I REALLY suck at googling)

I’m writing the shaders in CG, not directly in HLSL

First what I’ve read so far:

Sampler/Texture settings:

  • Some forum(post)s state that simply changing filtering of the depth texture is enough, this doesn’t seem to be true
  • I have read that the texture format should be DEPTH_STENCIL, some others have stated that it should be DEPTH_COMPONENT or some Nvidia specific format
    Combined with above, i could not get any results, and I couldn’t find any reference to a Nvidia specific format.

GLSL:
Some have said Texture2D should be used, some others have said Shadow2D should be used.
Some say a different kind of sampler-type should be used (can’t remember the name by heart atm)
I couldn’t get any code to compile by using above keywords in my shaders, I probably need their CG-coutnerparts, if they exist.
I’m also unclear of how the extra “compare value” should be passed to the sampling instruction (texture2D/shadow2D). Should it be the extra third component of the sampling coord?
I have almost nog OpenGL background, but I do have worked some years with DirectX. On some hardware, Using Tex2D() with a third component (and corret sampler settings) was enough to trigger PCF under DX.

I have tried to use the ARB_Shadow Texure comparison state, (COMPARE_TEXTURE_TO_R) but I couldn’t really get it to work correctly.
I couldn’t make heads or tails of the ARB_Shadow OpenGL Spec for explenation of how the comparison works
(it seems to be doing compare between the (2D?3D?) V coord and the scalar (?) depth value, but I don’t see how that would work)
see: http://www.opengl.org/registry/specs/ARB/shadow.txt

It seems that the COMPARE_TEXTURE_TO_R stuff seems to be ARB_shadow specific, while Shadow2D is part of a later OpenGL spec?
Are some extra extensions needed?

Help would be greatly appreciated.

You can do “free” 4-tap PCF shadow mapping using gathered texture fetches (http://www.opengl.org/registry/specs/ARB/texture_gather.txt), however this is only available on DX10.1 class hardware (GeForce 200 series, Radeon HD3000 series).

Actually I know that there was earlier support for 4-tap hardware PCF on both NVIDIA and ATI cards, however I don’t know whether it is exposed in any fashion in OpenGL.

I know it should be possible, I can find some info on it, scattered around the internet, but nothing that I could actually put together to create a working shader. :slight_smile:

Oh, and I completely forgot to mention that I use CG, not GLSL. I’ll put it in the OP, since it probably explains some of the issues.

  glGenTextures  ( 1, &depth_tex );
  glBindTexture  ( GL_TEXTURE_2D, depth_tex );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER  , GL_NEAREST );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER  , GL_NEAREST );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S      , GL_CLAMP_TO_EDGE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T      , GL_CLAMP_TO_EDGE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE );
  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );
  glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE  , GL_INTENSITY );
  glTexImage2D   ( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, xres, yres, 0, 
                                  GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0 );

The keys being 1) use a depth component or depth+stencil texture, 2) enable hardware depth comparisons, 3) Set filters to LINEAR.

Hmm, I just found out that, if I use 3 components for my tex2D call, it basically “breaks” and starts sampling a random texture without depth compare.

Even with the correct COMPARE_ settings, tried LINEAR and NEAREST sampling, both give the same result.

In GLSL, you have to use a sampler2DShadow sampler and pre-GLSL 1.3 a shadow2D* texture access function. In 1.3+, they got rid of the latter and you just use texture*.

In Cg, dunno. Check the Reference Manual.

Tested some more, with the DEPTH_TEXTURE_MODE also set, but still, the tex2D() seems to completely break.

CG doesn’t really give any reason this should happen:
http://http.developer.nvidia.com/Cg/tex2D.html

Hmm, haven’t done this with CG, but given that others correctly pointed out that with GLSL you need a sampler2DShadow (and possibly the correct texture access function), have you tried CG’s tex2Dcmpbias?

Hmmm, the cg compiler doesn’t recognize tex2Dcmpbias, which is strange I think. No mention of shadow2D or shadow2DShadow in the docs anywhere.

I am building with -profile fp40 so that should be allright.

Can’t get it to work, It seems that the CG compiler isn’t outputting the correct GLSL to get the compare-feature activated properly.
I’ll take a closer look later on when I have the tools and the time to go through the GLSL output.

Thanks everyone :slight_smile:

Google “Cg shadow mapping”, and you immediately come up with some links with source.

Seems from the source in the very first link that you do this to get shadow map lookups with built-in depth comparisons:


uniform sampler2D shadowMap : TEXUNIT0
...
float4 shadowed = tex2Dproj(shadowMap, shadowCoordProj)