Configurazione della funzionalità di fusione

Le operazioni di fusione vengono eseguite su ogni output pixel shader (valore RGBA) prima che il valore di output venga scritto in una destinazione di rendering. Se il multicampionamento è abilitato, la fusione viene eseguita su ogni multisample; in caso contrario, la fusione viene eseguita su ogni pixel.

Creare lo stato blend

Lo stato di fusione è una raccolta di stati utilizzati per controllare la fusione. Questi stati (definiti in D3D11_BLEND_DESC1) vengono usati per creare l'oggetto stato blend chiamando ID3D11Device1::CreateBlendState1.

Ad esempio, ecco un esempio molto semplice di creazione dello stato di fusione che disabilita la fusione alfa e non usa alcuna maschera pixel per componente.

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);

Questo esempio è simile all'esempio HLSLWithoutFX10.

Associare lo stato blend

Dopo aver creato l'oggetto blend-state, associare l'oggetto blend-state alla fase di unione dell'output chiamando ID3D11DeviceContext::OMSetBlendState.

float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
UINT sampleMask   = 0xffffffff;

pd3dDevice->OMSetBlendState(g_pBlendStateNoBlend, blendFactor, sampleMask);

Questa API accetta tre parametri: l'oggetto blend-state, un fattore di fusione a quattro componenti e una maschera di esempio. È possibile passare NULL per l'oggetto stato blend per specificare lo stato di fusione predefinito o passare un oggetto stato blend. Se è stato creato l'oggetto stato di fusione con D3D11_BLEND_BLEND_FACTOR o D3D11_BLEND_INV_BLEND_FACTOR, è possibile passare un fattore di fusione per modulare i valori per il pixel shader, la destinazione di rendering o entrambi. Se non è stato creato l'oggetto stato di fusione con D3D11_BLEND_BLEND_FACTOR o D3D11_BLEND_INV_BLEND_FACTOR, è comunque possibile passare un fattore di fusione non NULL, ma la fase di fusione non usa il fattore di fusione; il runtime archivia il fattore di fusione ed è possibile chiamare in seguito ID3D11DeviceContext::OMGetBlendState per recuperare il fattore di fusione. Se si passa NULL, il runtime usa o archivia un fattore di fusione uguale a { 1, 1, 1, 1 }. La maschera di esempio è una maschera definita dall'utente che determina come campionare la destinazione di rendering esistente prima di aggiornarla. La maschera di campionamento predefinita è 0xffffffff che definisce il campionamento dei punti.

Nella maggior parte degli schemi di buffering di profondità, il pixel più vicino alla fotocamera è quello che viene disegnato. Quando si configura lo stato dello stencil di profondità, il membro DepthFunc di D3D11_DEPTH_STENCIL_DESC può essere qualsiasi D3D11_COMPARISON_FUNC. In genere, si vuole che DepthFunc sia D3D11_COMPARISON_LESS, in modo che i pixel più vicini alla fotocamera sovrascrivano i pixel dietro di essi. Tuttavia, a seconda delle esigenze dell'applicazione, è possibile usare qualsiasi altra funzione di confronto per eseguire il test di profondità.

Argomenti avanzati sulla fusione

Da alfa a copertura

La copertura da alfa a copertura è una tecnica di multicampionamento che è più utile per situazioni come fogliame denso in cui ci sono diversi poligoni sovrapposti che usano la trasparenza alfa per definire i bordi all'interno della superficie.

È possibile usare il membro AlphaToCoverageEnable di D3D11_BLEND_DESC1 o D3D11_BLEND_DESC per attivare o disattivare se il runtime converte il componente .a (alfa) del registro di output SV_Target0 dal pixel shader a una maschera di copertura in un n-step (dato un oggetto RenderTarget n-sample). Il runtime esegue un'operazione AND di questa maschera con la copertura di esempio tipica per il pixel nella primitiva (oltre alla maschera di esempio) per determinare quali campioni aggiornare in tutti i renderTargetattivi.

Se il pixel shader restituisce SV_Coverage, il runtime disabilita la copertura da alfa a copertura.

Nota

Nel multicampionamento, il runtime condivide una sola copertura per tutti gli oggetti RenderTarget. Il fatto che il runtime legge e converte .a dall'output SV_Target0 alla copertura quando AlphaToCoverageEnable è TRUE non modifica il valore .a che passa al frullatore in RenderTarget 0 (se viene impostato un oggetto RenderTarget ). In generale, se si abilita la copertura alfa-a-coverage, non si influisce sul modo in cui tutti gli output di colore dei pixel shader interagiscono con RenderTargettramite la fase di unione dell'output , ad eccezione del fatto che il runtime esegue un'operazione AND della maschera di copertura con la maschera da alfa a copertura. Alfa-a-coverage funziona indipendentemente dal fatto che il runtime possa combinare RenderTarget o se si usa la fusione in RenderTarget.

 

L'hardware grafico non specifica esattamente come converte il pixel shader SV_Target0.a (alfa) in una maschera di copertura, ad eccezione del fatto che alfa di 0 (o meno) deve eseguire il mapping a nessuna copertura e alfa di 1 (o superiore) deve essere mappato alla copertura completa (prima che il runtime esegua un'operazione AND con copertura primitiva effettiva). Poiché alfa va da 0 a 1, la copertura risultante dovrebbe in genere aumentare monotonicamente. Tuttavia, l'hardware potrebbe eseguire il dithering dell'area per fornire una migliore quantizzazione dei valori alfa a costo della risoluzione spaziale e del rumore. Un valore alfa di NaN (Not a Number) restituisce una maschera di copertura (zero).

La copertura da alfa a copertura viene usata tradizionalmente anche per la trasparenza delle porte dello schermo o per definire forme dettagliate per sprite altrimenti opachi.

Blending Pixel Shader Outputs

Questa funzionalità consente all'unione di output di usare contemporaneamente entrambi gli output del pixel shader come origini di input a un'operazione di fusione con la singola destinazione di rendering nello slot 0.

Questo esempio accetta due risultati e li combina in un unico passaggio, fondendone uno nella destinazione con una moltiplicazione e l'altro con un add:

SrcBlend = D3D11_BLEND_ONE;
DestBlend = D3D11_BLEND_SRC1_COLOR;

In questo esempio viene configurato il primo output del pixel shader come colore di origine e il secondo output come fattore di fusione per componente per colore.

SrcBlend = D3D11_BLEND_SRC1_COLOR;
DestBlend = D3D11_BLEND_INV_SRC1_COLOR;

Questo esempio illustra come i fattori di fusione devono corrispondere ai swizzles dello shader:

SrcFactor = D3D11_BLEND_SRC1_ALPHA;
DestFactor = D3D11_BLEND_SRC_COLOR;
OutputWriteMask[0] = .ra; // pseudocode for setting the mask at
                          // RenderTarget slot 0 to .ra

Insieme, i fattori di fusione e il codice shader implicano che il pixel shader è necessario per restituire almeno o0.r e o1.a. I componenti di output aggiuntivi possono essere restituiti dallo shader, ma verrebbero ignorati, un minor numero di componenti produrrebbe risultati non definiti.

Fase di fusione dell'output

Fasi della pipeline (Direct3D 10)