DevSharma
DevSharma

Reputation: 45

alpha blending is not working as it supposed to be

I create a new DirectX project and rendered 2 color components and now when I am passing the transparency from shader it is not changing anything, I am new to c++ and DirectX and I used the standard template from visual studio to create a project

project link: https://github.com/AbhishekSharma-SEG/TestAlphaBlending

Blend State

D3D11_BLEND_DESC blendDesc;
blendDesc.RenderTarget[0].BlendEnable = true;

blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_COLOR;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_COLOR;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;;

blendDesc.IndependentBlendEnable = false;
blendDesc.AlphaToCoverageEnable = false;

auto hr = m_d3dDevice->CreateBlendState(&blendDesc, &AlphaEnableBlendingState);
if (SUCCEEDED(hr)) 
{
    blendDesc.RenderTarget[0].BlendEnable = false;
    m_d3dDevice->CreateBlendState(&blendDesc, &AlphaDisableBlendingState);
    TurnOnAlphaBlending();
}
}
void DX::DeviceResources::TurnOnAlphaBlending()
{
    float input[4] = { 0,0,0,0 };
    m_d3dContext->OMSetBlendState(AlphaEnableBlendingState, input, 1);
}
void DX::DeviceResources::TurnOffAlphaBlending()
{
    float input[4] = { 0,0,0,0 };
    m_d3dContext->OMSetBlendState(AlphaDisableBlendingState, input, 1);
}

Swapchain Desc

// Otherwise, create a new one using the same adapter as the existing Direct3D device.
DXGI_SCALING scaling = DisplayMetrics::SupportHighResolutions ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH;
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};

swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width);      // Match the size of the window.
swapChainDesc.Height = lround(m_d3dRenderTargetSize.Height);
swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;              // This is the most common swap chain format.
swapChainDesc.Stereo = false;
swapChainDesc.SampleDesc.Count = 1;                             // Don't use multi-sampling.
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;                                  // Use double-buffering to minimize latency.
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;    // All Microsoft Store apps must use _FLIP_ SwapEffects.
swapChainDesc.Flags = 0;
swapChainDesc.Scaling = scaling;
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;

Shader

struct PixelShaderInput
{
    float4 pos : SV_POSITION;
    float3 color : COLOR0;
};

float4 main(PixelShaderInput input) : SV_TARGET
{
    return float4(input.color, 0.2f);
}

output

enter image description here

I am unable to find what is wrong, several tutorials and the site only told about setting up the blend state and I tried most of the settings they told me to apply but it is not working also I don't know why but the yellow component is supposed to be behind because renders call for yellow one occurs first but it is printing it above red one if anyone can help, please and thanks

new output after alpha mode ignore and setting blend mode as per straight enter image description here

Edit: Fixed

so after some digging, I found that I m not using the depth stencil state which is causing this issue after using that it resolves, and obviously thanks to @chukWalbourn suggestion I was able to set up the write configuration for blending now it working perfectly fine here are the change that helped in it

//Describe our Depth/Stencil Buffer
CD3D11_DEPTH_STENCIL_DESC depthStencilStateDesc;

depthStencilStateDesc.DepthEnable = false;
depthStencilStateDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilStateDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilStateDesc.StencilEnable = true;
depthStencilStateDesc.StencilReadMask = 0xFF;
depthStencilStateDesc.StencilWriteMask = 0xFF;
depthStencilStateDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilStateDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depthStencilStateDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilStateDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

DX::ThrowIfFailed(
    m_d3dDevice->CreateDepthStencilState(
        &depthStencilStateDesc, 
        &m_d3dDepthStencilState
    )
);

m_d3dContext->OMSetDepthStencilState(m_d3dDepthStencilState.Get(), 1);

Upvotes: 1

Views: 1258

Answers (2)

DevSharma
DevSharma

Reputation: 45

so after some digging, I found that I m not using the depth stencil state which is causing this issue after using that it resolves, and obviously thanks to @chukWalbourn suggestion I was able to set up the write configuration for blending now it woking perfectly fine here are the change that helped in it

//Describe our Depth/Stencil Buffer
CD3D11_DEPTH_STENCIL_DESC depthStencilStateDesc;

depthStencilStateDesc.DepthEnable = false;
depthStencilStateDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilStateDesc.DepthFunc = D3D11_COMPARISON_LESS;
depthStencilStateDesc.StencilEnable = true;
depthStencilStateDesc.StencilReadMask = 0xFF;
depthStencilStateDesc.StencilWriteMask = 0xFF;
depthStencilStateDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
depthStencilStateDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
depthStencilStateDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilStateDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilStateDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

DX::ThrowIfFailed(
    m_d3dDevice->CreateDepthStencilState(
        &depthStencilStateDesc, 
        &m_d3dDepthStencilState
    )
);

m_d3dContext->OMSetDepthStencilState(m_d3dDepthStencilState.Get(), 1);

Upvotes: 1

Chuck Walbourn
Chuck Walbourn

Reputation: 41127

The DXGI swap-chain alpha mode should be set to DXGI_ALPHA_MODE_IGNORE for UWP or DXGI_ALPHA_MODE_UNSPECIFIED for Win32 when using it as a Direct3D render target. This is only there for some Direct2D / DirectComposition-related scenarios.

For straight-alpha, use:

D3D11_BLEND_DESC blendDesc = {};
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend =
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend =
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp =
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

For premultiplied alpha use:

D3D11_BLEND_DESC blendDesc = {};
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend =
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlend =
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp =
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

For 'additive' blend use:

D3D11_BLEND_DESC blendDesc = {};
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend =
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend =
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].BlendOp =
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

You may want to take a look at DirectX Tool Kit.

Upvotes: 3

Related Questions