Pixel Shader Assembler 2.0
Di RobyDx (del 13/02/2007 @ 09:39:06, in DirectX9, linkato 1513 volte)
La tecnologia shader già affermatasi con l’introduzione di DirectX8 continua ad evolversi e diventare sempre più presente nei giochi e nelle applicazioni di oggi. Molti giochi ormai usano effetti shader che portano la grafica a livelli altissimi e sempre più simili alla realtà. Con DirectX9 vengono introdotte nuove versioni dei linguaggi assembler destinati ai vertex e pixel shader. In questo tutorial vi illustrerò il funzionamento dei pixel shader 2.0 supportato ad oggi solo sulle schede di ultima generazione. La nuova versione shader ritorna come meccanismo di funzionamento alle prime 4 versioni di pixel shader (dalla 1.0 alla 1.3) eliminando la scomoda, seppur utile, doppia fase. Tuttavia i miglioramenti introdotti sono tali da rendere le precedenti versioni completamente antiquate ed inutili.
|
Pixel Shader 1.3 |
Pixel Shader 1.4 |
Pixel Shader 2.0 |
Max n°istruzioni |
4 texture + 8 aritmetiche |
6 texture + 8 aritmetiche per fase |
32 texture + 64 aritmetiche |
Texture caricabili |
4 |
6 |
16 |
Registri R# |
2 |
6 |
Da 12 a 36 |
Registri C# |
8 |
8 |
32 |
Chi di voi ha usato i pixel shader capisce come sia migliorato l’utilizzo degli shader che ora può veramente essere scritto senza limiti (difficilmente scriverete codici più lunghi di 96 istruzioni). Il tutto senza usare la doppia fase che sicuramente avrà confuso molti di voi e senza perdere la possibilità di modificare le coordinate texture del pixel su cui si lavora. I cambiamenti sono abbastanza indolore ma richiedono un po’ di lavoro.
Nuovi registri
I registri pixel shader sono ora aumentati
registro
|
numero
|
Read-Write
|
descrizione
|
Input register
V0,V1
|
2
|
R
|
I registri contengono i colori diffuce e specular provenienti dal vertex shader
|
Temporary register
R#
|
12-36
|
RW
|
I registri da usare come variabili, ora il registro r0 è diventato un normale registro
|
Costant float register
C#
|
32
|
R
|
Costanti da passare dal programma o da definire nel codice assembler
|
Sampler register
S#
|
16
|
R
|
Usati per definire i sampling stage. DirectX ha come massimo 8 texture caricabili ma una texture può essere letta più volte da sampler diversi. I sampler vengono settati dal programma e consentono ad esempio di settare filtri etc. Inoltre se da codice inserite 16 texture diverse potrete tramite questo registro sceglierne 8 da caricare e usare, in qualsiasi indice si trovino.
|
Texture coordinate register
T#
|
8
|
R
|
Le coordinate delle texture in quel pixel
|
Output color register
OC#
|
#
|
W
|
Il registro oC# contiene il colore finale. Vista la possibilità in directX di renderizzare simultaneamente su più texture (multiple render target) potete tramite il suo numero dare ad ogni render target un valore finale differente. Un solo codice shader per più rendering differenziati.
|
Output depth register
oDepth
|
1
|
W
|
Con questo registro si assegna la profondità per Zbuffer e stencil buffer
|
Dichiarazioni
Alcuni registri devono essere dichiarati nel codice prima di essere usati. Questo tramite l’istruzione dcl dcl v# ‘dichiarazione registro input dcl t# ‘dichiarazione registro texture dcl_2d s#, dcl_cube s# , dcl_volume s# ‘dichiarazione del sampler. Potete scegliere fra le 3 tipologie di texture a disposizione in modo da poter usare anche le texture volumetriche e cubiche.
Definizione
È possibile dichiarare un registro c# senza doverlo caricare da codice tramite l’istruzione def Es Def c0,1,2,3,4.5
Uso dei registri
I registri contengono 4 valori (rgba). Per specificare di utilizzare una istruzione basta inserire un punto e specificare quale componente usare. Es r0.r, c0.rg, etc.
Istruzioni 2.0
Nome e sintatti
|
Descrizione
|
Abs dst,src
|
Calcola il valore assoluto
|
Add dst,src1,src2
|
Esegue la somma
|
Cmp dst,src1,src2,src3
|
Inserisce nel registro di destinazione il 2° o il 3° registro se il primo è >=0 o no
|
Crs dst,src1,src2
|
Esegue il cross product |
Dp2add dst,src1,src2,src3
|
Esegue il dot product su 2 coordinate e le somma |
Dp3 dst,src1,src2
|
Esegue il dot product su 3 registri
|
Dp4 dst,src1,src2
|
Esegue il dot product su 4 registri
|
Exp dst,src
|
Calcola 2 elevato al 1° registro
|
Frc dst,src
|
Restituisce la parte fratta del registro
|
Log dst,src
|
Logaritmo in base 2 del registro
|
Lrp dst,src1,src2,src3
|
Calcola l'interpolazione lineare
|
M3x2 dst,src0,src1
|
Esegue il dot product applicato ad una matrice (quindi usa più registri costanti )
|
M3x3 dst,src0,src1
|
Esegue il dot product applicato ad una matrice (quindi usa più registri costanti )
|
M3x4 dst,src0,src1
|
Esegue il dot product applicato ad una matrice (quindi usa più registri costanti )
|
M4x3 dst,src0,src1
|
Esegue il dot product applicato ad una matrice (quindi usa più registri costanti )
|
M4x4 dst,src0,src1
|
Esegue il dot product applicato ad una matrice (quindi usa più registri costanti )
|
Mad dst,src0,src1,src2
|
Prodotto dei primi 2 registri più il terzo
|
Max dst,src0,src1
|
Restituisce il massimo fra 2 registri
|
Min dst,src0,src1
|
Restituisce il minimo fra 2 registri
|
Mov dst,src
|
Copia un registro in un altro
|
Mul dst,src0,src1
|
Esegue il prodotto
|
Nop
|
Esegue una istruzione a vuoto
|
Nrm dst
|
Normalizza un vettore
|
Pow dst,src0,src1
|
Elevazione a potenza del 1° registro con il secondo
|
Rcp dst,src
|
Restituisce il reciproco
|
Rsq dst,src
|
Restituisce il reciproco sotto radice
|
Sincos dst,src0,src1,src2
|
Esegue il calcolo di sin e cos di un angolo. Il registro di destinazione deve essere con registri xy, il primo registro deve invece avere solo un registro specificato (l'angolo in radianti). Infine i rimanenti 2 registri devono essere 2 costanti con i seguenti numeri.
Def c0, -1.5500992e- 006f , -2.1701389e- 005f , 0.0026041667f, 0.00026041668f Def c1, -0.020833334f, -0.12500000f, 1.0f, 0.50000000f
|
Sub dst,src0,src1
|
Esegue la sottrazione
|
Texkill src
|
Se la coordinata texture è minore di zero esce dal codice
|
Texld dst,src0,src1
|
Riceve il colore della texture secondo la coordinata texture specificata nel primo source register (registro t o r) e la texture dichiarata secondo il registro s (normalmente a s0 corrisponde la prima texture e così via)
|
Texldb dst,src0,src1
|
Come texld ma la coordinata texture .a (o .w) viene usata per il livello di dettaglio
|
Texldp dst,src0,src1
|
Come texld ma coordinata texture .a (o .w) viene usata per dividere le coordinate texture
|
Per maggiori dettagli vedere la SDK microsoft per C++
Modificatori di registri
Potete fare delle operazioni sui registri direttamente nelle istruzioni aggiungendo dei suffisso ai registri o facendo una operazione. registro_bias : sottrae 0.5 al registro. Es add r0,v0,r1_bias 1-registro : inverte il registro. Es add r0,v0,1-r0 - registro : cambia segno al registro. Es add r0,v0,-r1 registro_x2 : moltiplica per 2 il registro. Es add r0,v0,r1_x2 registro_bx2: moltiplica per 2 dopo aver sottratto 0.5. Es add r0,v0,r1_bx2
Modificatori
Potete usare dei suffissi accanto alla istruzione per moltiplicare, dividere o saturare (ossia rendere i valori compresi tra 0 e 1) i registri di destinazione. _x2, _x4, _x8 moltiplica per 2,4,8 _d2, _d4, _d8 divide per 2,4,8 _sat satura es add_x4 r0,r1,v0 farà in modo che il registro r0 sarà moltiplicato per 4.
Uso
I pixel shader 2.0 si usano come le prime versioni. Ps.2.0 Definizioni costanti Dichiarazioni registri Istruzioni Copia nei registri oC# Il miglior sistema di usare i pixel shader è tramite le istruzioni di texture che permettono di leggere pixel in posizione diversa da quella considerata. Vista poi la possibilità di leggere una texture più volte (usando sempre lo stesso registro s0), potete usare ben 16 pixel da posizioni qualsiasi per elaborare i vostri effetti. Il miglior uso diventa quindi la creazione di filtri ossia di effetti che tramite il calcolo dei pixel vicini elabora l’immagine. Nell’esempio vedete 4 filtri che ho scritto in pixel shader 2.0. 1)Filtro sobel: tramite differenza di colore tra pixel contigui permette di creare il contorno delle figure (ottimo per migliorare il Cell Shading con linee continue e ben delineate) 2)Gaussian Filter: questo serve per sfocare l’immagine, utile per il depth of field e altri effetti. 3)Tap Filter: espande l’immagine 4)Roberts filter: un filtro carino che ho trovato in un articolo di matematica Provate ad inventare effetti. Vi lascio all’esempio (molto leggero in modo da permettere a chi non ha la scheda video adatta di capire comunque il funzionamento dei pixel shader 2.0).
Esempio VB.Net
|
|
|