PCSS / CSM and TEXTURE_COMPARE_MODE

Hello everybody !
I am integrating PCSS (percentage-closer soft shadows) with CSM (cascaded shadow maps) in GLSL.
The problem is that it is obviously not possible to do both, read the z-value from the shadow map (needed for the PCSS blocker search and done with sampler2DArray) and use the hardware accelerated depth comparison mode (needed for the percentage closer filtering (PCF) and done with sampler2DArrayShadow).
Meanwhile I use for PCF sampler2DArray as well and doing the depth comparison in the shader code, but I get a performance hit I would like to avoid. In the original PCSS code from the Nvidia web site HLSL shader are used and the shadow map can be accessed via the functions tDepthMap.SampleLevel with a PointSampler to retrieve the z-value of the shadow map and tDepthMap.SampleCmpLevelZero with a ComparisonSampler to do the hardware-accelerated z-comparison with 4 shadow map z-values.
The question is how to switch in one GLSL-shader between the hardware-accelerated z-comparison mode and the z-retrieval mode without a performance hit ?
The problem with GLSL is that I have to set the glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE) for the z-comparison and the glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_COMPARE_MODE, GL_NONE) for the z-value retrieval in the OpenGL-program and cannot switch between them in the shader !

Any ideas on how to do this without a big performance hit would be greatly appreciated !

Cordially yours
EMIT_Shadow

Heh, try the following:
-set GL_COMPARE_R_TO_TEXTURE
-bind the texture in 2 different slots: one is accessed via sampler2DArray and the second via sampler2DArrayShadow

There can be no HW comparison with depth by using sampler2DArray, because you just don’t pass the depth anywhere :slight_smile:

I’m not sure what you mean. If you mean create two samplers and set both uniforms to the same value, it won’t work. The code below is invalid. You cannot use the same texture unit for both shadow and non-shadow sampling.


glUniform1i(shadowSamplerUniform, texUnit);
glUniform1i(samplerUniform, texUnit);

However, I think you can bind the same texture to two different texture units. I haven’t tried it, and the spec may not allow it. It seems reasonable, though.


glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, shadowMapTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowMapTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

glUniform1i(samplerUniform, 0);
glUniform1i(shadowSamplerUniform, 1);

Of course I mean to use 2 texture units. However, in the second code sample you don’t need to do:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);

just because later you nevertheless overwriting it with GL_COMPARE_R_TO_TEXTURE. Be careful: these settings are per texture, not per texture unit.

As I said before, don’t worry about the compare mode setup: it will not be used for the first sampler anyway.