Normalmente ogni volta che DirectX effettua un rendering, aggiorna i pixel del backbuffer con quelli del nuovo oggetto. L'alphablending è una caratteristica di DirectX che permette invece di effettuare un' operazione di confronto tra il pixel che si sta per mandare a video e quello già presente sullo schermo. In questo modo si possono creare ad esempio effetti di trasparenza impostando l'alphablending in modo che l'oggetto che si sta renderizzando sia una media tra lo sfondo e l'oggetto.
Il colore finale dei pixel dell'oggetto che si sta renderizzando rispettano questa formula
Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor
Dove ObjectColor è il colore dell'oggetto, PixelColor quello del backbuffer in quel punto (quindi ciò che è già stato renderizzato) mentre SourceBlendFactor e DestinationBlendFactor sono le impostazioni dell'alphablending.
Una cosa molto importante da considerare in questo processo è che è il nuovo pixel a compararsi con i vecchi, non il contrario. Questo implica che viene renderizzato un vetro trasparente e poi un oggetto dietro di esso, l'oggetto non subirà blending, ed anzi non comparirà perchè nascosto dal vetro. Questo perchè per lo ZBuffer è un oggetto dietro ad un altro oggetto, quindi da non visualizzare. Gli oggetti che volete sottoporre ad effetti di trasparenza dovranno quindi essere ordinati dal più lontano al più vicino.
L'alphablending funziona come il rastering, quindi potete usarlo sia da HLSL che tramite la classe ID3D11BlendState.
D3D11_BLEND_DESC blendDescription;
Questa struttura descrive l'impostazione del blending. I suoi parametri sono
- AlphaToCoverageEnable: attiva l'alpha coverage, una features introdotta in Direct3D10.
- IndependentBlendEnable: se impostata a true ogni render target avrà un suo settaggio
- RenderTarget: un array di 8 D3D11_RENDER_TARGET_BLEND_DESC. Se IndipendentBlendEnable è impostata a false solo il primo verrà utilizzzato.
La struttura D3D11_RENDER_TARGET_BLEND_DESC contiene i seguenti campi
- BlendEnable: attiva e disattiva il blending. Questo elemento è un array di 8 booleani, questo perchè in DirectX esiste la possibilità di fare il rendering su più 8 superfici differenti (multiple render target). Questo sarà oggetto di futuri tutorial
- SrcBlend: imposta il comportamento del source blend factor. Le opzioni sono quelle definite nell'enum Blend
- DestBlend: imposta il comportamento del destination blend factor. Le opzioni sono quelle definite nell'enum Blend
- BlendOp: imposta l'operazione da eseguire. Oltre alla somma esistono anche altre possibilità di calcolo nella formula.
- SrcBlendAlpha: source e destination blend stabiliscono il comportamento dei canali RGB. Questo invece è quello usato per il canale alpha
- DestBlendAlpha: source e destination blend stabiliscono il comportamento dei canali RGB. Questo invece è quello usato per il canale alpha
- BlendOpAlpha: specifica l'operazione sul canale alpha
- RenderTargetWriteMask: array che specifica quali colori saranno renderizzati su ognuno degli 8 target.
Per i blend factor i valori impostabili sono i seguenti
- D3D11_BLEND_ZERO : il valore è (0,0,0,0)
- D3D11_BLEND_ONE : il valore è (1,1,1,1)
- D3D11_BLEND_SRC_COLOR : il valore è il colore RGB del nuovo pixel
- D3D11_BLEND_INV_SRC_COLOR :il valore è il colore RGB del nuovo pixel ma invertito (1-RGB)
- D3D11_BLEND_SRC_ALPHA : il valore è l'alpha del colore del nuovo pixel
- D3D11_BLEND_INV_SRC_ALPHA: il valore è l'alpha del colore del nuovo pixel ma invertito
- D3D11_BLEND_DEST_ALPHA : il valore è l'alpha del colore del pixel sullo schermo
- D3D11_BLEND_INV_DEST_ALPHA : il valore è l'alpha del colore del pixel sul backbuffer ma invertito
- D3D11_BLEND_DEST_COLOR : il valore è il colore RGB del pixel sul backbuffer
- D3D11_BLEND_INV_DEST_COLOR :il valore è il colore RGB del pixel sul backbuffer ma invertito
- D3D11_BLEND_SRC_ALPHA_SAT : come source alpha ma il valore viene limitato tra 0 ed 1
- D3D11_BLEND_BLEND_FACTOR : utilizza il valore passato al device durante l'inserimento dei settaggi
- D3D11_BLEND_INV_BLEND_FACTOR : utilizza il valore passato al device durante l'inserimento dei settaggi ma invertito
Queste ultime 4 operazioni sono utilizzate per la nuova features di directX10, il dual color blending. In pratica è possibile utilizzare 2 target contemporaneamente e fare il blend tra di loro
- D3D11_BLEND_SRC1_COLOR
- D3D11_BLEND_INV_SRC1_COLOR
- D3D11_BLEND_SRC1_ALPHA
- D3D11_BLEND_INV_SRC1_ALPHA
Le operazioni utilizzabili sono invece
- D3D11_BLEND_OP_ADD = utilizza l'operatore di somma (Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor)
- D3D11_BLEND_OP_SUBTRACT = sottrae il secondo dal primo (Final Color = ObjectColor * SourceBlendFactor - PixelColor * DestinationBlendFactor)
- D3D11_BLEND_OP_REV_SUBTRACT = sottrae il primo dal secondo (Final Color = - ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor)
- D3D11_BLEND_OP_MIN = restituisce il minimo tra le due parti Final Color = min(ObjectColor * SourceBlendFactor , PixelColor * DestinationBlendFactor)
- D3D11_BLEND_OP_MAX = restituisce il massimo tra le due parti Final Color = max(ObjectColor * SourceBlendFactor , PixelColor * DestinationBlendFactor)
Infine per il writemask si usano i seguenti enum
- D3D11_COLOR_WRITE_ENABLE_RED : solo rosso
- D3D11_COLOR_WRITE_ENABLE_GREEN :solo verde
- D3D11_COLOR_WRITE_ENABLE_BLUE : solo blu
- D3D11_COLOR_WRITE_ENABLE_ALPHA :solo il canale alpha
- D3D11_COLOR_WRITE_ENABLE_ALL : tutti e 4 i componenti
Questi possono essere combinati con l'OR logico per selezionare più opzioni contemporaneamente.
Per creare il blendstate
ID3D11BlendState* state;
HRESULT hr= device->->CreateBlendState(&blendDescription,&state);
se hr è uguale ad S_OK il blend state è creato
deviceContext->OMSetBlendState(state,factor,sampleMask);
- factor è un array di valori utilizzati quando si imposta blend_factor
- sampleMask è un intero utilizzato per creare una maschera binaria