Il moderno hardware grafico è basato sulla cosiddetta "pipeline di rendering", consistente in una serie di passaggi che permettono di elaborare una scena tridimensionale e di disegnarla come immagine bidimensionale sullo schermo:
La pipeline di rendering deve essere veloce, perché deve ridisegnare la stessa scena con minimi cambiamenti almeno 20-30 volte al secondo per dare la sensazione di fluidità all'utente. Dal momento che la pipeline è gestita interamente dalla scheda grafica (o GPU, Graphics Processing Unit), è possibile sfruttarne il parallelismo intrinseco per aumentare la velocità di rendering (grazie al fatto di implementare più processori, infatti, la GPU può processare simultaneamente un numero elevatissimo di vertici e pixel).
D'altro canto, ciò comporta una certa rigidità nell'approccio usato per effettuare il rendering.
La pipeline è divisa in due sottosistemi principali, ciascuno dei quali è associato ad un diverso tipo di shader, ossia a un insieme di istruzioni software usate per programmare la pipeline. Abbiamo così:
- un sottosistema geometrico, cui corrisponde un Vertex Shader, che si preoccupa di portare la geometria (tridimensionale) del nostro modello nelle giuste coordinate dello schermo (bidimensionale);
- un sottosistema di raster, cui corrisponde un Pixel (o Fragment) Shader, che si incarica di "accendere" i pixel dello schermo del giusto colore in funzione della geometria, dell'illuminazione e delle texture.
Più nel dettaglio, la pipeline parte dalla geometria della scena per "trasportare" le coordinate dei vertici così come risultano nello spazio originale (ossia quello definito nell'editor usato per creare il modello tridimensionale) in coordinate che consentano di rappresentare quegli stessi vertici nella giusta posizione all'interno del "mondo" del nostro gioco (il cosiddetto "world").
View, il punto di vista della telecamera
Le coordinate dei vertici vengono quindi trasformate in coordinate relative al punto di vista dell'utente (la cosiddetta "view"), dove cioè:
Asse | Direzione dell'osservatore |
---|---|
X |
destra/sinistra |
Y |
su/giù |
Z |
avanti/indietro |
La view rappresenta insomma una sorta di telecamera che, a seconda di dove è posizionata e del verso in cui è orientata, offre una diversa rappresentazione della scena.
Projection, impostare l'inquadratura
Infine, una volta che le coordinate sono state "trasportate" nel nuovo mondo, devono essere messe in una qualche prospettiva (la quale dipenderà a sua volta dall'ampiezza del campo visivo, dal rapporto larghezza/altezza dello schermo, etc.), in modo che gli oggetti più vicini all'osservatore appaiano proporzionalmente più grandi rispetto a quelli più lontani (si parla, in questo caso, di projection).
Se, come si è detto prima, la view rappresenta il punto di vista di una telecamera, la projection ne costituisce l'inquadratura o, se si preferisce, il tipo di obiettivo montato sulla telecamera, che ne influenza il campo visivo, l'aspect ratio e la profondità di campo.
Clipping
Ora che sappiamo dove si trovano i vertici rispetto allo schermo, è possibile tagliare le parti dei triangoli che sono fuori dall'inquadratura (clipping), in modo da non dover rasterizzare porzioni di spazio non visibili per l'osservatore, con conseguenti benefici in termini di performance:
Ecco un utile riepilogo delle principali trasformazioni compiute dal sottosistema geometrico:
Il disegno della scena e la Programmable Graphics Pipeline
Infine, la scena viene disegnata sullo schermo assegnando a ciascun pixel il giusto colore, definito sulla base della texture applicata al modello e dell'illuminazione della scena.
Oggigiorno tutti i maggiori produttori di hardware grafico dedicano grandi sforzi per rendere la loro pipeline programmabili dall'esterno, mediante l'utilizzo di un cosiddetto shader language (Programmable Vertex Processor e Programmable Fragment Processor, rispettivamente detti Vertex Shader e Pixel Shader):
L'insieme degli shaders (Vertex e Pixel) utilizzati per disegnare una scena prende il nome di Effect.
In XNA è possibile programmare propri shader utilizzando il cosiddetto High Level Shading Language (HLSL), un apposito linguaggio di shading messo a punto da Microsoft. Sfortunatamente, per il momento questo è vero solo se sviluppiamo il nostro gioco per Windows o XBox 360, mentre per Windows Phone 7 non sono ancora ammessi shader custom (anche se abbiamo a nostra disposizione una serie di shader predefiniti che ci permettono comunque di realizzare molti degli effetti fondamentali, come vedremo in un prossimo articolo).
Può consolarci il fatto che gli shaders HLSL saranno abilitati anche per Windows Phone 7 in una release successiva di XNA: non sono stati esclusi per limitazioni intrinseche dell'hardware, ma solamente perché il compilatore di HLSL per nVidia Tegra 2 (la GPU di Windows Phone 7) non è ancora sufficientemente completato e ottimizzato.