notJustCode.it
 
\\ Home : Articoli
Cell Shading
Di RobyDx (del 16/08/2007 @ 12:58:40, in Direct3D10, linkato 3363 volte)

Detto anche Toon Mapping è una tecnica di rendering per simulare il disegno dei cartoni animati, caratterizzato dall'utilizzo di ombre nette e di contorni.

Il Cell shading è un algoritmo che si compone di due fasi

  1. Il cell shading vero e proprio, ossia il rendering della scena con ombre nette
  2. L'outline rendering, ossia il rendering dei contorni

Il secondo passaggio può essere saltato se non si vogliono usare i contorni (un esempio è Legend Of Zelda the Wind Waker che usa il Cell Shading senza contorni).

Il primo passaggio è un normale rendering multi pass (ossia in cui gli oggetti vengono renderizzati sul target ad uno ad uno). Per il toon mapping si possono utilizzare tutte le forme di illuminazione che vogliamo. Cambia però quello che mandiamo a video. Nel phong ad esempio otteniamo il valore di Diffuse con il DotProduct tra direzione della luce e normale, un valore che varia tra -1 e +1. Portandolo come valore tra 0 ed 1 (scartando quindi i valori negativi), possiamo usare il valore come coordinata per una texture come questa sotto. Più alto è il valore di diffuse e più a destra prenderemo il colore. Come potete subito capire il colore varierà in base al colore della texture.

Questa è un ingrandimento, basta anche una piccola texture 8x1. Il numero di bande e la loro gradazione è da scegliere in base alle proprie preferenze. Stesso sistema potete usare per lo specular (io ho utilizzato una texture con nero e bianco per lo specular).

Il secondo step richiede invece un post processing tramite un filtro di tipo Sobel.

I filtri sono degli algoritmi che permettono di ottenere delle trasformazioni dell'immagine. Il filtro sobel è un algoritmo che permette di tracciare linee nere dove c'è una forte differenza di colori.

Utilizzando 2 texture come render target mandiamo nella prima il rendering del cell shading, nel secondo invece mandiamo le normali in RGB e la distanza dalla telecamera in alpha. Un punto dove tracciare una linea nera è dove un corpo ha degli spigoli ed uno spigolo è proprio un punto in cui le normali cambiano direzione rapidamente. L'altro punto è invece quello in cui c'è differenza di profondità e per quello si usa la distanza (il contorno comparirà dove c'è una forte differenza di distanza). Con il filtro sobel applicato alla media delle normali e alla profondità otterremo i contorni corretti. Questo è l'algoritmo Sobel

 

float d=1.0f/1024.0f;
float4 aa=depthTarget.Sample(textureSampler2,float2(input.tex.x-d,input.tex.y-d));
float4 bb=depthTarget.Sample(textureSampler2,float2(input.tex.x,input.tex.y-d));
float4 cc=depthTarget.Sample(textureSampler2,float2(input.tex.x+d,input.tex.y-d));
float4 dd=depthTarget.Sample(textureSampler2,float2(input.tex.x-d,input.tex.y));
float4 ee=depthTarget.Sample(textureSampler2,float2(input.tex.x+d,input.tex.y));
float4 ff=depthTarget.Sample(textureSampler2,float2(input.tex.x-d,input.tex.y+d));
float4 gg=depthTarget.Sample(textureSampler2,float2(input.tex.x,input.tex.y+d));
float4 hh=depthTarget.Sample(textureSampler2,float2(input.tex.x+d,input.tex.y+d));
float4 delX;
float4 delY;
delX = ((cc + (2 * ee) + hh) - (aa + (2 * dd) + ff));
delY = ((ff + (2 * gg) + hh) - (aa + (2 * bb) + cc));
float4 var = abs(delX) + abs(delY);

Questo è l'algoritmo di sobel usato. Si legge la texture negli 8 punti intorno a lui, quindi si usa la formula per calcolare la differenza ed in var si ottiene un valore che indica quanto varia. Usando ad esempio

float C= var.x<0.4F;

La variabile C varrà 0 dove c'è una differenza minore del valore 0.4 scelto, 1 altrimenti (quindi bianco e nero). Nel nostro caso useremo la media di XYZ per i contorni basati su normale, W per quelli basati sulla distanza. Variando il parametro di confronto potremo correggere il contorno.

Ultime note sul demo, il post processing. Per ottenerlo ho renderizzato un quadrato di spigoli -1,-1,0 e 1,1,0. Se mandato in output dal vertex shader senza trasformarlo per una matrice coprirà perfettamente lo schermo. Su di esso useremo le texture uscite dal primo rendering su texture.

Si può migliorare ulteriormente l'algoritmo applicando un filtro blur al contorno in modo da renderlo più morbido.

Vi lascio al demo

Demo

Articolo Articolo  Storico Storico Stampa Stampa
I commenti sono disabilitati.
"Non condivido la tua idea, ma darei la vita perché tu la possa esprimere"

Voltaire


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

22/11/2024 @ 15:42:23
script eseguito in 39 ms