ブレンド機能の構成
ブレンド操作は、出力値がレンダー ターゲットに書き込まれる前に、すべてのピクセル シェーダー出力 (RGBA 値) で実行されます。 マルチサンプリングが有効になっている場合、ブレンドは各マルチサンプリングで行われます。それ以外の場合は、各ピクセルに対してブレンドが実行されます。
ブレンド状態を作成する
ブレンド状態は、ブレンドを制御するために使用される状態のコレクションです。 これらの状態 ( D3D11_BLEND_DESC1で定義) は、 ID3D11Device1::CreateBlendState1 を呼び出してブレンド状態オブジェクトを作成するために使用されます。
たとえば、アルファ ブレンドを無効にし、コンポーネントごとのピクセル マスクを使用しないブレンド状態の作成の非常に簡単な例を次に示します。
ID3D11BlendState1* g_pBlendStateNoBlend = NULL;
D3D11_BLEND_DESC1 BlendState;
ZeroMemory(&BlendState, sizeof(D3D11_BLEND_DESC1));
BlendState.RenderTarget[0].BlendEnable = FALSE;
BlendState.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
pd3dDevice->CreateBlendState1(&BlendState, &g_pBlendStateNoBlend);
この例は HLSLWithoutFX10 サンプルに似ています。
ブレンド状態をバインドする
blend-state オブジェクトを作成した後、 ID3D11DeviceContext::OMSetBlendState を呼び出して、blend-state オブジェクトを出力マージャー ステージにバインドします。
float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
UINT sampleMask = 0xffffffff;
pd3dDevice->OMSetBlendState(g_pBlendStateNoBlend, blendFactor, sampleMask);
この API は、blend-state オブジェクト、4 成分ブレンド係数、サンプル マスクの 3 つのパラメーターを受け取ります。 ブレンド状態オブジェクトに NULL を 渡して、既定のブレンド状態を指定するか、ブレンド状態オブジェクトを渡すことができます。 D3D11_BLEND_BLEND_FACTORまたはD3D11_BLEND_INV_BLEND_FACTORを使用して blend-state オブジェクトを作成した場合は、ブレンド 係数を渡して、ピクセル シェーダー、レンダー ターゲット、またはその両方の値を調整できます。 D3D11_BLEND_BLEND_FACTORまたはD3D11_BLEND_INV_BLEND_FACTORを使用してブレンド状態オブジェクトを作成しなかった場合でも、NULL 以外のブレンド係数を渡すことができますが、ブレンド ステージではブレンド係数は使用されません。ランタイムはブレンド係数を格納し、後で ID3D11DeviceContext::OMGetBlendState を呼び出してブレンド係数を取得できます。 NULL を渡すと、ランタイムは { 1、1、1、1} と等しいブレンド係数を使用または格納します。 サンプル マスクは、既存のレンダー ターゲットを更新する前にサンプリングする方法を決定するユーザー定義マスクです。 既定のサンプリング マスクは、ポイント サンプリングを指定する0xffffffffです。
ほとんどの深度バッファリング スキームでは、カメラに最も近いピクセルが描画されます。 深度ステンシルの状態を設定する場合、D3D11_DEPTH_STENCIL_DESCの DepthFunc メンバーには任意のD3D11_COMPARISON_FUNCを指定できます。 通常、 DepthFunc を D3D11_COMPARISON_LESSして、カメラに最も近いピクセルが背後のピクセルを上書きするようにします。 ただし、アプリケーションのニーズに応じて、他の比較関数のいずれかを使用して深度テストを行うことができます。
高度なブレンド のトピック
Alpha-To-Coverage
アルファ対カバレッジはマルチサンプリング手法であり、アルファ透明度を使用してサーフェス内のエッジを定義する重複するポリゴンが複数存在する高密度の葉などの状況で最も役立ちます。
D3D11_BLEND_DESC1 または D3D11_BLEND_DESC の AlphaToCoverageEnable メンバーを使用して、出力レジスタの .a コンポーネント (アルファ) SV_Target0 をピクセル シェーダーから n ステップ カバレッジ マスクに変換するかどうかを切り替えることができます (n サンプル RenderTarget を指定)。 ランタイムは、プリミティブ内のピクセルの一般的なサンプル カバレッジ (サンプル マスクに加えて) を使用して、このマスクの AND 演算を実行して、アクティブなすべての RenderTargetで更新するサンプルを決定します。
ピクセル シェーダーが SV_Coverage出力する場合、ランタイムはアルファからカバレッジを無効にします。
注意
マルチサンプリングでは、ランタイムはすべての RenderTargetに対して 1 つのカバレッジのみを共有します。 AlphaToCoverageEnable が TRUE の場合、ランタイムが出力 SV_Target0 からカバレッジに .a を読み取って変換しても、RenderTarget 0 のブレンダーに移動する .a 値は変更されません (RenderTarget が設定されている場合)。 一般に、アルファ対カバレッジを有効にした場合、ピクセル シェーダーからのすべてのカラー出力が出力マージャー ステージを通じて RenderTargetと対話する方法には影響しません。ただし、ランタイムがアルファ対カバレッジ マスクを使用してカバレッジ マスクの AND 操作を実行する点が異なります。 アルファカバレッジは、ランタイムが RenderTarget をブレンドできるかどうか、または RenderTarget でブレンドを使用するかどうかに関係なく機能します。
グラフィックス ハードウェアでは、ピクセル シェーダー SV_Target0.a (アルファ) をカバレッジ マスクに変換する方法を正確に指定しません。ただし、アルファ 0 (またはそれ以下) はカバレッジなしにマップする必要があり、アルファ 1 (以上) はフル カバレッジにマップする必要があります (ランタイムが実際のプリミティブ カバレッジで AND 操作を実行する前)。 アルファが 0 から 1 になるにつれて、結果のカバレッジは一般に単調に増加する必要があります。 ただし、ハードウェアは領域ディザリングを実行して、空間解像度とノイズを犠牲にしてアルファ値の量子化を向上させる場合があります。 アルファ値が NaN (数値ではない) の場合、カバレッジなし (ゼロ) マスクになります。
アルファ対カバレッジは、従来、スクリーンドアの透明度や、不透明なスプライトの詳細なシルエットの定義にも使用されています。
ピクセル シェーダー出力のブレンド
この機能により、出力マージでは、スロット 0 の単一レンダー ターゲットを使用したブレンド操作への入力ソースとして、両方のピクセル シェーダー出力を同時に使用できます。
この例では、2 つの結果を受け取り、それらを 1 つのパスで結合し、1 つを乗算と加算で変換先にブレンドします。
SrcBlend = D3D11_BLEND_ONE;
DestBlend = D3D11_BLEND_SRC1_COLOR;
次の使用例は、最初のピクセル シェーダー出力をソース カラーとして構成し、2 番目の出力を色ごとのコンポーネント ブレンド係数として構成します。
SrcBlend = D3D11_BLEND_SRC1_COLOR;
DestBlend = D3D11_BLEND_INV_SRC1_COLOR;
次の例は、ブレンド係数がシェーダー スウィズルと一致する必要がある方法を示しています。
SrcFactor = D3D11_BLEND_SRC1_ALPHA;
DestFactor = D3D11_BLEND_SRC_COLOR;
OutputWriteMask[0] = .ra; // pseudocode for setting the mask at
// RenderTarget slot 0 to .ra
ブレンド 係数とシェーダー コードは、少なくとも o0.r と o1.a を出力するためにピクセル シェーダーが必要であることを意味します。 追加の出力コンポーネントはシェーダーによって出力できますが、無視され、未定義の結果が生成されるコンポーネントが少なくなります。
関連トピック