notJustCode.it
 
\\ Home : Articoli
Depth Stencil Buffer
Di robydx (del 16/09/2007 @ 15:23:07, in Direct3D10, linkato 6537 volte)

Il Depth buffer è la superficie addetta alla gestione della profondità. Ogni pixel che sta per essere disegnato a video confronta la sua profondità restituisce un colore ed una profondità. Questo valore viene confrontato con il depth buffer, se minore sostituisce il valore e scrive il colore del pixel sul back buffer.

Normalmente il valore di distanza massima è 1 e passano questo controllo (chiamato depth test) solo i pixel con profondità minore (ricordo che la profondità è letta dopo che è stata applicata la projection matrix che la porta ad essere compresa tra 0 ed 1). In DirectX si può comunque variare questa regola ed utilizzare confronti diversi (ad esempio si può usare un uguaglianza in modo che il rendering successivo vada a video solo per distanze uguali a quelle già sullo schermo, utili per la tecnica chiamata ZOnly).

Il depth buffer però è utilizzato anche per altri scopi. Durante l’inizializzazione del depth buffer viene indicato il formato di precisione ed accanto a formati come D16 e D32 (ossia 16 e 32 bit di precisione) ne compaiono altri come D24S8. Questo formato ad esempio indica che 8 bit saranno dedicati allo stencil buffer.

Lo stencil buffer è, come il depth buffer, una superficie di controllo che impedisce a certi pixel di essere mandati a video ma a differenza di questo, lo stencil non utilizza la profondità come confronto ma delle regole che noi andremo a definire.

Facciamo un esempio.

Vogliamo creare un effetto in cui al centro della scena compare un cerchio contenente il livello successivo del nostro ipotetico gioco che va a sostituire quello precedente. Quello che noi vorremmo è che la prima scena sia renderizzata fuori da questo cerchio, l’altra all’interno.

Tramite lo stencil noi faremo questo: renderizzeremo un cerchio (o qualsiasi figura desideriate) ordinando di valorizzare ad 1 lo stencil buffer nella zona in cui i pixel sono stati tracciati; successivamente manderemo a video le due scene escludendo in una i pixel che compaiono dove lo stencil è uguale ad 1, nell’altra quella in cui i pixel sono diversi da 1.

Questo effetto è chiamato maschera.

Lo stencil si utilizza per molti effetti altri effetti tra cui ombre, fumo e luci volumetriche.

Le possibilità dello stencil sono molte e si basano su semplici regole.

Ogni volta che un pixel arriva al pixel shader viene confrontata la sua distanza con quella dei pixel già tracciati a video. Se il pixel è più vicino viene mandato a video allora significa che ha superato il depth test, altrimenti che ha fallito. Il caso di fallimento viene chiamato depthFail. Se il pixel supera il depth test allora viene confrontato con la funzione di stencil. Questa funzione confronta il valore dello stencil sul buffer con uno a nostro piacimento che impostiamo prima del rendering e che chiamiamo StencilRef. I tipi di confronti sono gli stessi del depth test (quindi maggiore, minore, uguale, etc). A questo punto si procede all’aggiornamento.

Sono 3 i casi

  1. Lo stencil test viene superato
  2. Lo stencil test fallisce
  3. Lo stencil test viene superato ma fallisce il depth stencil

Per ognuno può essere applicata una regola indipendente. Ad esempio si può decidere che se il test passa si incrementi il valore dello stencil e che si decrementi quando fallisce. Il valore per cui si incrementerà sarà quello di stencilRef. Quindi se noi impostiamo come operazione “sostituisci”, lo stencil assumerà il valore dello stencilRef in quel punto, così come incrementerà di stencilRef con operazione “aumenta”. In directX9 e 10 lo stencil può essere gestito indipendentemente sia per le superfici con cull diretto (che guardano verso di noi) che con cull invertito.

Ulteriore libertà è data dall’utilizzo di maschere bit a bit per modificare i valori letti e scritti.

Una maschera bit a bit è un modo per prendere solo un certo gruppo di bit da un numero. Facciamo un esempio. Il numero 11 in binario vale 1011 ma noi vogliamo utilizzare come confronto solo il primo e l’ultimo valore. Moltiplichiamo il valore per 0001

1001 x 0001 = 0001

Se fosse stato 8 sarebbe stato 1000 x 0001 = 0000. Questo è un semplice metodo per sapere se il numero è pari o disparo. I flags che vedete spesso in directX si basano sullo stesso principio

Esempio 2 flags di valori 4 e 8 ossia 100 e 1000. Se si fa l’OR (che equivale al più) otteniamo 1100. Per sapere se quel valore contiene il flags 4 basta fare 1100 x 0100 = 100 ossia il flags 4. Ovviamente il trucco funziona solo per potenze di 2.

Lo stesso trucco lo potete usare con lo stencil. Ci sono come per il rasterizer ed il blending 2 metodi per impostare le proprietà depth e stencil: da shader e da codice.

Da codice si utilizza la funzione CreateDepthStencilState del device per creare una classe di tipo ID3D10DepthStencilState. La funzione prende in input una struttura di tipo D3D10_DEPTH_STENCIL_DESC che contiene quanto descritto finora.

DepthEnable : attiva il depth test (con false non c’è la gestione della profondità)

DepthWriteMask : la maschera bit a bit per la profondità, di default a D3D10_DEPTH_WRITE_MASK ossia tutti i bit sono usati

DepthFunc : tipo di confronto, di default less. Utilizza l’enum D3D10_COMPARISON_FUNC

StencilEnable : con true attiva lo stencil

StencilReadMask : maschera usata in lettura

StencilWriteMask : maschera usata in scrittura

Ci sono all’interno della struttura altre due strutture di tipo D3D10_DEPTH_STENCILOP_DESC chiamate frontFace e backFace per descrivere il comportamento dello stencil per i due tipi di cull. Queste contengono

StencilFailOp : operazione in caso fallisca lo stencil test

StencilDepthFailOp : operazione in caso fallisca il depth test ma abbia successo lo stencil test

StencilPassOp : operazione in caso abbia successo lo stencil test

StencilFunc : funzione di confronto di tipo D3D10_COMPARISON_FUNC

Le funzioni di comparazioni sono le seguenti

D3D10_COMPARISON_NEVER

D3D10_COMPARISON_LESS

D3D10_COMPARISON_EQUAL

D3D10_COMPARISON_LESS_EQUAL

D3D10_COMPARISON_GREATER

D3D10_COMPARISON_NOT_EQUAL

D3D10_COMPARISON_GREATER_EQUAL

D3D10_COMPARISON_ALWAYS

Quelle di modifica dello stencil

D3D10_STENCIL_OP_KEEP : mantiene il valore

D3D10_STENCIL_OP_ZERO : lo porta a zero

D3D10_STENCIL_OP_REPLACE : lo sostituisce con il valore stencilRef

D3D10_STENCIL_OP_INCR_SAT : incrementa di stencilRef ma non supera il massimo

D3D10_STENCIL_OP_DECR_SAT : decrementa di stencilRef ma non scende mai sotto a zero

D3D10_STENCIL_OP_INVERT : inverte il valore

D3D10_STENCIL_OP_INCR : incrementa di stencilRef. Nel caso superi il massimo ritorna a zero

D3D10_STENCIL_OP_DECR : decrementa di stencilRef. Nel caso scenda sotto lo zero viene impostato al Massimo valore possible.

Il valore stencilRef viene passato al device quando si imposta lo stencil tramite l’istruzione OMSetDepthStencilState.

Da shader si utilizza la struttura DepthStencilState contenente

DEPTHENABLE

DEPTHWRITEMASK

DEPTHFUNC

STENCILENABLE

STENCILREADMASK

STENCILWRITEMASK

FRONTFACESTENCILFAIL

FRONTFACESTENCILZFAIL

FRONTFACESTENCILPASS

FRONTFACESTENCILFUNC

BACKFACESTENCILFAIL

BACKFACESTENCILZFAIL

BACKFACESTENCILPASS

BACKFACESTENCILFUNC

La vedete sempre nei miei esempi per impostare correttamente il depth test. I valori sono gli stessi della struttura da codice C++ eliminando le desinenze (esempio D3D10_COMP_NEVER diventa NEVER).

Vi lascio al mio demo che mostra tramite stencil il numero di pixel renderizzati in ogni punto. Questo si ottiene incrementando lo stencil per ogni pixel che va a video. Successivamente renderizziamo piani con colori diversi a seconda di quale valore vogliamo vedere ed impostiamo lo stencil in modo che passi il test solo quando il valore di stencil è quello che vogliamo.

 

Demo

Articolo Articolo  Storico Storico Stampa Stampa
I commenti sono disabilitati.
"Un gioco posticipato potrebbe essere alla fine un buon gioco, un cattivo gioco è cattivo per sempre. "

Shigeru Miyamoto


Cerca per parola chiave
 

Titolo
Articoli (4)
C++ (4)
Direct3D10 (30)
Direct3D11 (20)
DirectX9 (82)
DotNet (10)
English (9)
FanGames (22)
ManagedDX11 (2)
Materiale Utile (4)
News (39)
Shader Library (12)
SharpDX (1)
Software (25)
Tecnologia (19)
Varie (9)

Gli interventi più cliccati

Ultimi commenti:
If you wish to retai...
23/05/2013 @ 13:07:45
Di chanel outlet
You deficit of self-...
23/05/2013 @ 13:07:13
Di cartier watches uk
Reinforce your own l...
23/05/2013 @ 13:06:37
Di replica watches
Whenever you"re shiv...
23/05/2013 @ 13:06:11
Di swiss replica watches
It's likely you have...
23/05/2013 @ 13:05:02
Di chanel handbags
Cheap automobile ins...
23/05/2013 @ 13:04:28
Di replica watches

Titolo
Con quale tecnologia state realizzando o avete intenzione di realizzare i vostri progetti?

 DirectX11
 DirectX10
 DirectX9
 XNA
 DirectX8 o Precedenti
 OpenGL
 Motori grafici già pronti
 Altro

Titolo
Umorismo (17)

Le fotografie più cliccate



Ci sono 10 persone collegate
Sono state visualizzate  pagine

18/10/2021 @ 14:51:51
script eseguito in 47 ms