Directx how to account for alpha blending in depth test

369 Views Asked by At

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.

1

There are 1 best solutions below

1
On BEST ANSWER

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