Il legno di un tavolo, i mattoni di un muro, il tessuto di una giacca: nei modelli 3D questi dettagli raramente sono costruiti con la geometria. Sono texture, immagini 2D "avvolte" sulla superficie. L'operazione sembra semplice, ma solleva problemi interessanti: come far corrispondere un'immagine piatta a una superficie curva, e come evitare che quell'immagine sfarfalli o si sfochi quando l'oggetto si allontana o si inclina.
Le coordinate UV
A ogni vertice della mesh si associano, oltre alla posizione 3D, due coordinate (u, v) che indicano un punto dell'immagine. Per convenzione vanno da 0 a 1 su ciascun asse, indipendentemente dalla risoluzione della texture: (0, 0) è un angolo dell'immagine, (1, 1) quello opposto.
Durante il rendering, le coordinate UV vengono interpolate su ogni triangolo, e per ogni pixel la scheda video legge il colore corrispondente. Il pixel di una texture si chiama texel, per distinguerlo dal pixel dello schermo.
Valori fuori dall'intervallo 0–1 sono ammessi, e il comportamento dipende dalla modalità di indirizzamento:
- ripetizione (repeat): la texture si ripete come una piastrella, utile per pavimenti e pareti;
- specchio (mirror): si ripete alternando versioni specchiate;
- blocco al bordo (clamp): i valori oltre il limite usano il texel del bordo.
Lo "srotolamento" UV
Assegnare coordinate UV a un oggetto complesso equivale a srotolarne la superficie su un piano, come si fa con la mappa di un globo o con il cartamodello di un vestito. Una sfera non può essere appiattita senza deformazioni o tagli: lo stesso vale per quasi tutti gli oggetti.
Le scelte da fare sono due, e sono in conflitto:
- Distorsione: se le proporzioni sulla mappa non corrispondono a quelle sulla superficie, la texture appare stirata.
- Cuciture (seam): per ridurre la distorsione si taglia la superficie in più parti (le isole UV), ma lungo i tagli la texture può mostrare discontinuità.
Il buon senso suggerisce di nascondere le cuciture dove si vedono meno: sotto le braccia di un personaggio, sul retro di un oggetto, lungo spigoli naturali.
Densità dei texel
Un concetto pratico importante è la densità dei texel: quanti texel corrispondono a un metro di superficie. Se due oggetti vicini hanno densità molto diverse, uno appare nitido e l'altro sfocato. Mantenere una densità uniforme in una scena è uno dei segni di un lavoro accurato.
Il problema della minificazione
Quando un oggetto è lontano, un singolo pixel dello schermo può coprire decine di texel. Se la scheda video ne leggesse uno solo, a ogni piccolo movimento della telecamera verrebbe scelto un texel diverso: la superficie sfarfallerebbe, con moiré e scintillii. È lo stesso problema di aliasing che si incontra riducendo un'immagine.
Le mipmap
La soluzione classica sono le mipmap: insieme alla texture originale si memorizzano versioni sempre più piccole, ciascuna metà della precedente in ogni dimensione, fino a 1 × 1 texel. Una texture da 1024 × 1024 ha quindi undici livelli.
Durante il rendering, la GPU stima quanti texel cadono in un pixel e sceglie il livello adatto. Le versioni ridotte sono state calcolate in anticipo con un buon filtro, quindi l'aliasing scompare. Il costo in memoria è contenuto: tutti i livelli insieme occupano circa un terzo in più dell'originale.
Filtraggio delle texture
| Metodo | Cosa fa | Effetto |
|---|---|---|
| Vicino più prossimo | legge il texel più vicino | aspetto a blocchi, utile per pixel art |
| Bilineare | media dei 4 texel più vicini in un livello | morbido, ma salti visibili tra livelli mipmap |
| Trilineare | bilineare su due livelli mipmap e media tra i due | transizioni continue |
| Anisotropico | più campioni lungo la direzione di inclinazione | superfici inclinate nitide anche in lontananza |
Il caso tipico in cui si nota la differenza è una strada vista da un'auto: con il solo filtro trilineare, l'asfalto diventa rapidamente una macchia sfocata, perché la GPU sceglie il livello mipmap in base alla direzione più compressa. Il filtraggio anisotropico campiona più volte lungo quella direzione e mantiene leggibili le strisce e i dettagli.
Texture che non sono colori
Una texture è semplicemente una griglia di valori, e può contenere informazioni diverse dal colore:
- mappe di normali: ogni texel memorizza una direzione, che modifica la normale e simula rilievi e solchi senza aggiungere geometria;
- rugosità e metallicità, per i materiali fisici;
- occlusione ambientale, per scurire fessure e angoli;
- mappe di spostamento, che modificano davvero la geometria.
Un punto da ricordare: le texture di colore sono in genere in sRGB, mentre quelle di dati (normali, rugosità) vanno lette come valori lineari. Confondere le due impostazioni produce materiali sbagliati in modo sottile e difficile da diagnosticare.
Compressione delle texture
Le GPU usano formati compressi specifici (famiglie come BCn sui computer e ASTC su molti dispositivi mobili) che permettono di leggere qualunque blocco senza decomprimere l'intera immagine. Sono formati con perdita e a dimensione fissa: riducono molto la memoria occupata, ma un JPEG o un PNG devono comunque essere decompressi e ricompressi in questi formati prima di arrivare alla scheda video.
In sintesi
- Le coordinate UV collegano ogni vertice a un punto della texture, con valori da 0 a 1.
- Srotolare un modello richiede di bilanciare distorsione e cuciture; la densità dei texel va mantenuta uniforme.
- Le mipmap eliminano lo sfarfallio degli oggetti lontani con circa un terzo di memoria in più.
- Il filtraggio anisotropico mantiene nitide le superfici inclinate.
- Le texture di dati vanno lette come lineari, quelle di colore come sRGB.