Output Merger (OM)
Overview
The Output Merger (OM) stage is the final stage of the Direct3D 11 graphics pipeline. It combines pixel shader output with existing data in the render target(s) and depth‑stencil buffer according to blend, depth, and stencil operations.
Pipeline Stage
The OM stage receives:
- Pixel color data from the pixel shader.
- Optional per‑pixel depth information.
- Current contents of bound render targets and depth‑stencil view.
Key Functions & Structures
// Creating a blend state
D3D11_BLEND_DESC blendDesc = {};
blendDesc.AlphaToCoverageEnable = FALSE;
blendDesc.IndependentBlendEnable = FALSE;
blendDesc.RenderTarget[0].BlendEnable = TRUE;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
ID3D11BlendState* pBlendState = nullptr;
device->CreateBlendState(&blendDesc, &pBlendState);
context->OMSetBlendState(pBlendState, nullptr, 0xffffffff);
// Creating a depth‑stencil state
D3D11_DEPTH_STENCIL_DESC dsDesc = {};
dsDesc.DepthEnable = TRUE;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
dsDesc.StencilEnable = FALSE;
ID3D11DepthStencilState* pDSState = nullptr;
device->CreateDepthStencilState(&dsDesc, &pDSState);
context->OMSetDepthStencilState(pDSState, 0);
For a full reference, see the DirectX API reference.
Typical Usage Pattern
- Configure and bind render target views and a depth‑stencil view using
OMSetRenderTargets
. - Create and bind a blend state object with
OMSetBlendState
. - Create and bind a depth‑stencil state object with
OMSetDepthStencilState
. - Issue draw calls; the OM stage automatically performs blending, depth testing, and stencil testing.
Sample Code
// Simple rendering loop demonstrating OM setup
while (running)
{
// Clear render target and depth buffer
const float clearColor[4] = {0.1f, 0.1f, 0.1f, 1.0f};
context->ClearRenderTargetView(rtView, clearColor);
context->ClearDepthStencilView(dsView, D3D11_CLEAR_DEPTH, 1.0f, 0);
// Set pipeline state
context->IASetInputLayout(inputLayout);
context->VSSetShader(vertexShader, nullptr, 0);
context->PSSetShader(pixelShader, nullptr, 0);
// Bind OM state (render targets already bound earlier)
context->OMSetBlendState(pBlendState, nullptr, 0xffffffff);
context->OMSetDepthStencilState(pDSState, 0);
// Draw call
context->DrawIndexed(indexCount, 0, 0);
// Present
swapChain->Present(1, 0);
}