3
\$\begingroup\$

Alright, just finished most of my early UI stuff and I wanted the windows to have some transparency. So I expanded my application to initialize and bind blend states so that my UI shader could implement alpha blending. I was initially having no luck but I got the blend state configured to achieve my purpose, however the way it is configured doesn't make sense to me so I must be missing something.

Here is how I initialize my blend state.

bool BlendState::StartUp() {
    D11DeviceManager* _pDeviceManager = D11DeviceManager::GetSingleton();

    D3D11_BLEND_DESC _desc;
    _desc.AlphaToCoverageEnable = false;
    _desc.IndependentBlendEnable = false;

    _desc.RenderTarget[0].BlendEnable            = true;
    _desc.RenderTarget[0].SrcBlend               = D3D11_BLEND_SRC_COLOR;
    _desc.RenderTarget[0].DestBlend              = D3D11_BLEND_DEST_COLOR;
    _desc.RenderTarget[0].BlendOp                = D3D11_BLEND_OP_ADD;
    _desc.RenderTarget[0].SrcBlendAlpha          = D3D11_BLEND_SRC_ALPHA;
    _desc.RenderTarget[0].DestBlendAlpha         = D3D11_BLEND_DEST_ALPHA;
    _desc.RenderTarget[0].BlendOpAlpha           = D3D11_BLEND_OP_ADD;
    _desc.RenderTarget[0].RenderTargetWriteMask  = 7;

    return !FAILED(_pDeviceManager->GetDevice()->CreateBlendState(&_desc, &pBlendState));
}

Right now my alpha blending only works when the AlphaToCoverage bool is set to false... I thought this was just a bool enabling the pixel fragment blending (which upon retrospection would be redundant considering the BlendEnable flags...) but looking at the MSDN documentation is appears to do this...

You can use the AlphaToCoverageEnable member of D3D11_BLEND_DESC1 or D3D11_BLEND_DESC to toggle whether the runtime converts the .a component (alpha) of output register SV_Target0 from the pixel shader to an n-step coverage mask (given an n-sample RenderTarget). The runtime performs an AND operation of this mask with the typical sample coverage for the pixel in the primitive (in addition to the sample mask) to determine which samples to update in all the active RenderTargets.

Could someone explain this to me and how it differs from when the AlphaToCoverageEnable bool is false? I see that it adds a new mask to the fragment but I don't quite follow what the mask exactly is.

\$\endgroup\$
2
  • \$\begingroup\$ The boolean turns on alpha-to-coverage (which is not alpha blending). Are you asking what alpha-to-coverage is or is useful for? \$\endgroup\$
    – user1430
    Commented Jan 16, 2012 at 19:42
  • \$\begingroup\$ Yeah, I had a misconception with it and now I realize I don't understand the concept behind it at all. \$\endgroup\$ Commented Jan 16, 2012 at 20:15

1 Answer 1

7
\$\begingroup\$

When rendering with multisampled anti-aliasing, a coverage value is computed for each fragment; this coverage value is based on the fraction of the pixel that would be covered by the fragment based on the triangle that created the fragment. The net result is that the edges of the triangle are anti-aliased. Because the coverage is based ultimately on what the originating primitive covers, only the edges are anti-aliased. Fragments on the interior of the primitive are rendered normally. Blending is applied to those interior fragments, but to do blending properly one must normally sort one's primitives from back-to-front to achieve correct results.

Sprites or other billboarded textures can be sorted (although it's sometimes expensive), but non-billboarded quads are sometimes used for rendering large volumes of grass, foliage or hair and cannot always be effectively sorted back-to-front. Alpha testing can be used in such a scenario (which essentially allows the alpha channel to determine if the fragment is visible or not, without blending it) but creates aliasing.

Alpha-to-coverage attempts to solve the problem by allowing the alpha value of a fragment to be used as its coverage value (the value that would normally be computed based only on the primitive). This allows you to have varying, appropriate coverage values for the fragments within the source primitive and achieve nicer looking anti-aliased transparency when doing MSAA.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .