In questo paragrafo vedremo come completare la definizione dei materiali tramite il fondamentale processo di Texturing, ovvero la tecnica che aumenta il dettaglio dei modelli mediante l’uso di trame o tessiture da “mappare” adeguatamente sulla superficie della mesh. Iniziamo dal base color del Principled Shader per il quale fino ad ora abbiamo impostato un colore RGB uniforme per tutta la superficie. Applicando una texture bitmap (jpg o png) come potete vedere a destra, il motore di rendering andrà a utilizzare i valori rgb/rgba dei singoli pixel dell’immagine caricata nel nodo Image Texture per mappare la superficie del modello (che in tale processo viene suddivisa in dei texture element) ciò ricorrendo a un’interpolazione utile a migliorare la visualizzazione quando la superficie si troverà vicina alla camera. Banalmente possiamo paragonare questa operazione alla posa della carta da parati sulle pareti di casa.
Trattando il Principled Shader abbiamo visto che nella definizione di un materiale la maggior parte dei parametri sono numerici (socket grigi), motivo per cui potremo ricorrere a delle texture che funzioneranno non da mappa colori RGB, ma come mappe d’intensità e utilizzate dal motore di rendering per variare i parametri numerici punto per punto sulla superficie del modello. Con tali Intensity Map, graficamente rappresentate in scala di grigio (256 livelli) otterremo in fretta risultati sorprendenti, come ad esempio quello di alterare l’ombreggiatura delle superfici in modo da simulare la presenza di rilievi (bump) senza dover modificare o aggiungere neanche un vertice alla nostra mesh, semplificandoci così la vita in fase di modellazione. Le principali famiglie di Texture che utilizzeremo in Blender sono quelle procedurali e le immagini bitmap. Le texture procedurali sono immagini generate da algoritmi frattali che restituiscono delle forme più o meno complesse, variabili agendo su alcuni parametri. Il vantaggio principale di tali texture è sicuramente il loro dettaglio molto elevato senza alcuna necessità di archiviare dati su disco rigido, in quanto esse vengono generate e gestite internamente da Blender. Rispetto alle immagini Bitmap, le texture procedurali si adatteranno in modo più semplice e naturale alla forma della mesh e sono native seamless (cioè senza tagli o discontinuità). Un’importante funzione delle texture procedurali è quella di aiutarci a simulare alcune trame esistenti in natura, come le nuvole, le nervature del marmo e del legno, etc. Ognuna di esse sarà rappresentata da un nodo che potremo inserire nello Shader Editor direttamente dal menù Add>Texture.
Di quelle elencate a noi interessano tutte meno: IES, Point Density e White Noise. Applichiamo la texture Voronoi come nella figura in basso. Si tratta di una Texture strutturata a celle un po’ difficile da approcciare per il principiante, simile a un mosaico random, ma che viene impiegata nella realizzazione di parecchi materiali, dai tessuti organici ai metalli grezzi.
Il socket Distance restituisce una scala di grigi da usare come intensity map. Nel nodo potrete scegliere il tipo di struttura reticolare partendo da Euclidean (l’impostazione 3D è tipica per molte texture procedurali). Noterete che l’engine grafico tende a impiegare alcuni istanti prima di visualizzare la texture, poiché questa viene generata dalla cpu, convertita in bitmap e infine mappata nella vista real time. Questa è una caratteristica estremamente importante di Eevee, poiché senza di essa avremmo dovuto fare tutto manualmente tramite un processo di texture baking.
Blender di default mappa le texture utilizzando le coordinate Generated, proprio quelle che impiegheremo principalmente lavorando con le texture procedurali a meno di ricercare particolari effetti. Inseriamo ora i nodi Texture Coordinate e Mapping come nella seguente immagine
Con le coordinate: Window, Reflection e Camera, la mappatura dipenderà dalla posizione della mesh nello spazio o dall’angolo della visuale. Vi basteranno pochi minuti di sperimentazione per capire gli effetti di questi tre sistemi. Generated ha il vantaggio di elaborare la texture restando solidale all’oggetto stesso e mappando in modo soddisfacente le trame procedurali qualunque sia la geometria della mesh. Tramite le coordinate Object potremo indicare un altro oggetto come fonte delle coordinate. Approfondiremo in seguito le coordinate UV parlando delle Texture Bitmap, contesto nel quale divengono utili anche alcune modalità di proiezione (situate nel nodo image). Dopo aver scelto un sistema di coordinate, tramite il nodo mapping potremo traslare ruotare e scalare la texture lungo gli assi x y e z. Proviamo ora ad utilizzare la texture procedurale Musgrave al posto del voronoi nel medesimo schema di nodi visibile in alto.
Musgrave è una trama utile nella simulazione della materia organica con cinque possibili formule frattali (di default troverete fBM fractal Brownian Motion). Nel nodo manca un socket output color (giallo) si tratta infatti di una Intensity Map che va utilizzata in modo differente e per una moltitudine di scopi diversi. Innanzitutto provate ugualmente a collegare il socket output Fac (grigio) a quello input (giallo) del Base Color, e vedrete delle macchie bianco-nere sul modello.
fatto ciò associate mentalmente al colore bianco il valore numerico 1, e al colore nero lo zero. Tutte le tonalità intermedie avranno di conseguenza un valore compreso tra 0 e 1. A questo punto utilizziamo la texture collegando il socket grigio Fac a quelli del medesimo colore del Principled Shader. Ecco l’effetto che si ottiene utilizzando l’intensity map per variare il valore Metallic:
oppure il valore Transmission:
in quest’ultimo caso ho impostato l’IOR ad 1 in modo da avere una trasparenza pura (ricordatevi di attivare screen space reflection + refraction nel contesto render e in quello del material).
Così facendo è possibile rendere una mesh parzialmente riflettente o trasparente (nelle zone prima mappate col bianco) senza dover intervenire sulla struttura del modello stesso. Pensate a quanto sarebbe stato difficile eliminare in modo così preciso le parti trasparenti della mesh, o attribuire solo ad esse un material riflettente.
Con le intensity map potremo aumentare a piacimento la complessità del modello sia mantenendo inalterato il numero di vertici (bump/normal map) sia aumentando a dismisura la definizione della mesh (displacement). Analizziamo il materiale visibile nell’immagine in basso: troviamo la texture Noise collegata al nodo Bump (asperità/protuberanza) che appartiene alla famiglia dei nodi Vector.
Noise è una texture che può essere utilizzata per simulare del rumore casuale, più o meno dettagliato, ma anche delle trame simili alle nuvole. Il nodo possiede in uscita il socket Color (giallo) e il consueto Fac (grigio). Il nodo bump ha tre socket input grigi, dei quali quello che ci interessa è il parametro Altezza, infatti la nostra intensity map (texture noise) è collegata proprio al socket Height. Il nodo bump ha in uscita il solo socket Normal (viola – dati vettoriali) che in questo caso è collegato all’omonimo socket in ingresso del Principled Shader. Nel paragrafo dedicato alla modellazione abbiamo introdotto il concetto di normale, ossia quei vettori ortogonali ad ogni singola faccia della mesh; ebbene in questo modo il processo di shading provvede a variare lungo la superficie l’orientamento della normale in modo da simulare la presenza di rilievi (di qualsiasi dimensione) la cui altezza è data dal valore height indicato dalla nostra intensity map. Alle zone mappate con tonalità più scure (se il valore di Normal in influence è positivo)corrispondono delle rientranze della superficie che avranno massima profondità in corrispondenza del nero (nell’immagine in basso, la mesh suzanne a sinistra). Il nodo bump è dunque utile nel creare piccoli, ma anche significativi rilievi, come nel caso di superfici ruvide, pavimenti, pareti, etc. È bene ricordarsi che in realtà la geometria del modello rimane assolutamente liscia, cosa che si potrebbe notare avvicinandosi al modello da certe angolazioni.
Potete ovviamente sperimentare con le altre texture procedurali e magari combinarle tra loro sfruttando i nodi MixRGB (famiglia Color) per le texture di tipo color, o il nodo Math (famiglia Converter) per le intensity map.
Il Funzionamento del nodo MixRGB è piuttosto semplice, in ingresso abbiamo due socket gialli a cui collegare altrettante texture (sia procedurali, sia immagini bitmap). In sostituzione potremo anche impostare un colore nelle relative aree rettangolari.
Cliccando Mix appare la lista Blend Type, con i vari metodi di fusione che dovrebbero essere noti a chiunque abbia utilizzato un qualsiasi software di foto ritocco. Mix opera una sovrapposizione lineare: al valore zero di fac prevarrà sempre il socket Color1. Potrete anche utilizzare una qualsiasi intensity map per variare il valore fac:
nell’esempio precedente ho collegato la texture procedurale Wave al socket fac del nodo MixRGB, ciò in modo da mixare i colori bianco e marrone secondo la trama della texture. Il risultato è stato infine mappato sul socket Base Color del Principled Shader. Potete facilmente intuire che le combinazioni possibili tra texture e colori sono praticamente infinite. Nell’immagine in basso nella pagina potete vedere come combinare due intensity map tramite il nodo Math. Il nodo è settato di default su Add, per cui esso procede a sommare i valori in ingresso dei socket Value. Il socket Value in uscita è collegato al socket Fac del nodo MixRGB. Quindi stavolta non sarà la sola texture Wave usata in precedenza a regolare il mix dei colori rgb, ma la combinazione di essa con l’intensity map Musgrave.
Nel sommare due valori che variano da 0 a 1, è ovviamente possibile arrivare a un massimo di due. Di conseguenza potremo ‘normalizzare’ le operazioni compiute dal nodo map in modo da non uscire mai dall’intervallo 0-1, semplicemente attivando la casella Clamp. Oltre alla somma ci sono molte altre operazioni che il nodo Math può eseguire:
Passiamo ora all’importantissimo uso delle texture Bitmap che possiamo suddividere in due categorie:
- Immagini seamless (tile, pattern, etc), le quali ripetendosi copriranno una superficie grande a piacere.
- Immagini che necessitano una mappatura sul modello secondo le regole dell’UV Mapping.
Un’immagine seamless è tale che se applicata in modo ripetuto e affiancato su una qualsiasi superficie, essa non presenterà alcun segno di stacco o di giuntura. Nell’applicare una texture bitmap seamless potremo ricorrere alle coordinate di mappatura Generated, ma dovremo fornire qualche informazione di più al software, ad esempio indicando le proiezioni da impiegare nel processo di mapping. Nell’esempio seguente e per tutte le forme del modello approssimativamente cubiche (ricche di spigoli) andremo a indicare Box nel terzo selettore del nodo Image Texture
L’impostazione di default è Flat ottima per tutte le superfici piane aperte e curve, dopodiché troviamo le proiezioni Tube (per superfici curve chiuse simili a quelle cilindriche) e Sphere (per modelli assimilabili a delle sfere).
Vediamo il set completo di nodi utilizzati
In tutto abbiamo quattro nodi Image Texture per altrettante trame, di cui la prima (rgb) è collegata al base color, la seconda (bianco e nero) al socket specular, la terza al socket roughness (bianco e nero), e infine la normal map. Soffermiamoci su quest’ultima che come potete vedere è collegata al nodo Normal Map. Nel cubo infatti vi sono delle scanalature tra i mattoni che evee ha ombreggiato come se queste fossero realmente modellate. Molte textures reperibili in rete includono le cosiddette normal map. Esistono inoltre diversi software per generare texture e relative normal map, sia commerciali, sia open source.
Vediamo dunque come è fatta una normal map:
Quando applichiamo al materiale una normal map come questa, accade qualcosa di molto simile a quanto visto in precedenza con il nodo Bump. Il motore grafico determinerà l’ombreggiatura della superficie come se i suoi “punti” (chiamati Texel, cioè i “pixel” del processo di Texturing) avessero una normale diversa rispetto a quella ortogonale alla superficie, simulando così in modo realistico la presenza di piccoli e medi rilievi. Le normali utili a tal scopo vengono derivate dai valori RGB dei pixel della normal map e, trattandosi di vettori tridimensionali, occorrono tre componenti:
- Al canale Red (0 – 255)
componente X(-1,0 -1,0) - Al canale Green (0 – 255)
componente Y(-1,0 – 1,0) - Al canale Blu (0 – 255)
componente Z (0,0 – 1,0)
Z non possiede dunque valori negativi (cioè normali rivolte verso l’interno del modello) da qui il motivo per cui le normal map sono immagini bitmap dal colore prevalentemente bluastro. Ad ogni modo tali considerazione tecniche non ci interessano più di tanto e una volta che imparerete a ottenere le normal map desiderate, o a crearle con appositi software (di cui molti Free), il loro utilizzo come già visto sarà molto semplice. Quando scaricherete delle texture PBR, la maggior parte delle volte troverete dei pacchetti compressi contenenti le seguenti immagini a colori (rgb) e in Bianco e Nero (bw):
- diffuse map (rgb – base color)
- specular map (bw -intensity map)
- roughness (bw – intensity map)
- normal map (rgb)
- displacement (bw – intensity map)
Vedremo in azione le displacement map con Cycles in quanto tramite esse l’engine non si limiterà a modificare l’ombreggiatura, ma provvederà ad aumentare il dettaglio poligonale delle superfici. Le intensity map, essendo delle immagini in bianco e nero, non necessitano di una correzione gamma, per tanto nel nodo Texture occorre impostare Non-Color in Color Space al posto del profilo sRGB di default (stessa scelta vale per le normal map sebbene si tratti di immagini rgb)
Paragrafo successivo
Paragrafo precedente
Torna all’Indice
Nell’augurarti un divertente e produttivo studio di Blender, ti ricordo che puoi supportare questo progetto in due diversi modi: con una piccola donazione (paypal) oppure acquistando la versione PDF (su lulu.com) impaginata in modo professionale e ottimizzata per la visione su Tablet.