Gli Shaders 3.0 sono la versione ultima del linguaggio assembler destinato alle schede con GPU programmabile. La versione 3 dei vertex e pixel shader amplia ulteriormente le possibilità offerte da 2.0 e 2_x e diventerà nei prossimi anni lo standard base per gli effetti shaders. Al momento esistono pochissime schede video che supportano gli shader 3.0 e prima che venga utilizzato in un qualunque gioco occorreranno molti anni visto che i primi giochi shaders 2.0 stanno appena affacciandosi. Il tutorial è il seguito del tutorial sugli shaders 2_x.
Vertex shader 3.0
Registri
Il nuovo registro di input è il registro sampler. Ebbene, con gli shader 3.0 potrete caricare texture direttamente nel codice vertex shader. Potrete utilizzare così il displacement mapping. In pratica la texture sarà utilizzata a livello di vertici come informazioni per deformare i vertici. Una montagna sarà semplicemente un piano con una texture in bianco e nero che ne determina l’altezza in ogni punto. Già si vedono i primi possibili utilizzi in cui le texture deformano gli oggetti per simulare gli impatti tra oggetti (un esempio che ho avuto modo di vedere è quello di un lenzuolo che passava su una sfera adattandosi perfettamente sfruttando una texture come inpatto e le comuni leggi fisiche per generare in modo realistico le pieghe).
I registri sampler sono indicati con s1, s2, s3, s4. Essi non contengono però le texture negli indici da 0 a 7 ma quelle in indici speciali (257,258,259,260). Passate la texture a questi 4 indici per inserirle nei sampler. I sampler come gli altri registri vanno dichiarati prima dell’utilizzo
dcl_2D s0
dcl_volume s0
dcl_cube s0
Per i registri di output enorme novità. Ora i registri di output sono semplicemente registri o# che vanno dichiarati per essere usati
Eccone i principali
dcl_position o1//posizione
dcl_normal o2//normale (potete passare anche dati riguardo vertici)
dcl_color o3//diffuse
dcl_color1 o4//specular
dcl_texcoord0 o5 //coordinate texture
dcl_texcoord1 o6
…………….
dcl_psize o7//dimensione del punto
dcl_fog o8//nebbia
potete ovviamente dichiarare i registri nell’ordine che volete (ad esempio il position magari con o5) e anche per parti. Ad esempio
dcl_texcoord0 o5.xy
dcl_texcoord1 o5.zw
In questo modo potete con un solo registro passare più valori. Il limite è 12 registri o, più che sufficienti per ogni possibile output vi inventiate.
Tutti i registri sono indicizzabili con il registro aL durante l’uso nei cicli loop.
Vertex Texture
Come ho detto ora potete caricare le texture sul vertice. In ogni vertice potete caricare dei punti delle texture ed usarle come volete. Lo scopo è essenzialmente come dicevo di usare le informazioni per deformare i vertici in base a dati che vengono inseriti in texture (che sono come sappiamo facilmente elaborabili anche tramite render to surface).
L’istruzione da usare è
texldl dest ,src1,src2
dove dest è un registro r#, src1 una coordinata texture (registro r# o o#) e src2 è un registro sampler associato alla texture.
Il componente .w di src1 è usato per il level of detail (texture con mipmapping).
Potete usare tutto ciò che è presente negli shader 2.0 e 2_x.
Pixel Shader 3.0
Come i vertex shader sono diventati un po’ pixel così i pixel shader 3.0 possono accedere ad alcuni dati dei vertici. Comunque le novita sono poche ma come al solito interessanti.
Registri
Ci sono 2 nuovi registri di input da adoperare.
vFace
vPos
il primo indica l’area del triangolo in cui si trova il pixel. Per il momento (ci sarà un probabile aggiornamento) viene solo restituito un valore negatico o positivo per indicare se la faccia è opposta o di fronte a noi. Se state già pensado di sfruttare il culling (procedura in cui le faccie da un lato non sono visibili) avete indovinato. Potrete applicare effetti particolari ai lati a seconda se siano in senso orario o no. Quando verrà aggiunto anche il valore preciso dell’area (che sarà sempre negativo o positivo per indicare il verso) potrete ad esempio variare il colore a seconda della dimensione della faccia.
Il secondo semplicemente indica in xy la posizione che il pixel ha sullo schermo. Anche questo è incredibilmente utile perché finalmente si avrà facilmente la posizione esatta in cui un pixel si trova sullo schermo.
Entrambi vanno dichiarati
dcl vFace
dcl vPos.xy
Ed il primo può essere usato solo nelle istruzioni if (almeno per il momento).
I registri ora sono totalmente cambiati in input. I registri t sono scomparsi e tutti sono ora registri v da dichiarare in questo modo
dcl_color v0
dcl_color1 v1
dcl_texcoord0 v2
E così via
Il resto rimane invariato. L’ultima fondamentale novità è che ora gli shaders possono avere lunghezza infinita. Non esistono più limiti (salvo quelli che daranno le schede video) per la lunghezza e complessità degli shader. Quello che facevate con 10 pass potreste riuscire a farlo addirittura con 1.