I'm trying to render 3d texture quads with the following properties:
- With lighting (rule out "AlphaTestEffect").
- Transparent background (no opacity levels, just binary opaque or transparent).
- No ordering, eg, I don't want to sort objects by camera distance.
If I just try to render the quads regularly with their transparent background, the result is that even the transparent pixels are written to the depth buffer, which cause a background bug see picture:
So I try to do it with a different way, using the stencil buffer. What I do is the following:
- Render just the transparent pixels on the stencil buffer, to create a mask.
- Render the texture itself, again, using the stencil buffer I created before.
Now it works with the background renderings, but the problem is that different quads with transparent background hide each other in transparent pixels, as seen here:
I'm not sure if it's because the stencil buffer is not cleared between renders or maybe in one of my steps I mistakenly write to depth?
Anyway here's my code (at least the relevant parts of it):
// set effect and settings for the stencil mask phase
_alphaMaskEffect = new AlphaTestEffect(device);
_alphaMaskEffect.World = Matrix.Identity;
_alphaMaskEffect.AlphaFunction = CompareFunction.Equal;
_alphaMaskEffect.ReferenceAlpha = 0;
_alphaMaskEffect.VertexColorEnabled = true;
_alphaMaskEffect.DiffuseColor = Color.White.ToVector3();
_alphaRenderStencilMaskSettings = new DepthStencilState
{
StencilEnable = true,
StencilFunction = CompareFunction.Always,
StencilPass = StencilOperation.Replace,
ReferenceStencil = 1,
DepthBufferEnable = true,
DepthBufferWriteEnable = false,
};
// set settings for the regular rendering phase
_alphaRenderTextureWithStencilSettings = new DepthStencilState
{
StencilEnable = true,
StencilFunction = CompareFunction.Equal,
StencilPass = StencilOperation.Keep,
ReferenceStencil = 0,
DepthBufferEnable = true,
DepthBufferWriteEnable = true,
};
And here's the draw function itself:
// set settings for the stencil buffer rendering
device.DepthStencilState = _alphaRenderStencilMaskSettings;
// render stencil buffer
foreach (EffectPass pass in _alphaMaskEffect.CurrentTechnique.Passes)
{
// draw current pass
pass.Apply();
device.DrawUserIndexedPrimitives
<VertexPositionNormalTexture>(
PrimitiveType.TriangleList,
Vertices, 0, 4,
Indexes, 0, 2);
}
// now render the quad with the stencil buffer
device.DepthStencilState = _alphaRenderTextureWithStencilSettings;
// render effect itself
foreach (EffectPass pass in _effect.CurrentTechnique.Passes)
{
// draw current pass
pass.Apply();
device.DrawUserIndexedPrimitives
<VertexPositionNormalTexture>(
PrimitiveType.TriangleList,
Vertices, 0, 4,
Indexes, 0, 2);
}
tl;dr what's the right way to render 3d quads with transparent background, lighting and without sorting objects by distance from camera? And if it's the code I tried - how do I make the renderings stop hiding each other?