Q:

XNA / MonoGame: depth sorting alpha blended UserPrimitives

Googling around a lot for this, read this very useful article, but still wondering about a solution for my project. This screenshot illustrates my problem perfectly:

There are 2 objects: the red object which consists of 2 quads, one with z-index of -1 and the other one with a z-index of 1. Both quads have Color.Red * 0.5f. Gets drawn first. The other object is the player with z-index 0. Gets drawn second
Because I want the player to move in between the quads, I have set DepthStencilState to  DepthStencilState.Default; but this provides the following image. The player's pixels get disregarded because there is an object in front of it.
I batch all my primitives into one big DrawUserPrimitive based on this class. What is the best solution to this problem? Do I have to sort triangle based on z-index (and how would I do that; is it expensive?) or is there another solution?

A:

You simply have to do exactly what that article says. Here are the instructions listed as "The most common approach", updated for XNA 4:

Set GraphicsDevice.DepthStencilState = DepthStencilState.Default
Draw all opaque geometry
Set GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead
Sort alpha blended objects by distance from the camera, then draw them in order from back to front

If your transparent objects are more-or-less convex, then you don't need to sort triangles - just the objects themselves - as long as you use RasterizerState.CullCounterClockwise (ie: backface culling, the default).
The reason that you must do this is that the depth buffer can only store a single value - which is that of the topmost pixel. There is no concept of drawing "under" that depth. The data that would be required to do that (the colours of the objects drawn above and below that Z-index, at that pixel) has already been blended into the final image and cannot be extracted.

