notJustCode.it
 
\\ Home : Articoli
Shadow Mapping
Di RobyDx (del 29/07/2007 @ 08:39:33, in DirectX9, linkato 2276 volte)

Il rendering delle ombre è sicuramente uno degli aspetti più complessi da analizzare. In attesa che directX gestisca in maniera automatica questo problema vi propongo un nuovo metodo, alternativo allo stencil: lo shadow mapping.

Il presupposto da cui partire è la definizione di ombra. Un ombra è una schermatura tra tutto quello che si trova tra la luce e l'oggetto. Lo shadow mapping si basa su questo: renderizzare su una texture quello che si trova tra la luce e l'oggetto. L'oggetto ombreggiato semplicemente userà questa texture per creare zone d'ombra.

shadowMap

Una sorgente luminosa (il cerchio arancione) illumina un oggetto (sfera rossa), parzialmente coperto da un secondo oggetto(sfera blu). Attorno alla luce è evidenziata un quadrato che rappresenta la nostra cubemap. Su di essa, centrando la telecamera nell'origine, renderizzeremo gli oggetti utilizzando come colore la distanza tra esso e la luce. Quello che la mappa vedrà in questo esempio saranno le 2 sfere ma il valore di quella blu sarà minore perchè più vicina alla luce. L'oggetto rosso quindi caricherà questa mappa su se stesso posizionando le coordinate texture in modo da andare a prendere la zona verso la luce. Il valore abbiamo detto che rappresenta la distanza: se la distanza tra di lui e la luce è maggiore del valore sulla mappa in quel pixel allora aggiungerà l'ombra su se stesso perchè significa che sulla cubemap c'è un oggetto davanti a lui che ha inserito un valore minore. In questo caso l'oggetto avrà una zona in ombra ed il resto in luce perchè tra di lui e la luce non c'è nulla (valore minore a quello sulla cubemap che avrà sfondo massimo, quindi bianco). Ogni oggetto sulla scena utilizzerà lo stesso algoritmo caricando la shadowmap ed il risultato sarà l'ombreggiatura perfetta della scena.

Il rendering si divide in 2 pass.

Il primo pass renderizzerà sulla cubemap la scena vista dai suoi 6 lati restituendo nel pixel shader la distanza.

Il secondo pass (quello finale) renderizza gli oggetti con questa mappa. Ecco la formula da usare (e da inserire nello shader).

lightDirection=vertexPosition-lightPosition;
distanza=distance(vertexPosition,lightPos);
float shadow=texCUBE(Shadow,normalize(lightDirection));
float ombra=distanza<(shadow);

Tramite lightdirection prendiamo la cubemap verso la direzione della luce e tramite l'operatore < avremo 0 se la distanza + maggiore dell'ombra, 1 altrimenti. Questo valore è ora a disposizione per farci quello che vogliamo.

Caratteristiche delle shadowmapping:

Pro

  • tutto il calcolo è sulla gpu
  • universale, prende in considerazione ogni elemento della scena
  • l'ombra viene proiettata anche sullo stesso oggetto

Contro

  • richiedono il rendering della scena più volte (con shader molto semplice)
  • occorre creare una cubemap per ogni sorgente
  • dipende fortemente dalla qualità della cubemap (dimensione, formato)

L'algoritmo deve essere ulteriormente migliorato. In prossimità dell'oggetto dove la distanza è minima è possibile che ci siano degli artefatti (difetti). Al valore shadow occorre aggiungere una correzione. La distanza per un valore (esempio 0.03) mi sembra una buona approssimazione che fa ottenere una scena più che buona. Un'altra ottimizzazione sta nel fatto che spesso non si devono renderizzare tutte le facce. Se una luce si trova in cima alla scena allora non serve la faccia superiore. Il sistema funziona per la luce puntiforme. Per le luci direzionali è sufficiente una normale texture da orientare verso la scena. Le formule sono leggermente diverse ma non difficili da calcolare. Magari saranno argomento di successivi tutorial. Per risparmiare risorse potete anche calcolare la shadow map non ad ogni frame. Infine se avete ancora un pò di frame liberi potete fare un blur delle mappe per migliorare ancora la scena.

Vi lascio all'esempio:

Esempio VB.Net

Articolo Articolo  Storico Storico Stampa Stampa
I commenti sono disabilitati.
"L'esperienza è quella cosa meravigliosa che permette di riconoscere un errore quando lo si commette di nuovo."

F.P Jones


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 60 persone collegate
Sono state visualizzate  pagine

19/05/2024 @ 02:10:26
script eseguito in 41 ms