(Solved) DEPTH semantic in fragment shader output

Has anyone successfully used the DEPTH semantic in the output of a fragment shader? I can’t seem to change a single pixel with it.

Here’s what I’m trying to do: First, render an object in an offscreen buffer. Next, extract the color and depth textures from the offscreen buffer, and put them on a fullscreen card which is rendered with a shader that sets the depth value of each fragment to the value in the extracted depth texture. Finally, render the rest of the scene with the card in front of it. I think this should display the object occluded normally by other parts of the scene. Instead, it displays the object in front of everything.

Here is the fragment shader I’ve written:

void fshader(   float4 l_texcoord0 : TEXCOORD0,
                uniform sampler2D tex_0 : TEXUNIT0,     //color data
                uniform sampler2D tex_1 : TEXUNIT1,     //depth data
                out float4 o_color : COLOR,
                out float o_depth : DEPTH)
    o_color = tex2D(tex_0, l_texcoord0.xy);
    o_depth = tex2D(tex_1, l_texcoord0.xy);

I have checked (by setting o_color.xyz to the value from texture 1) and the depth texture does contain the right data. The fullscreen card has the depth test enabled.

While I’m no expert, I suspect that what’s happening is your shader is writing to the depth buffer just fine, but it is either A) rendered after everything else in the scene, and doesn’t check the depth buffer against the value it writes, or B) rendered before everything else in the scene, and Panda thinks the rest of the scene is obscured so it doesn’t bother rendering anything else.

Have you tried placing the card behind everything else, and rendering it first?

You can use card.setBin(“background”, 10)

to make sure it’s rendered first. Hopefully the other objects will still be rendered, but respect the depth values that your shader wrote.

Thank you.

Well, you were right that it was writing to the depth buffer just fine. The problem seems to have been that the quad was parented to aspect2d. When I reparented it to render and adjusted the vertex program to make it draw like a fullscreen quad, it worked. Perhaps render2d clears the depth buffer before drawing itself?

That seems plausible. The manual says “Anything parented to render2d will be rendered on top of the 3-D scene, as if it were painted on the screen glass.” It doesn’t mention by what mechanism it does this, but maybe it’s by clearing the depth buffer.

It does this by having another DisplayRegion above the one displaying the scene, which is probably set to clear the depth buffer (but not the color buffer). Also, I think render2d has depth testing disabled.