1

I am trying to implement a simple way to render particles in my toy app. I'm rendering billboarding quads with alpha blending, but this causes a problem with the depth stenciling where parts of the quad that are fully transparent are still obscuring the particles behind them, since they fail depth test. The result looks like this:

enter image description here

This is the way I've setup my pipeline:

// rasterizer
D3D11_RASTERIZER_DESC rasterizerDesc;
rasterizerDesc.AntialiasedLineEnable = true;
rasterizerDesc.CullMode = D3D11_CULL_BACK;
rasterizerDesc.DepthBias = 0;
rasterizerDesc.DepthBiasClamp = 0.0f;
rasterizerDesc.DepthClipEnable = true;
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.FrontCounterClockwise = false;
rasterizerDesc.MultisampleEnable = true;
rasterizerDesc.ScissorEnable = false;
rasterizerDesc.SlopeScaledDepthBias = 0.0f;

// depth stencil state
D3D11_DEPTH_STENCIL_DESC depthStencilStateDesc;
ZeroMemory(&depthStencilStateDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
depthStencilStateDesc.DepthEnable = TRUE;
depthStencilStateDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilStateDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilStateDesc.StencilEnable = FALSE;

// blend state
D3D11_BLEND_DESC blendStateDescription;
ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC));

blendStateDescription.AlphaToCoverageEnable = FALSE;
blendStateDescription.IndependentBlendEnable = FALSE;
blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

I've been searching for a while, but not really sure how to setup the depth stenciling to work with alpha blending correctly here, or if even this is the correct approach. Looking at render doc capture it just doesn't care about transparency:

enter image description here

Not sure what other setup might be important here, so let me know in the comments and I'll include whatever else is relevant to this case.

Gregor Sattel
  • 352
  • 3
  • 12

1 Answers1

2

I figured it out eventually. In short there is no automatic way to handle this. A simple implementation is to draw opaque objects first while writing to depth buffer, then draw transparents with only depth test, without writing to depth stencil. Transparents should be sorted by depth and rendered from farthest to closest to view point.

Follow up to previous images:

enter image description here

Gregor Sattel
  • 352
  • 3
  • 12
  • 1
    Yes, the standard algorithm for depth-sorting transparency is to draw all opaques and then draw all alpha objects. You may also need to fully sort the alpha objects a.l.a. the [Painter's algorithm](https://en.wikipedia.org/wiki/Painter%27s_algorithm) for correct blending, but this can be quite challenging and expensive. – Chuck Walbourn Apr 04 '22 at 20:38