PDA

View Full Version : Nvidia's free PCF, how to get it



CruiseElroy
06-29-2011, 04:36 AM
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.

aqnuep
06-29-2011, 05:11 AM
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.

CruiseElroy
06-29-2011, 05:33 AM
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. :)


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.

Dark Photon
06-29-2011, 06:31 AM
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.

CruiseElroy
06-29-2011, 06:49 AM
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.

Dark Photon
06-29-2011, 07:04 AM
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.

CruiseElroy
06-29-2011, 07:29 AM
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

carsten neumann
06-29-2011, 07:41 AM
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 (http://http.developer.nvidia.com/Cg/tex2Dcmpbias.html)?

CruiseElroy
06-29-2011, 08:04 AM
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.

CruiseElroy
07-01-2011, 12:52 AM
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 :)

Dark Photon
07-01-2011, 05:33 AM
Google "Cg shadow mapping", and you immediately come up with some links with source.

Seems from the source in the very first link (http://www.gamedev.net/topic/393224-cg-shadow-mapping-projecting-depth-map/) that you do this to get shadow map lookups with built-in depth comparisons:



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