notJustCode.it
 
\\ Home : Articoli
Pixel Shader Assembler 1.1 - 1.3
Di RobyDx (del 11/02/2007 @ 14:08:05, in DirectX9, linkato 1293 volte)

Esistono diversi tipi di linguaggi per i pixel shader con differenze più o meno marcate. Le prime 4 versioni sono molto simili e per questo raggruppate in un unico tutorial. Osservate questo schema:

Questo schema rappresenta il funzionamento del processore grafico della scheda video per i pixel shader. Il discorso è identico a quanto fatto con i vertex shader. A differenza dei linguaggi di alto livello dove non avete problemi nella creazione di variabili in assembler dovete specificare voi in che zona del processore depositare la memoria: tali sono i registri, zone fisiche del processore in cui vengono inseriti valori da usare come variabili. In assembler tali spazi sono molto limitati perchè interni al processore ma allo stesso tempo molto più veloci della RAM usata per depositare grandi porzioni di memoria. In assembler destinato ai pixel shader non potete depositare nulla nella RAM, le uniche zone che potete usare sono i registri. Esistono diversi tipi di registri, alcuni possono essere usati solo in lettura, altri solo in scritture ed altri in entrambi i modi.

 

In questo schema potete vedere i tipi di registri ed il loro numero che non cambia se non nella versione 1.4
I costant register contengono valori che vengono passati dal programma in fase di esecuzione tramite l'istruzione

device.SetPixelShaderConstant n,new single(){0,0,0,0}

Sono solo in lettura
I temporary register invece servono per fare i conti e tenere "a mente" eventuali valori. Sono solo 2 e quindi vanno ben usati. Inoltre il registro r0 è quello più importante: alla fine del codice sarà il valore contenuto in questo a rappresentare il colore effettivo del pixel. Sono usati sia in lettura che scrittura.
I texture register servono per ottenere dati dalla texture. Possono contenere a seconda di come vengono usati sia le coordinate texture che il colore della texture in quel punto. Dalla versione 1.1 sono sia in lettura che in scrittura altrimenti sono solo in lettura.
I color register sono i registri che contengono il colore del pixel in base al colore assegnato al vertice (ricordate oD0 e oD1?). V0 contiene il colore diffuse del pixel mentre V1 quello specular. Anche questo solo in lettura.
I registri sono vettori da 4 divisi in r,g,b e a. Potete accedere ad un registro in questo modo

r0.a

per avere solo la componente a (alpha). Le istruzioni eseguite lavoreranno solo su questa. Attenzione potete farlo solo per a e b per le versioni da 1.1 a 1.3. Se non usate il modificatore tutti i componenti rientreranno nel calcolo. In tutte le versioni potete usare registro.rgb per considerare solo questi 3 componenti.

Modificatori

 

I modificatori sono dei suffissi che si mettono alla fine dell'istruzione per moltiplicare o dividere il risultato per quel numero. Es add_x2 r0,r1,v0 significa moltiplicare per 2 il risultato di r1 per v0. Saturate pone a 0 i valori negativi e ad 1 quelli oltre l'unità (i colori infatti variano tra 0 e 1).

Istruzioni

Le istruzioni sono le seguenti. Alcune tuttavia si adoperano solo in concatenazione con altre.

 

Ps Tutte le versioni

L’istruzione Ps serve per specificare la versione pixel shader da usare e deve essere la prima istruzione.
Es ps.1.1 indica che stiamo usando la versione 1.1

Def Tutte le versioni

Serve per creare delle costanti numeriche in un registro in modo da non doverle passare tramite Visual basic. Utile per valori che non devono mai mutare. Si inseriscono il registro c da usare ed i valori con punto decimale ed f alla fine. Si devono inserire subito dopo l'istruzione ps
def c0, 1.0f, 0.0f, 0.0f, 1.0f ora in c0 ci sono I valori 1,0,0,1

Add Tutte le versioni

esegue la somma tra registri. Per la destinazione usare solo r1 e r0 per la versione 1.0, anche i registri T per le successive
Es add r1,c0,v0 equivale a r1=c0+v0

Cmp Versioni 1.2, 1.3

cmp dest, src0, src1, src2
Inserisce nella destinazione src1 se src0=>0 o src2 altrimenti. Come destinazione si può usare sia il registro r che i t.

Cnd Tutte le versioni

Identico a cmp ma il confronto è fatto su 0.5 anziché 0. Nella versione 1.0 non usare i registri T.

Dp3 Tutte le versioni

Calcola il dot product tra le due sorgenti (somma dei prodotti dei componenti dei registri per tre componenti)
Es Dp3 r1,c0,v0

Dp4 versioni 1.2, 1.3

Calcola il dot product tra le due sorgenti (somma dei prodotti dei componenti dei registri per quattro componenti)
Es Dp4 r1,c0,v0

Lrp Tutte le versioni

Calcola l’interpolazione tra le tre sorgenti
lrp dest, src0, src1, src2 equivalente a dest = src2 + src0 * (src1 - src2)

Mad Tutte le versioni

Esegue questo calcolo dest = src0 * src1 + src2
Es mad r0, v0, t0, v0

Mov Tutte le versioni

Copia il secondo registro nel primo
Es mov r1,c0 copia c0 in r1

Mul tutte le versioni

Esegue il prodotto tra le sorgenti
Es mul r0, v0, t0 equivale a r0 =v0 x t0

Nop tutte le versioni

Non fa nulla. Serve solo a rallentare il programma effettuando un ciclo a vuoto.
Es nop

Sub Tutte le versioni

Esegue la differenza tra registri
Es sub r0, v0, t0 equivale a r0=v0-t0

Tex Tutte le versioni

Carica il colore della texture per quel pixel
Es tex t0 copia il colore della prima texture nel registro, usando t1 si copia la seconda.

Texbem Tutte le versioni

Effettua il bumpmapping.
Es texbem t1, t0
Si può usare solo su texture consecutive (infatti la bumpmap va inserita in uno strato precedente).

Texbeml tutte le versioni

Come sopra ma in più c’è la correzione del colore per la luminosità

TexCoord tutte le versioni

Copia le coordinate uvw1 nel registro T per quella texture in modo che si dispongano al posto dei valori rgba.
texcoord t0

TexDp3 versioni 1.2 e 1.3

Esegue il dotproduct 3 tra registri t usando anche la destinazione come sorgente
texdp3 t1,t0

texdp3tex versioni 1.2 e 1.3

Come sopra ma il risultato viene posto come texture 1D

Texkill Tutte le versioni

Es texkill t0 Se per un pixel le coordinate di quella texture sono minori di 0 allora quel pixel non verrà disegnato.

texreg2ar, texreg2gb tutte le versioni e texreg2rgb versioni 1.2 e 1.3

es texreg2ar t1,t0
Carica nel registro texture che gli viene passato le coordinate UV nei colori specificati nelle ultime due lettere delle istruzioni.

Note sulle texture.

Per ogni texture potete caricare solo una cosa (ad esempio coordinata texture o colore texture). Se vi servono sia le coordinate che il colore di una stessa texture dovete metterle su indici diversi (esempio
texcoord t0
tex t1
potete non mettere texture nel primo e mettere la texture nel secondo indice. Per ogni indice o caricate le coordinate o caricate il colore etc.Ogni registro texture si usa solo una volta in dichiarazione (non si può usare tex 2 volte sulla stessa t ad esempio).

Istruzioni multiple

Ci sono delle istruzioni che devono obbligatoriamente essere usate insieme per non generare errori e funzionare. Sono molto complesse e difficilmente comprensibili nei risultati ma per gli effetti migliori sono le uniche.

texm3x2depth versione 1.3

Effettua un calcolo per generare un valore per il depth testing. M e n sono i numeri delle texture con m>n
tex t(n)
texm3x2pad t(m), t(n)
texm3x2depth t(m+1), t(n)
Nelle coordinate texture tm e tm+1 vanno le 6 valori che insieme alla tex(n) che deve contenere una texture con le normali sostituisce il sistema con cui viene calcolato il depth (è complicato, l'unica è fare prove). Il calcolo fatto è questo
z = TextureCoordinates(stage m)UVW • t(n)RGB
w = TextureCoordinates(stage m+1)UVW • t(n)RGB'per i sistemi che con W buffer
if (w == 0)
t(m+1) = 1.0
else
t(m+1) = z/w
le t usate non vanno usate (eccetto la prima) perchè saranno usate per il depth buffer. In definitiva potete personalizzare il modo con cui lavorerà lo Z buffer (e il W buffer). I valori vanno passati tramite coordinate nelle texture specificate (quindi servirà un vertex shader per gestire tutto al meglio).

texm3x2tex tutte le versioni

Effettua una trasformazione matriciale tramite le due istruzioni precedenti. In t2 rimarrà il colore definitivo.
Es
tex t0 ;n
texm3x2pad t1, t0 ;m
texm3x2tex t2, t0 ;m+1
Nelle coordinate texture t1 e t2 andranno valori u,v,w che modificheranno t0 tramite questa formula.
u' = t(n)RGB • TextureCoordinates(stage m)UVW
v' = t(n)RGB • TextureCoordinates(stage m+1)UVW
t(m+1)RGB = TextureSample(stage m+1)RGB using (u', v') as coordinates.

texm3x3 versione 1.2 e 1.3

Effettua una trasformazione matriciale utilizzando le due istruzioni pad. Come sopra ma si usa una matrice 3x3 scaricata nelle coordinate texture 1,2,3
es
tex t0 texm3x3pad t1 ,t0
texm3x3pad t2, t0
texm3x3 t3, t0
u' = TextureCoordinates(stage m)UVW • t(n)RGB
v' = TextureCoordinates(stage m+1)UVW • t(n)RGB
w' = TextureCoordinates(stage m+2)UVW • t(n)RGB
t(m+2)RGBA = (u', v', w', 1)
Il calcolo è
u' = TextureCoordinates(stage m)UVW • t(n)RGB
v' = TextureCoordinates(stage m+1)UVW • t(n)RGB
w' = TextureCoordinates(stage m+2)UVW • t(n)RGB
t(m+2)RGBA = (u', v', w', 1)

texm3x3spec tutte le versioni

Effettua una trasformazione matriciale per effetti specular dove C è il punto di vista.
tex t0
texm3x3pad t1, t0
texm3x3pad t2, t0
texm3x3spec t3, t0, c0

texm3x3vspec tutte le versioni

ps.1.0
tex t0
texm3x3pad t1, t0 // First row of matrix multiply.
texm3x3pad t2, t0 // Second row of matrix multiply.
texm3x3spec t3, t0, c# // Third row of matrix multiply to get a 3-vector.
mov r0, t3
Come sopra ma per punto di vista in movimento.

Creare un codice shader

Tutti i codici per le versioni 1.0 fino a 1.3 devono iniziare con l’istruzione della versione, le definizioni di costanti, se ci sono, e terminare dopo i vari calcoli con un’assegnazione finale a r0 che sarà il colore effettivamente proiettato. R0 può essere comunque usato come registo temporaneo, l'importante è essere sicuri che alla fine del ciclo contenga qualcosa (e possibilmente qualcosa che vogliamo).
Es

ps.1.0
tex t0
mov r0, t0

Questo codice ignora l’illuminazione inserendo direttamente il colore della texture nel colore finale (in questo modo si può ad esempio mettere una texture su un materiale diverso dal bianco evitando che assuma quella sfumatura).

ps.1.0
tex t0
mul r0, v0, t0

Qui invece il colore viene modulato tra quello diffuse e quello texture (colore normale).

ps.1.0
tex t0
tex t1
mov r1, t1
lrp r0, v0, t0, r1

Questo invece effettua un blending tra due texture.
L’unico modo per impadronirsi della tecnica è fare prove e prove. Consiglio a tutti di utilizzare dei programmi per il testing dei codici pixel shader. Uno si trova nella SDK di Dx8 della microsoft nella sezione C++. L’esempio C++ infatti è un vero tester degli shader e quindi può essere utile almeno per verificare che il codice è corretto prima di vederne l’effetto all'interno del programma. C'è ne sono altri migliori come ad esempio lo smart shader, o i vari tools di ATI e NVidia. Sulla rete si possono trovare molti esempi, alcuni che sfruttano sia i vertex che i pixel shader per effetti veramente professionali. Un pixel shader ad ogni modo ha poco effetto se utilizzato da solo in quanto non è possibile fare molto calcolando un pixel alla volta. Nella maggioranza dei casi infatti vengono utilizzati in simbiosi con i vertex shader. Lo scopo infatti non è quello di fare operazioni con texture e colore diffuse o specular. Si possono infatti inserire al posto delle coordinate texture dei valori (ad esempio le normali e perchè no la posizione dei vertici) e usarli per eseguire calcoli. Se ad esempio volete creare delle riflessioni dovrete sfruttare normali, direzioni ed altro ancora. Molto difficile a volte ma del resto i migliori effetti di shader vengono creati da gente veramente in gamba con un bagaglio di matematica e fisica non indifferente. Basta comunque una intuizione per trovare un'ottima idea da applicare. In alternativa potete leggere articoli e tutorial su shader creati da queste persone e tentare di riprodurli. Vi lascio ad uno shader che ho creato io. Lo shader si compone di un vertex shader che emette come colore le normali del poligono orientate rispetto al mondo e di un pixel shader che in base alle normali crea un riflesso metallico.

Esempio VB

Articolo Articolo  Storico Storico Stampa Stampa
I commenti sono disabilitati.
"La fede unisce. La religione divide."

Il volo della Fenice


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

28/01/2022 @ 03:20:28
script eseguito in 49 ms