設定混合功能

混合作業會在將輸出值寫入轉譯目標之前,在每個圖元著色器輸出上執行 (RGBA 值) 。 如果已啟用多重取樣,則會在每個多重取樣上完成混合;否則,會在每個圖元上執行混合。

建立 Blend 狀態

混合狀態是用來控制混合的狀態集合。 這些狀態 (定義于 D3D11_BLEND_DESC1) ,可用來呼叫 ID3D11Device1::CreateBlendState1來建立混合狀態物件。

例如,以下是一個非常簡單的混合狀態建立範例,可停用 Alpha 混合,且不會使用個別元件的圖元遮罩。

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 狀態

建立 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 物件、四個元件混合因數和範例遮罩。 您可以傳遞混合狀態物件的 Null ,以指定預設混合狀態或傳入 blend-state 物件。 如果您使用 D3D11_BLEND_BLEND_FACTORD3D11_BLEND_INV_BLEND_FACTOR建立混合狀態物件,您可以傳遞混合因數來調整圖元著色器、轉譯目標或兩者的值。 如果您未使用 D3D11_BLEND_BLEND_FACTORD3D11_BLEND_INV_BLEND_FACTOR建立混合狀態物件,您仍然可以傳遞非 Null 混合因數,但混合階段不會使用混合因數;執行時間會儲存混合因數,您稍後可以呼叫 ID3D11DeviceCoNtext::OMGetBlendState 來擷取混合因數。 如果您傳遞 Null,執行時間會使用或儲存等於 { 1, 1, 1, 1 } 的混合因數。 範例遮罩是使用者定義的遮罩,可決定如何在更新現有轉譯目標之前取樣現有轉譯目標。 預設取樣遮罩0xffffffff指定點取樣。

在最深入的緩衝配置中,最接近相機的圖元是繪製的圖元。 設定深度樣板狀態時,D3D11_DEPTH_STENCIL_DESCDepthFunc成員可以是任何D3D11_COMPARISON_FUNC。 一般而言,您會想要 讓 DepthFuncD3D11_COMPARISON_LESS,讓最接近相機的圖元覆寫它們背後的圖元。 不過,視應用程式的需求而定,任何其他比較函式都可以用來進行深度測試。

進階混合主題

Alpha 到涵蓋範圍

Alpha 到涵蓋範圍是一種多重取樣技術,最適用于密集的葉子,其中有幾個重迭多邊形使用 Alpha 透明度來定義表面內的邊緣。

您可以使用D3D11_BLEND_DESC1D3D11_BLEND_DESCAlphaToCoverageEnable成員,將執行時間是否將 .a 元件 (Alpha) SV_Target從圖元著色器轉換成 n 步驟涵蓋範圍遮罩, (指定 n 個範例RenderTarget) 。 執行時間會執行此遮罩的 AND 作業,除了範例遮罩) 之外,還會針對基本 (中的圖元執行 AND 作業,以判斷所有作用中 RenderTargets 中要更新的樣本。

如果圖元著色器輸出 SV_Coverage,執行時間會停用 Alpha 到涵蓋範圍。

注意

在多重取樣中,執行時間只會共用所有 RenderTargets 的一個涵蓋範圍。 當AlphaToCoverageEnable為 TRUE 時,執行時間會讀取並將 .a 從輸出SV_Target轉換成涵蓋範圍的事實,不會變更在RenderTarget 0 的混合器 (如果RenderTarget發生設定) 值。 一般而言,如果您啟用 Alpha 到涵蓋範圍,則不會影響圖元著色器的所有色彩輸出如何透過輸出合併階段RenderTarget互動,不同之處在于執行時間會使用 Alpha 到涵蓋範圍遮罩執行涵蓋範圍遮罩的AND作業。 Alpha 到涵蓋範圍可獨立運作,不論執行時間是否可以混合 RenderTarget ,還是您在 RenderTarget上使用混合。

 

圖形硬體不會精確地指定將圖元 著色器SV_Target0.a (Alpha) 轉換為涵蓋範圍遮罩的方式,不同之處在于,0 (或更少) 的 Alpha 必須對應至沒有涵蓋範圍,且 1 個 () 或更新版本的 Alpha 必須對應至完整涵蓋範圍 (,執行時間才能執行具有實際基本涵蓋範圍) 的 AND 作業。 當 Alpha 從 0 到 1 時,產生的涵蓋範圍通常應該以單調方式增加。 不過,硬體可能會執列區域分割,以提供一些較佳的 Alpha 值量化,代價是空間解析度和雜訊。 NaN (非數位) 的 Alpha 值會導致沒有涵蓋範圍 (零) 遮罩。

Alpha 到涵蓋範圍傳統上也用於螢幕門透明度,或定義不透明 Sprite 的詳細擷取。

混合圖元著色器輸出

這項功能可讓輸出合併同時使用圖元著色器輸出做為輸入來源,並搭配位置 0 的單一轉譯目標進行混合作業。

此範例會採用兩個結果,並將它們結合在單一階段,並將其中一個混合至目的地與乘法,另一個結果則搭配加法:

SrcBlend = D3D11_BLEND_ONE;
DestBlend = D3D11_BLEND_SRC1_COLOR;

本範例會將第一個圖元著色器輸出設定為來源色彩,並將第二個輸出設定為每一色彩元件混合因數。

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 所需的圖元著色器。 著色器可以輸出額外的輸出元件,但會忽略,較少的元件會產生未定義的結果。

輸出合併階段

管線階段 (Direct3D 10)