\\ Home : Articoli : Stampa
Pixel Shader Assembler 2.0
Di RobyDx (del 13/02/2007 @ 09:39:06, in DirectX9, linkato 1380 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