How to get distance using a sampler2DShadow?


I am using sampler2DShadow + shadow2DProj() to perform shadow mapping. However, I need to fetch the distance value contained in that depth map texture, but shadow2DProj() only returns whether I’m in shadow or not.
As the sampler comparison function has been configured as GL_COMPARE_R_TO_TEXTURE, using texture2D() from GLSL to fetch the distance stored in the depth map won’t work.

So, do I need to use two different shaders (and thus two different passes) and disabling the GL_COMPARE_R_TO_TEXTURE in the second pass to fetch the contents of the depth map?

Do I need to replicate the depth map configuring it with different GL_COMPARE_R_TO_TEXTURE models and assigning them to different texture units to be able to use both shadow2D() and texture2D() ?

In practice is there a huge difference in performance using texture2D() instead of shadow2D()?

Thank you in advance.

Why not fetch the depth value from the texture and perform the GL_COMPARE_R_TO_TEXTURE operation in the shader yourself?

Because I thought that performing it via the shadow2DProj() function was faster than doing it manually in the shader. Am I wrong?

Most likely, but it will surely be faster than using two rendering passes. If you don’t mind performing two texture lookups maybe you can bind the same depth map to both a sampler2DShadow and a sampler2D and use the same texture coordinates for performing the texture lookup.

I don’t mind performing one more texture lookup. However, the depth map has to be configured either GL_COMPARE_R_TO_TEXTURE or not, thus either shadow2DProj or texture2D will fail. Because according to the specs, when GL_COMPARE_R_TO_TEXTURE is enabled then the return values of texture2D() are undefined.

Yes, but the GL_COMPARE_R_TO_TEXTURE mode is limited to a texture unit and you’re binding them to different units.

unit 0 -> GL_TEXTURE_COMPARE_MODE = GL_COMPARE_R_TO_TEXTURE -> sampler2DShadow sampler1 -> shadow2DProj(sampler1, texcoord.xy)
unit 1 -> GL_TEXTURE_COMPARE_MODE = GL_NONE -> sampler2D sampler2 -> texture2DProj(sampler2, texcoord.xy)

No, GL_TEXTURE_COMPARE_MODE is not texture unit state. It is texture object state.
So you’d have to create two texture objects if you want to use one as depth and one as shadow.

Yes, this is stupid.

If you don’t care about using the (implementation-dependent, possibly non-existent) hardware PCF filtering, sample it once as depth and do the comparison manually in the shader.

Are you sure? Haven’t tried it myself, but this is what the spec says

If the currently bound texture’s base internal format is DEPTH COMPONENT, then
control the output of the texture unit as described below. Otherwise, the texture
unit operates in the normal manner and texture comparison is bypassed.

It’s kinda misleading :slight_smile:

I’ve tried it. I’ve implemented it. I’m sure:

Accepted by the <pname> parameter of TexParameterf, TexParameteri,
TexParameterfv, TexParameteriv, GetTexParameterfv, and GetTexParameteriv:


It says TexParameter. Not TexEnv.

Then, I’ll have to replicate the texture if I want to use both shadow2Droj() and texture2D() in the same shader, right?

However, I think that the most sensible decision is to apply the shadow map doing only texture2D() and performing the comparison manually in the shader.

Thank you very much guys!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.