Questa settimana lasceremo da temporaneamente da parte l’evoluzione del mercato delle gpu per tornare ad occuparci delle tecniche di filtraggio. Qualche mese fa, avevamo avuto modo di
introdurre il discorso sull’aliasing, sulle tecniche di antialiasing e su come queste trovino applicazione nei chip grafici. Questa volta faremo un breve cenno alle tecniche di texture mapping e filtering. Nei tre articoli riguardanti la realizzazione di un’immagine 3D, avevamo visto che dopo aver disegnato le geometrie, disposto gli oggetti all’interno dello spazio, definite le dimensioni e la forma del campo visivo, rimosso le superfici nascoste, colorati gli elementi contenuti all’interno dello spazio stesso, sulle superfici di questi stessi elementi, siano essi pareti, alberi, rocce o, magari, esseri animati, per rendere il tutto più verosimile, si applicano delle “skin” che hanno lo scopo di rendere realistiche le superfici stesse. A titolo di esempio, si faccia un confronto tra le due immagini sottostanti:
quella a sinistra è composta da soli 8 poligoni (triangoli, ovviamente) di cui è stato calcolato il solo colore. Le immagini, come ovvio, sono bidimensionali e solo la differenza cromatica tra i due quadrilateri che compongono il muro dà una vaga illusione di tridimensionalità.
Se, però, applico una texture come, ad esempio, quella che si vede a destra sul muro stesso, ottengo l’effetto di dare l’illusione di una struttura 3D con addirittura i mattoni in rilievo. L’effetto finale è è piuttosto buono se rapportato alla potenza computazionale “spesa”. In questo caso ci si è limitati alla sola applicazione di una texture 2D ma, come abbiamo visto qualche settimana fa, c’è anche la possibilità di fare di meglio, ricorrendo a tecniche di bump mapping, che prevedono l’uso di fino a 3 texture bidimensionali, oppure di displacement mapping che prevedono, invece, l’uso di texture 3D ricavate da quelle 2D di partenza. Come ricordato nell’articolo sulle High Order Surface, il passo successivo è il ricorso alle operazioni di tessellation, le uniche in grado di aumentare fisicamente il numero di poligoni, che possono essere integrate dall’utilizzo di displaced map e/o di bump map.
Nell’applicare texture bidimensionali si deve decidere come “incollarle” sull’oggetto; in parole povere si deve stabilire una esatta corrispondenza tra colori dei pixel su cui la texture va applicata e posizione della texture map stessa.
Per fare ciò, si deve tener conto di due fattori; la forma della texture, il map shape che ci dà informazioni sulle coordinate (x, y, z) che interessano la texture in oggetto e il cosiddetto map entity, ossia il range dei valori (x, y, z) tra cui possono variare queste coordinate.
La forma più semplice è quella planare; si tratta di una texture bidimensionale applicata su un oggetto come una pellicola; l’applicazione avviene “proiettando l’immagine della texture lungo uno dei tre assi”; in parole povere, si fissa uno dei tre assi e si muove la texture lungo di esso, fino ad incontrare l’oggetto su cui la si deve applicare. Se, quindi, ad esempio, uso l’asse z come asse di proiezione, una traslazione dell’oggetto lungo l’asse z non porterà a cambiamenti nella posizione relativa di pixel e texel; se, invece, traslo l’oggetto lungo uno degli altri due assi, rileverò una traslazione relativa dei texel rispetto ai pixel avente stessa direzione e intensità della traslazione dell’oggetto, ma verso opposto. Nella figura in basso, una texture bidimensionale applicata usando come asse di “riferimento” proprio l’asse z
Come si vede, se applico una traslazione relativa dell’oggetto o della texture lungo z, continua a restare invariata la posizione dei punti dell’oggetto rispetto ai texel (i quadratini di cui è formata la texture che si possono considerare per la texture quello che i pixel sono per un poligono). Una qualunque traslazione del poligono o della texture lungo x o y, invece, provoca uno “sfasamento” tra pixel e texel che porta a trovare, ad esempio, un colore in posizione differente da quella in cui si troverebbe in assenza di spostamenti relativi.
Altra forma utilizzata per le texture è quella cilindrica in cui le coordinate (x, y, z) sono convertite in (r, theta, height) e in cui, assumendo che l’asse z sia parallelo all’asse del cilindro, per trovare i colori applicati sulla superficie dell’oggetto si applica un cambio di coordinate che trasforma l’angolo theta in x e l’altezza in y.
Oltre quella cilindrica c’è quella sferica, in cui si deve operare una trasformazione della latitudine e della longitudine rispettivamente in x e y per ritrovare i colori sull’oggetto
Sia l’uso di texture cilindriche che sferiche produce distorsioni in prosismità dei valori massimi e minimi di z, ossia nei punti più lontani e più vicini rispetto all’osservatore; per questo motivo, nel tempo, sempre più affermate, quelle che fanno uso di shape di tipo cubico. Queste ultime si applicano sull’oggetto allo stesso modo delle texture planari, conservando lo stesso sistema di riferimento, ma hanno il vantaggio di presentare 6 superfici planari al posto di una sola, unendo i vantaggi delle texture planari e si quelle sferiche o cilindriche. In basso un esempio di texture di tipo cubico
Nelle due successive immagini, una texture di tipo cubico “aperta”
e il risultato della sua applicazione sulla nostra teiera
Questa è quella che in gergo si definisce cubemap; una delle feature introdotte dalle DX10.1 e presente, ovviamente, anche nelle DX11, dal nome piuttosto evocativo di cubemap array, permette di effettuare con singola chiamata l’accesso ad un intero array di cubemap così come la texture array delle DX10 permetteva di accedere con singola chiamata ad un intero array di texture planari. Evidente il vantaggio, in termini di illuminazione globale della scena, dato dalla possibilità di scrivere e leggere più cube map in una sola passata.
Finora abbiamo parlato di forme e di coordinate ma non abbiamo definito il range all’interno del quale queste ultime possono variare, ossia il parametro che abbiamo chiamato entity. Per definirlo di adottano, fondamentalmente, quattro metodi a seconda degli elementi adoperati per definirlo, una volta individuati i punti sull’oggetto da utilizzare come riferimenti: 1) la posizione (ossia un punto sull’oggetto messo in relazione con l’object bounding box); 2) la normale alla superficie che deve essere renderizzata, calcolata in un suo punto; 3) un vettore che dal centro dell’oggetto attraversa il punto preso come riferimento sull’oggetto stesso; 4) il vettore che rappresenta la “riflessione” calcolato nel solito punto di riferimento (quest’ultimo dipende, oltre che dalla posizione dell’oggetto e dal punto scelto, anche dalla posizione dell’osservatore) . Nella successiva immagine è schematizzato quanto detto sulle quattro modalità di scelta della map entity
dove si è scelto come esempio, in tutti e quattro i casi, lo stesso punto sul becco della teiera.
Dall’interazione tra map shape e map entity si ottengono risultati differenti; ad esempio, in figura sono riportati 4 differenti esempi di texture con la stessa map shape (di tipo cilindrica) ma differenti scelte per la map entity
Combinando map shape e map entity per la stessa texture si possono ottenere risultati molto diversi tra di loro.
Per non appesantire troppo la trattazione sia a livello nozionistico che di immagini, tralascio di parlare delle funzioni parametriche e di quelle di tipo non lineare. Nell’introdurre il discorso sull’utilizzo delle texture e sulle operazioni di filtraggio ad esse relative, si è fatto un uso delle immagini di molto superiore al solito. In effetti, parlare di grafica significa parlare di immagini e il modo migliore per descriverle è, sicuramente, quello di mostrarle. In particolare, parlare di texture trattando l’argomento a livello teorico e nozionistico diventa estremamente pesante, molto più delle stesse immagini postate. Da’ltronde, se tentassi di descrivere un manifesto o un dipinto riuscirei a farvelo “vadere” meglio che se ve lo mostrassi? Una texture può considerarsi proprio alla stregua di un manifesto o di una “foto” applicata su una superficie liscia e del tutto “anonima”; grazie a questa applicazione, quella superficie può diventare un muro di mattoni o di pietra, un prato, una tenda, oppure un vestito o qualunque altra cosa. Sono, dunque, le texture a simulare la meterialità degli oggetti presenti in uno spazio 3D virtuale.
In realtà, le texture non sono degli oggetti materiali che possiamo immaginare che siano presi e applicati fisicamente su qualcosa, come ad esmepio si fa con la carta da parati su un muro; in realtà si tratta di tabelle che recano informazioni su colore, consistenza dei materiali, eventuali riflessioni, ecc.
Se oggi abbiamo iniziato a prendere confidenza con questi strumenti, nei prossimi articoli vedremo come questi elementi sono usati, come si possono applicare più layer di texture per ottenere, ad esempio, effetti di trasparenza, o simulare riflessioni, ecc. Vedremo anche come le texture sono campionate, applicate e come pure esse siano soggette a problemi di aliasing e necessitino di speciali operazioni di filtraggio. Vedremo, in breve, infine, a livello hardware, chi si occupa di tutte queste operazioni e in che modo.