Questo sito non è in nessun modo collegato a Microsoft.
I punti di vista ed i commenti inseriti nei blog degli utenti sono personali e non necessariamente coincidenti con i nostri.
La nostra direzione non è responsabile per il contenuto di siti internet esterni.
4.6. Un materiale con tutte le componenti
Posted Dom, 21/03/2010 - 12:50 by Koder4Fun
5
Il tuo voto: NessunoMedia: 5(2 voti)
Utilizzando i framenti di codice d'esempio e le equazioni dei precedenti capitoli siamo ora in grado di assemblare il codice di uno shader che permetta il rendering di un materiale completo di tutte le sue componenti. In questo caso è utile anche creare una tecnica di shading (quindi anche un Pixel Shader dedicato) per ogni tipo di materiale secondo le componenti che vengono utilizzate. L'obbiettivo di questa pratica è quello di ottimizzare quanto più possibile la parformance generale. Lascio però questa parte al lettore dato che potrà ricavare tutte le tecniche necessarie eliminando opportunamente parti di codice dalla funzione del Pixel Shader completo presentato di seguito.
1 // Matrici di trasformazione in ingresso 2 uniform float4x4 World; 3 uniform float4x4 WorldView; 4 uniform float4x4 ViewProj; 5 6 // Posizione della telecamera in World-Space 7 uniform float4 eyePos; 8 // Posizione della sorgente luminosa omnidirezionale 9 uniform float3 lightPos; 10 11 // Colori delle componenti del materiale 12 uniform float4 ambientColor; 13 uniform float4 diffuseColor; 14 uniform float4 specularColor; 15 uniform float4 emissiveColor; 16 uniform float4 reflectionColor; 17 18 // Esponenete per definire la forma del riflesso speculare 19 uniform float specularExponent; 20 21 // Variabile della riflessione di fresnel per angolo = zero 22 uniform float r0; 23 24 // Textures in ingresso per definire il materiale 25 texture diffuseTex; 26 texture specularTex; 27 texture emissiveTex; 28 texture normalTex; 29 texture reflectionTex; 30 31 // Samplers delle textures delle componenti del materiale 32 sampler2D diffuseSampler :register(s0) =sampler_state 33 { 34 Texture = (diffuseTex); 35 ADDRESSU =WRAP; 36 ADDRESSV =WRAP; 37 ADDRESSW =WRAP; 38 MINFILTER =LINEAR; 39 MIPFILTER =LINEAR; 40 MAGFILTER =LINEAR; 41 }; 42 43 sampler2D specularSampler :register(s1) =sampler_state 44 { 45 Texture = (specularTex); 46 ADDRESSU =WRAP; 47 ADDRESSV =WRAP; 48 ADDRESSW =WRAP; 49 MINFILTER =LINEAR; 50 MAGFILTER =LINEAR; 51 MIPFILTER =LINEAR; 52 }; 53 54 sampler2D emissiveSampler :register(s2) =sampler_state 55 { 56 Texture = (emissiveTex); 57 ADDRESSU =WRAP; 58 ADDRESSV =WRAP; 59 ADDRESSW =WRAP; 60 MAGFILTER =LINEAR; 61 MINFILTER =LINEAR; 62 MIPFILTER =LINEAR; 63 }; 64 65 sampler2D normalSampler :register(s3) =sampler_state 66 { 67 Texture = (normalTex); 68 MIPFILTER =LINEAR; 69 MINFILTER =LINEAR; 70 MAGFILTER =LINEAR; 71 ADDRESSU =WRAP; 72 ADDRESSV =WRAP; 73 ADDRESSW =WRAP; 74 }; 75 76 samplerCUBE reflectionSampler :register(s4) =sampler_state 77 { 78 Texture = (reflectionTex); 79 ADDRESSU =CLAMP; 80 ADDRESSV =CLAMP; 81 ADDRESSW =CLAMP; 82 MAGFILTER =LINEAR; 83 MINFILTER =LINEAR; 84 MIPFILTER =LINEAR; 85 }; 86 87 // Struttura per gli elementi in uscita dal Vertex Shader 88 struct VS_OUT
89 { 90 float4 oPos :POSITION; 91 float2 oTexCoords :TEXCOORD0; 92 float3 oLightVec :TEXCOORD1; 93 float3 oViewVec :TEXCOORD2; 94 float3 oWorldNormalVec :TEXCOORD3; 95 float3 oWorldViewVec :TEXCOORD4; 96 }; 97 98 // Dichiarazione della funzione del Vertex Shader con elementi del vertice 99 // inseriti direttamente nella lista dei parametri.100 VS_OUT mainVS(101 in float3 Pos :POSITION,102 in float3 Normal :NORMAL,103 in float3 Tangent :TANGENT,104 in float3 Binormal :BINORMAL,105 in float2 TexCoords :TEXCOORD0)106 {107 // Dichiarazione della struttura per i dati in uscita108 VS_OUT Out;109 110 // Trasformazione del vertice da object-space a world-space111 float4 p =mul(float4(Pos,1.0), World);112 113 // Passaggio della posizione trasformata in screen space...114 Out.oPos =mul(p, ViewProj);115 // ...e delle coordinate di texture al Pixel Shader116 Out.oTexCoords = TexCoords *2.0;117 118 // Calcolo della matrice di rotazione per la trasformazione da119 // world-space a tangent-space120 float3x3 objToTangentSpace;121 objToTangentSpace[0] =mul(float4(Tangent,0.0), World);122 objToTangentSpace[1] =mul(float4(Binormal,0.0), World);123 objToTangentSpace[2] =mul(float4(Normal,0.0), World);124 125 // Calcolo del vettore normale in world-space126 Out.oWorldNormalVec =mul(float4(Normal,0.0), World);127 // Calcolo del "vettore vista" in world-space128 Out.oWorldViewVec = p - eyePos;129 130 // Calcolo dei vettori che vanno al vertice alla sorgente luminosa e131 // dal vertice alla posizione della telecamera.132 // Trasformazione dei vettori in tangent-space.133 float3 LightVec = lightPos - p;134 Out.oLightVec =mul(objToTangentSpace, LightVec);135 Out.oViewVec =mul(objToTangentSpace, Out.oWorldViewVec);136 137 return Out;138 }139 140 // Dichiarazione del Pixel Shader per il rendering con illuminazione141 // da una luce puntiforme posizionata su "lightPos"142 float4mainPS(143 float2 TexCoord :TEXCOORD0,144 float3 LightVec :TEXCOORD1,145 float3 ViewVec :TEXCOORD2,146 float3 WorldNormalVec :TEXCOORD3,147 float3 WorldViewVec :TEXCOORD4) :COLOR0148 {149 // Normalizzazione dei vettori provenienti dal VertexShader150 LightVec =normalize(LightVec);151 ViewVec =normalize(ViewVec);152 WorldNormalVec =normalize(WorldNormalVec);153 WorldViewVec =normalize(WorldViewVec);154 155 // Recupero di tutti i texel delle varie componenti del materiale e156 // modulazione con i rispettivi colori157 float4 ambient =tex2D(diffuseSampler, TexCoord) * ambientColor;158 float4 diffuse =tex2D(diffuseSampler, TexCoord) * diffuseColor;159 float4 specular =tex2D(specularSampler, TexCoord) * specularColor;160 float4 emissive =tex2D(emissiveSampler, TexCoord) * emissiveColor;161 float3 normal =tex2D(normalSampler, TexCoord).xyz;162 163 float3 reflVec =reflect(WorldViewVec, WorldNormalVec);164 float4 reflection =texCUBE(reflectionSampler, reflVec) * reflectionColor;165 166 // Espansione della normale recuperata dalla texture dal167 // range 0.0 ... 1.0 a -1.0 ... 1.0 per poter essere utilizzata168 // nei calcoli di illuminazione169 normal =normalize((normal *2.0f) -1.0f);170 171 // Calcolo della componente di illuminazione diffusa172 float diff =saturate(dot(normal, LightVec));173 // Calcolo della componente dell'hot-spot speculare174 float spec =pow(saturate(dot(reflect(ViewVec, normal), LightVec)), specularExponent);175 // Calcolo della componente della riflessione Fresnel176 float fres = r0 + (1.0- r0) *pow(1.0-saturate(dot(-ViewVec, normal)),5);177 178 // Calcolo del colore definitivo come somma delle componenti179 return(ambient + diffuse * diff + specular * spec + emissive + reflection * fres);180 }181 182 // Tecnica per il rendering del materiale183 technique Materiale
184 {185 pass Pass0
186 {187 ZEnable =true;188 ZWriteEnable =true;189 AlphaBlendEnable =false;190 FillMode = solid;191 192 VertexShader =compile vs_2_0mainVS();193 PixelShader =compile ps_2_0mainPS();194 }195 }
Con questo capitolo abbiamo esaurito la trattazione di ogni caratteristica di un materiale standard proponendo uno shader che sia sufficentemente flessibile da rappresentare un buon numero di differenti materiali utilizzando un'interfaccia unica verso il codice C#.