\\ Home : Articoli : Stampa
Alphablending
Di robydx (del 28/05/2007 @ 20:54:54, in Direct3D10, linkato 1914 volte)

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 ID3D10BlendState.

D3D10_BLEND_DESC blendDescription;

Questa struttura descrive l'impostazione del blending. I suoi parametri sono

  • AlphaToCoverageEnable: attiva l'alpha coverage, una nuova features di DirectX10. In pratica permette di evitare il problema dell'ordinamento, utile ad esempio per sistemi dove ci sono molti oggetti ed è impossibile ordinarli. Richiede il multisampling (impostazione antialiasing)
  • 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

  • D3D10_BLEND_ZERO : il valore è (0,0,0,0)
  • D3D10_BLEND_ONE : il valore è (1,1,1,1)
  • D3D10_BLEND_SRC_COLOR : il valore è il colore RGB del nuovo pixel
  • D3D10_BLEND_INV_SRC_COLOR :il valore è il colore RGB del nuovo pixel ma invertito (1-RGB)
  • D3D10_BLEND_SRC_ALPHA : il valore è l'alpha del colore del nuovo pixel
  • D3D10_BLEND_INV_SRC_ALPHA: il valore è l'alpha del colore del nuovo pixel ma invertito
  • D3D10_BLEND_DEST_ALPHA : il valore è l'alpha del colore del pixel sullo schermo
  • D3D10_BLEND_INV_DEST_ALPHA : il valore è l'alpha del colore del pixel sul backbuffer ma invertito
  • D3D10_BLEND_DEST_COLOR : il valore è il colore RGB del pixel sul backbuffer
  • D3D10_BLEND_INV_DEST_COLOR :il valore è il colore RGB del pixel sul backbuffer ma invertito
  • D3D10_BLEND_SRC_ALPHA_SAT : come source alpha ma il valore viene limitato tra 0 ed 1
  • D3D10_BLEND_BLEND_FACTOR : utilizza il valore passato al device durante l'inserimento dei settaggi
  • D3D10_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

  • D3D10_BLEND_SRC1_COLOR
  • D3D10_BLEND_INV_SRC1_COLOR
  • D3D10_BLEND_SRC1_ALPHA
  • D3D10_BLEND_INV_SRC1_ALPHA

Le operazioni utilizzabili sono invece

  • D3D10_BLEND_OP_ADD = utilizza l'operatore di somma (Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor)
  • D3D10_BLEND_OP_SUBTRACT = sottrae il secondo dal primo  (Final Color = ObjectColor * SourceBlendFactor - PixelColor * DestinationBlendFactor)
  • D3D10_BLEND_OP_REV_SUBTRACT = sottrae il primo dal secondo (Final Color = - ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor)
  • D3D10_BLEND_OP_MIN = restituisce il minimo tra le due parti Final Color = min(ObjectColor * SourceBlendFactor , PixelColor * DestinationBlendFactor)
  • D3D10_BLEND_OP_MAX = restituisce il massimo tra le due parti Final Color = min(ObjectColor * SourceBlendFactor , PixelColor * DestinationBlendFactor)

Infine per il writemask si usano i seguenti enum

  • D3D10_COLOR_WRITE_ENABLE_RED : solo rosso
  • D3D10_COLOR_WRITE_ENABLE_GREEN :solo verde
  • D3D10_COLOR_WRITE_ENABLE_BLUE : solo blu
  • D3D10_COLOR_WRITE_ENABLE_ALPHA :solo il canale alpha
  • D3D10_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

ID3D10BlendState* state;

HRESULT hr= device->->CreateBlendState(&blendDescription,&state);

se hr è uguale ad S_OK il blend state è creato

device->OMSetBlendState(state,factor,sampleMask);

  • factor è un array di valori utilizzati quando si imposta blend_factor
  • sampleMask è un intero utilizzato per creare una maschera binaria

 

In HLSL vi basterà dichiarare una struttura BlendState e valorizzarla

 

BlendState SampleBlending
{
    AlphaToCoverageEnable = FALSE;
    BlendEnable[0] = TRUE;
    SrcBlend = SRC_ALPHA;
    DestBlend = ONE;
    BlendOp = ADD;
    SrcBlendAlpha = ZERO;
    DestBlendAlpha = ZERO;
    BlendOpAlpha = ADD;
    RenderTargetWriteMask[0] = 0x0F;
};

ed impostare nel pass il blend state

SetBlendState( SampleBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );

 

Vi lascio al demo

Demo