Depth-Blit puzzle


ARB_framebuffer specs say:

If SAMPLE_BUFFERS for the read framebuffer is zero and
SAMPLE_BUFFERS for the draw framebuffer is greater than zero, the value of the source sample is replicated in each of the destination samples.

Suppose you draw a red triangle into a non-MSAA fbo. Afterwards you blit the color- AND depthbuffer of it into a 4xMSAA fbo. Now draw the exact same triangle in green color on top of it (into the MSAA FBO). What would you expect?

I expect to see either a green or red triangle, or maybe red/green zfighting artifacts.

What do I get instead? A brownish mixture of both triangles!

It seems, while doing the blit, the depthvalues are not properly replicated into the destination depthbuffer. When the second triangle gets rendered, the depthtest for the second triangle sometimes failes, sometimes succeeds which results in a mixture of both triangles when the FBO gets finally resolved and displayed. What makes me wonder is, that both, nVidia and ATI fail the same way :frowning: Or am I missing something?

During the whole operation no blending, alphatesting, stenciltesting or SAMPLE_TO_ALPHA_COVERAGE is active.

Can anyone comment on this?

Interesting. Sure sounds like the depth buffer samples are being linearly interpolated when upsampled.

Or that the MSAA depth buffer sample values are slightly jittered w.r.t. the non-MSAA depth buffer samples.

What happens if both your red and green triangle are drawn in a plane parallel to the near clip plane (same Z buffer depth value)?

What happens if both your red and green triangle are drawn in a plane parallel to the near clip plane (same Z buffer depth value)?

In this case, it “works” on my machine (GF8800GTS) as expected. If the depthtest is GL_LESS, the first (red) triangle is visible, if the depthtest ist GL_LEQUAL, the green triangle surives.

Thanks for asking this… I think I just may have found an explanation for my observation (in ARB_multisample):

Depth operations use the fragment depth value that is specific for each sample. The single fragment color value is used for all sample operations, however, as is the current stencil value.

So, if the triangle is rotated, the per-sample depth values of the msaa-triangle are not the same for all samples of each pixel, resulting in some samples that fail the depthtest against the non-msaa triangle and some samples pass it. …and as a result I get the brownish mix :frowning:

Would that be correct?

That sounds right, and that’s the flip-side of what I was thinking. Yours makes more sense and seems consistent with the spec. That is, upsample replicates pixel-center depths. Rendering MSAA generates different depths sloped about the depth of the pixel center.

Given a larger number of MSAA samples, about 50% would be above and 50% below, resulting in a nice homogenous brown. But with something like 2X MSAA with a simple reconstruction filter, I’d imagine you could find angles where this breaks down.