INDICE: it.Of Effects and Shaders
Precedente: I Dati del Vertice
Prossimo: Morphing della Geometria
VVVV ha un modulo d'aiuto per visualizzare le normali di una mesh: Normals (EX9)
Possiamo modificare la sua helppatch per avere una vista della mesh con le normali:
Se la mesh non contiene le sue normali, allora è possibile usare il nodo Normals (EX9.Geometry Mesh) per calcolarle nella patch prima di passare la mesh allo shader. Usa il pin Smoothing Angle per calcolare la media delle normali sulla superficie.
Dato che la maggior parte di modelli di shading (come il phong) hanno bisogno della normale nello spazio relativo alla vista, dobbiamo trasformare la normale assieme alla posizione del vertice, facendo attenzione al fatto che la normale è un float3, o se è un float4, la componente w della normale è 0 (invece che 1 come nella posizione), e che può essere solo ruotata, ma non traslata. Un tipico vertexshader compie queste trasformazioni:
... //normal in view space Out.NormV = normalize(mul(NormO, tWV)); //position (projected) Out.PosWVP = mul(PosO, tWVP); ...
Naturalmente le cose si complicano se si cambiano le posizioni del vertice nel vertexshader, proprio come è successo in it.Mr.Wiggle o in Disegnare con le Funzioni. Dato che la traslazione delle posizioni dei vertici cambia la curvatura della superficie, le normali memorizzate precedentemente nella mesh non sono più valide. Quindi i calcoli per lo shading sono sbagliati.
Così, se hai bisogno di calcolare l'illuminazione nel pixelshader devi trovare il modo di ricalcolare le normali, prima. Questo però è strettamente legato al metodo che usi per traslare le posizioni.
Il metodo più usato, ma poi non così preciso, per calcolare le nuove normali consiste nel calcolare 2 posizioni vicine in più ed ottenerne due vettori che sono sul piano tangente a questo vertice e non sono paralleli. Dai due vettori tangenti si può calcolare la normale con il prodotto vettoriale (cross product):
Usando l'esempio del cono da Disegnare con le Funzioni avremmo:
float NeighbourOffset = 0.001; vs2ps VS( float4 PosO : POSITION, float4 TexCd : TEXCOORD0) { //dichiara la struttura dell'output vs2ps Out; //calcola la nuova posizione float3 p = Cone(PosO.xy); //calcola la posizione vicina nella direzione u float3 n1 = Cone(PosO.xy + float2(NeighbourOffset, 0)); //calcola la posizione vicina nella direzione v float3 n2 = Cone(PosO.xy + float2(0, NeighbourOffset)); //ottiene il vettore tangente 1 float3 t1 = p - n1; //ottiene il vettore tangente 2 float3 t2 = p - n2; //ottiene la normale float3 NormO = cross(t1, t2); //imposta la nuova posizione PosO.xyz = p; ...
Per poter usare le normali potremmo per sesempio usare la funzione Phong dichiarata nel file PhongDirectional.fxh nella cartella effects di vvvv. Copia quindi il contenuto del file .fxh nel tuo shader, e poi confronta il codice contenuto in PhongDirectional.fx pr capire quali righe siano necessarie per aver un phong shading che funzioni.
Dobbiamo inserire la normale, la luce e la direzione della vista nello spazio della vista, e poi passare tutto quello che c'è nella struttura vs2ps al pixelshader. copamo anche il codice per la texture per aver un buon setup per lo shading, dove si possa semplicemente rimpiazzare la funione Cone con tutte le superfici parametriche-uv che si possono troare sul web:
// ---------------------------------------------------------------------------- // PARAMETRI: // ---------------------------------------------------------------------------- //trasforma float4x4 tW: WORLD; //il modello matrice mondo tramite lo shader float4x4 tV: VIEW; //matrice vista come impostata tramite Renderer (EX9) float4x4 tP: PROJECTION; //matrice proiezione come impostata tramite Renderer (EX9) float4x4 tWV : WORLDVIEW; float4x4 tWVP: WORLDVIEWPROJECTION; //tutti e 3 premoltiplicati /la trasformazione della texture segnata con la semantica TEXTUREMATRIX //per ottenere trasformazioni simmetriche float4x4 tTex: TEXTUREMATRIX <string uiname="Texture Transform";>; //texture texture Tex <string uiname="Texture";>; sampler Samp = sampler_state //campionatore per il lookup della texture Texture = (Tex); //applica una texture al campionatore MipFilter = LINEAR; //stati del campionatore MinFilter = LINEAR; MagFilter = LINEAR; }; //la struttura dati: "vertexshader to pixelshader" //usata come output della Funzione VS //e come input della funzione PS struct vs2ps { float4 Pos : POSITION; float2 TexCd : TEXCOORD0; float3 LightDirV: TEXCOORD1; float3 NormV: TEXCOORD2; float3 ViewDirV: TEXCOORD3; }; #include "PhongDirectional.fxh" // ---------------------------------------------------------------------------- // VERTEXSHADERS // ---------------------------------------------------------------------------- #define twopi 6.28318531 float2 Scale = 1; float2 Offset = 0; float3 Cone(float2 uv) { uv *= Scale; uv += Offset; float u = uv.x * twopi; float v = uv.y; float3 newPos; newPos.x = v * cos(u); newPos.y = v * sin(u); newPos.z = v; return newPos; } float NeighbourOffset = 0.001; vs2ps VS( float4 PosO : POSITION, float4 TexCd : TEXCOORD0) { //dichiara la struttura dell'output vs2ps Out; //calcola la nuova posizione float3 p = Cone(PosO.xy); //calcola la posizione vicina nella direzione u float3 n1 = Cone(PosO.xy + float2(NeighbourOffset, 0)); //calcola la posizione vicina nella direzione v float3 n2 = Cone(PosO.xy + float2(0, NeighbourOffset)); //ottiene il vettore tangente 1 float3 t1 = p - n1; //ottiene il vettore tangente 2 float3 t2 = p - n2; //ottiene la normale float3 NormO = cross(t1, t2); //imposta la nuova posizione PosO.xyz = p; //immette la normale nello spazio vista e la normalizza Out.NormV = normalize(mul(NormO, tWV)); //direzione inversa della luce nello spazio vista Out.LightDirV = normalize(-mul(lDir, tV)); //direzione inversa della vista nello spazio vista Out.ViewDirV = -normalize(mul(PosO, tWV)); //trasforma la posizione (proiettata) Out.Pos = mul(PosO, tWVP); //trasforma le coordinate della texture Out.TexCd = mul(TexCd, tTex); return Out; } // ---------------------------------------------------------------------------- // PIXELSHADERS // ---------------------------------------------------------------------------- float Alpha <float uimin=0.0; float uimax=1.0;> = 1; float4 PS(vs2ps In) : COLOR { float4 col = tex2D(Samp, In.TexCd); col.rgb *= PhongDirectional(In.NormV, In.ViewDirV, In.LightDirV); col.a *= Alpha; return col; } // ---------------------------------------------------------------------------- // TECHNIQUES: // ---------------------------------------------------------------------------- technique TFunctionWithPhong { pass P0 { VertexShader = compile vs_1_1 VS(); PixelShader = compile ps_2_0 PS(); } }
INDICE: it.Of Effects and Shaders
Precedente: I Dati del Vertice
Prossimo: Morphing della Geometria
anonymous user login
~8d ago
~17d ago
~17d ago
~22d ago
~26d ago
~1mth ago
~1mth ago
~2mth ago
~2mth ago
~2mth ago