Texture mapping
# Texture mapping

Il texture mapping in computer grafica è una tecnica che permette di proiettare una o più texture sulla superficie di un modello 3D, utilizzando le coordinate UV. Essa rende il modello più dettagliato e realistico, inoltre la sovrapposizione di più texture è utilizzata ad esempio per dare degli effetti speciali ai modelli tridimensionali come luce e nebbia. La tecnica, in particolare nelle animazioni 3D, unisce la rapidità di calcolo della grafica poligonale alla ricchezza di dettaglio delle immagini in grafica raster.

La diffusione di tale tecnica di animazione nelle applicazioni domestiche come i videogiochi si ebbe negli anni 1990; nei primi anni del decennio era ancora fattibile con velocità adeguate solo sui PC più potenti dell'epoca.

## Storia

Agli albori della computer grafica, i piccoli dettagli dei modelli - che fossero geometrici o riconducibili al colore - erano rappresentati sul modello dell'oggetto "dipingendoli" sul modello stesso, come in una pittura trompe-l'œil. Era possibile dipingere una piccola macchia chiara sul modello in modo sembrasse un punto luce, a prescindere dall'illuminazione nella scena. Questi dettagli erano chiamati texture, ed erano memorizzati in un array immagine. Il modellista della scena doveva anche associare ogni vertice del modello alla posizione nell'array immagine, perciò "mappare" il modello all'immagine (sebbene l'obiettivo generale fosse proprio l'opposto - questa mappatura era usata per "applicare" l'immagine sul modello, come un adesivo).

Presto divenne chiaro che piuttosto che mappare l'albedo (ovvero la frazione dell'energia riflessa), era possibile mappare altri parametri del modello di illuminazione, come il vettore normale. Il variare del vettore normale rendeva il modello come increspato o accidentato (senza modificare la geometria del modello); in altre parole, l'aspetto di una trama. Ma il termine "texture" era già utilizzato per dare il significato a qualcosa di diverso, così questo fu chiamato bump mapping (Blinn, 1978). In seguito divenne chiaro che si potevano anche memorizzare in una mappa piccole variazioni nella posizione della superficie, e mentre questo sarebbe stato chiamato bump mapping - dato che effettivamente aggiungeva irregolarità a una superficie - quell'espressione era comunque in uso, così venne chiamato displacement mapping (Cook, 1984).

Infine, quando divennero comuni le GPU programmabili, la loro texture memory era l'unica struttura dati disponibile indirizzabile casualmente al programmatore, ed era spesso usata per memorizzare array n-dimensionali, puntatori, e altre cose (ovvero, essa era trattata come una memoria ordinaria). Perciò, il particolare significato di "texture" è piuttosto dipendente dal tempo; quando si legge un documento sulla materia, c'è bisogno di sapere quando è stato scritto per sapere cosa il termine sta a indicare.

## Funzionamento

Le texture sono immagini utilizzate per aggiungere dettagli ulteriori all'ombreggiatura di superfici che apparirebbero altrimenti troppo omogenee e artificiali. L'idea è semplice: ogni volta che lo shading viene calcolato, vengono letti i valori utilizzati dalla computazione - il colore diffuso, per esempio - da una texture, invece che usare i valori di attributo che sono connessi alla geometria renderizzata. Questa operazione è conosciuta come texture lookup: il codice dello shading specifica una texture coordinate, un punto nel dominio della texture, e il sistema di texture mapping trova il valore in quel punto nella texture immagine e lo restituisce. Il valore della texture è dopo usato nella computazione dello shading.

### Caso generale

Si consideri una scena con un pavimento ligneo, e si determini che il colore diffuso del pavimento sia controllato da un'immagine che mostra assi del pavimento con una grana lignea. A prescindere che si stia utilizzando il ray tracing o la rasterizzazione, il codice dello shading che calcola il colore per un punto di intersezione raggio-superficie o per un frammento generato dal rasterizer, necessita di sapere il colore della texture nello shading point, in modo da usarlo come colore diffuso nel modello di shading lambertiano.

Per ottenere questo colore, lo shader esegue un texture lookup: comprende la posizione, nel sistema di coordinate della texture immagine, che corrisponde allo shading point, e legge il colore in quel punto nell'immagine, che ci risulta nel texture sample. Quel colore è dopo usato nello shading e, dato che il texture lookup avviene in differenti posizioni nella texture per ogni pixel che vede il pavimento, diviene visibile un pattern di colori differenti nell'immagine. Il codice potrebbe apparire in questo modo:

In questo codice, lo shader chiede alla superficie dove guardare nella texture, e in qualche modo ogni superficie che si desideri ombreggiare usando una texture necessita di essere in grado di rispondere a questa richiesta. Questo porta al primo ingrediente chiave del texture mapping: abbiamo bisogno di una funzione che esegua una mappatura dalla superficie alla texture, che possiamo calcolare facilmente per ogni pixel. Questa è la texture coordinate function, e diremo che essa assegna delle texture coordinates per ogni punto sulla superficie. Matematicamente essa è una mappatura dalla superficie $S$ al dominio della texture, $T$:

${\begin{aligned}\phi &:S\rightarrow T\\&:(x,y,z)\mapsto (u,v)\\\end{aligned}}$

L'insieme $T$, spesso chiamato "texture space", è di solito solo un rettangolo che contiene l'immagine; è comune l'utilizzo del quadrato unitario $(u,v)\in [0,1]^{2}$ (useremo le lettere $u$ e $v$ per le due texture coordinates). La funzione $\phi$ è una mappatura dalla superficie alla texture, quando il nostro obiettivo è inserire la texture sulla superficie, questa tuttavia è la funzione di cui abbiamo bisogno.

Per il caso del pavimento di legno, se il pavimento si trova a essere a una costante $z$ e allineato agli assi $x$ e $y$, possiamo semplicemente usare la mappatura

$u=ax;\quad v=by$

per alcuni fattori di scala appropriatamente scelti $a$ e $b$, per assegnare le texture coordinates $(s,t)$ al punto $(x,y,z)_{\text{floor}}$, e in seguito utilizzare il valore di un texture pixel, o texel, il più vicino a $(u,v)$, come valore della texture in $(x,y)$.

I pixel da visualizzare sullo schermo, calcolati a partire dai texel, verranno in seguito governati dal filtro della texture. Il metodo più veloce è quello di usare l'interpolazione lineare (filtro lineare), ma l'interpolazione bilineare (filtro bilineare) o l'interpolazione trilineare (filtro trilineare) tra MIP map sono quelle più comunemente utilizzate per ridurre l'aliasing, e quindi per aumentare la qualità complessiva dell'immagine. L'applicazione della texture sul modello tridimensionale è compito della scheda video.

