Davide Pesare Natural Shaders Tesi di Laurea – corso di laurea specialistica in Realtà Virtuale e Multimedialità Università degli studi di Torino – Facoltà di Scienze M.F.N. Anno accademico 2003-2004 – sessione di Luglio Relatore: prof. Albert Werbrouck Controrelatore: prof. Nello Balossino Introduzione Al termine di un piano di studi prettamente interdisciplinare quale è il corso di laurea specialistica in “realtà virtuale e multimedialità”, presento in questa sessione una tesi caratterizzata dalla stessa interdisciplinarità. Si tratteranno argomenti fondamentalmente informatici, che però hanno subìto una profonda influenza da parte degli studi tecnici ed artistici che ho affrontato in ambito accademico e professionale. In particolare lavorare come artista 3d in una software house di videogiochi, ed in seguito come technical director in una casa discografica mi ha chiaramente mostrato quali possano essere le esigenze di chi non è un informatico, nell’uso di strumenti avanzati quali i pacchetti 3d in commercio. La mia prima tesi, al termine della laurea triennale, trattava di tecniche di modellazione, animazione e texturing 3D. Nella sua conclusione avevo annunciato che avrei proseguito gli studi nello stesso campo ed approfondito le tematiche della programmazione 3D, non limitandomi come allora a linguaggi di scripting, ma 2 affidandomi a più potenti e complessi strumenti, quali le API di windows e di 3dsMax. Il risultato di tale approfondimento è questa tesi, dedicata alla teoria del rendering, dei materiali e delle mappe procedurali, e soprattutto della scrittura degli shader. La concretizzazione di questa teoria è stata in questi mesi lo sviluppo, sulla piattaforma 3dsMax, ma per diversi renderizzatori, di materiali (detti comunemente shader) fotorealistici che rispondessero ai requisiti di: • facilità d’uso ed immediatezza per gli artisti meno esperti • alta flessibilità e personalizzabilità per gli “shading TD” più esperti • alta qualità e realismo nel rendering, a qualsiasi livello di dettaglio • massima integrazione nell’ambiente del pacchetto software usato • prestazioni in termini di tempo migliori rispetto a risultati paragonabili, ottenibili con gli strumenti di base di Max Si tratta di una plug-in, perfettamente integrata nel celebre pacchetto 3d, che si chiama Natural:shaders, e comprende sei materiali studiati per rappresentare altrettanti fenomeni naturali, e rientra in un disegno più grande, denominato SHADarts che comprende altri tre pacchetti: Industrial:shaders ed Artistic:shaders. I sei materiali sono: 1. natural:Sand. Per la ricostruzione di spiagge e deserti 2. natural:Snow. Per la simulazione di paesaggi innevati 3. natural:Rock. Per riprodurre alcuni tipi di rocce e minerali 4. natural:Sea. Per rappresentare il mare e gli oceani 5. natural:Magma. Per modellare colate laviche in via di raffreddamento 6. natural:Ice. Per ricostruire l’aspetto di iceberg nel mare e di pareti di ghiaccio 3 In questa trattazione si toccheranno molti argomenti chiave. Si vedrà la pipeline di lavorazione e produzione 3d, in particolare per le produzioni non interattive, quali il cinema e la pubblicità. Si vedrà dove si collocano le varie professionalità, tra cui quella dello shaderwriting, al centro di questa tesi. Si passerà poi ad un breve riassunto sulla teoria e sulla evoluzione nella storia del rendering. Sarà spiegato cosa è un renderer, e perché è oggi disgiunto dagli shader stessi. Si vedranno le texture procedurali, una frontiera ancora aperta alla ricerca di matematici, fisici e informatici. Si vedrà poi la implementazione attuale dei materiali su 3dsMax, e le sue differenze rispetto ad altri pacchetti software. Verranno visti in dettaglio tutti gli shader componenti Natural:Shaders, le loro problematiche e le loro qualità. Ci sarà una attenzione particolare alle interfacce utente, diverse in approccio rispetto a quelle di 3dsMax. Si vedrà brevemente il meccanismo di licenza della plugin, integrato anch’esso in 3dsMax senza disturbarne il funzionamento. Infine ci sarà una breve illustrazione sul futuro delle produzioni in computer grafica e della scrittura di shaders. Il progetto è stato sviluppato in C++, utilizzando le API di 3dsMax e della piattaforma Windows. Il sistema di licenza ha avuto bisogno di alcune utility disgiunte, sviluppate in Visual Basic ed in MaxScript (linguaggio di scripting integrato in 3dsMax). Per la licenza, la request utility è stata sviluppata da Alessandro Cangelosi. Parte dello sviluppo di Natural:ice è stato integrato da Davide De Conti. Le bozze delle shading network da cui è partito lo sviluppo sono state curate, oltre che da me, da Alessandro Cangelosi e da Filippo Pierdicca. 4 1. La pipeline di lavorazione 3d nei Visual FX In questo capitolo si tratta la pipeline di lavorazione di prodotti in computer grafica prettamente 3d, ad alta qualità e non interattiva. Quindi non si tratta di realtà virtuale. Il campo di applicazione di questi prodotti spazia dalla pubblicità al cinema alle produzioni multimediali scientifiche o di intrattenimento. Per prima cosa va sottolineato che difficilmente si troveranno due case di produzione con la stessa pipeline lavorativa. Questo è dovuto ai gusti dei dirigenti, alle competenze presenti nelle risorse umane, al tipo di tecnologie di cui si dispone, fino anche alla organizzazione fisica e geografica della azienda. Per questa ragione la pipeline che spiegherò non è da vedere come l’unico modello valido, ma uno dei modelli in uso. In particolare ho fatto riferimento alla pipeline in uso presso la Weta Workshop e la Weta Digital per “Il Ritorno del Re” ed a quella della Square Pictures, usata “Final Fantasy”. 5 Si noti che delle fasi elencate nessuna è disgiunta dalle altre. A produzione avanzata si può cambiare un personaggio con un altro, e cambiare perfino lo storyboard, così come le esigenze di illuminazione di un elemento nella scena ne potrebbero richedere la sua rimodellazione. Figura 1.1. Storyboarding La prima fase è quella di definire un tema ed una storia. A questo ci pensano il regista, l’autore ed i loro assistenti. Appena si hanno in piedi un po’ di idee si mettono al lavoro numerosi artisti “tradizionali”: fumettisti, disegnatori, concept artists. A loro si affida il look dei personaggi, delle ambientazioni, secondo i dettami del regista. A loro si fa preparare lo storyboard. Uno storyboard è un modo per pianificare una storia digitale in due dimensioni. La prima dimensione è il tempo: cosa succede prima, e cosa succede dopo. La seconda dimensione è l’interazione: come interagisce la storia con le immagini? Come aiutano le transizioni visive e gli effetti a legare le immagini? Ogni elemento può interagire con ogni altro, e lo storyboard è il luogo per pianificare l’impatto che si vuole avere sul pubblico. 6 Figura 1.2. Animatic Subito dopo si ha la creazione di un animatic, o storyboard in 3d che ha il vantaggio di contenere già le tempistiche ed i movimenti di camera abbozzati per avere una idea più chiara di come realizzare gli shot. Attualmente ci sono aziende di effetti speciali che si dedicano alla produzione di animatic, tramite lo sviluppo di software di previsualizzazione. Un esempio è la Pixel Liberation Front, che oltre a produrre effetti speciali, ha un reparto dedicato alla previsualizzazione, che viene usato anche per dare consulenza ad altre case di produzione. Figura 1.3. Modellazione 7 Contemporaneamente il reparto di modellazione inizia i lavori, realizzando ogni parte richiesta nella produzione. Gli artisti sono divisi in gruppi a seconda della loro specializzazione: personaggi, scenari, accessori. Ogni produzione affronta il problema a modo suo. Se per la Square Pictures tutti i modelli sono stati prodotti direttamente in 3D, alla Weta sono stati costruiti prima in creta o in plastilina, e poi in silicone, per poi modellarli in 3d su Maya (Alias) prima e rifinirli su ZBrush (Pixologic) dopo. Infine alla BlueSky studios, sopra i modelli in creta sono state direttamente disegnate le linee del wireframe e, una volta scannerizzati, i modelli erano già pronti per gli ultimi ritocchi. Non è raro ricorrere alla modellazione procedurale o a quella basata su immagini quando il lavoro è tanto e il tempo poco. In certe situazioni si preferisce perfino ricorrere alle tecniche tradizionali: modelli in scala fatti di plastilina, dipinti a mano da artisti dedicati e poi ripresi da cineprese, pronti per essere composti con gli effetti speciali. E’ questo il caso della città di “Minas Tyrith” in “Il ritorno del re”. Figura 1.4 Rigging Accanto ai modellatori, i character TDs (technical directors) preparano il rigging dei personaggi e degli oggetti per facilitare e aumentare le possibilità espressive degli animatori. Il character setup (o rigging) è una fase cruciale, in quanto 8 crea tutti gli strumenti che l’animatore avrà a disposizione. Se gli strumenti sono inadeguati i personaggi risulteranno difficili da animare come se fossero di legno, o di plastica. Un buon rigging per contro permetterà di dare dell’espressività eccezionale. Questo è di particolare importanza nelle produzioni non fotorealistiche, dove i personaggi digitali hanno un design “cartoon” e hanno bisogno di esagerare le proprie espressioni oltre i tipici limiti umani. Normalmente prima di iniziare una produzione in Computer Grafica si sceglie e si acquista o si sviluppa un motore di rendering adatto alle necessità. Lo sviluppo degli shader, o shaderwriting, si basa infatti sul linguaggio accettato dal particolare motore di rendering. Questa è una fase cruciale. Chi scrive gli shader (shaderwriter o shading TD) deve avere notevoli competenze informatiche, ma anche nei campi più vari di ottica, estetica, fisica, ecc… Il “look” di un film si deve in gran parte al talento impalpabile di chi ha scritto il software che gestisce e genera i materiali e le texture. Per scrivere un singolo shader può essere necessaria una settimana come poche ore. L’italiano Guido Quaroni, R&D Shading Group Lead alla Pixar, racconta di quanto uno shader di base, usato per la produzione di tutti gli altri, possa effettivamente dare una impronta ad un film, come ha fatto con “Finding Nemo”. Figura 1.5 Esempio di shader in "Alla Ricerca di Nemo" 9 Non bisogna confondere gli shaderwriter con chi disegna poi le texture, ovvero i Texture Artist. Questi sono gli artisti che con tavolette grafiche o strumenti ancora più avanzati, usando programmi appositi di disegno 2D, come Photoshop (Adobe) producono le texture usate dai materiali preparati dagli shaderwriter, per creare dei materiali completi, fotorealistici o surreali, a scelta del regista. Gli stessi strumenti vengono usati anche dai Matte Artist, che invece di produrre texture producono sfondi, spesso riccamente miscelati con elementi 3d renderizzati e poi ritoccati. A lavorare al fianco degli shaderwriter c’è lo staff dei Lighting TD. A loro spetta dapprima illuminare le scene al massimo per vedere gli errori di modellazione. In seguito cercano di creare l’illuminazione più adatta al singolo shot o alla singola scena. Sebbene le tecnologie di illuminazione globale fotorealistica e fisicamente corretta progrediscano rapidamente, spesso i lighting TD preferiscono affidarsi ad un approccio più tradizionale. Cioè posizionano e regolano tutte le luci a mano e disattivano i fenomeni di radiosità. Questo approccio, se è meno corretto fisicamente, permette di ottenere illuminazioni più espressive, che sottolineino o nascondano gli aspetti che vuole il regista. A volte le leggi fisiche vengono del tutto stravolte. Le traiettorie dei fotoni si piegano, le riflessioni convesse funzionano come fossero concave. Le ombre sono del tutto inventate. Ma questo non è un problema fino a quando il pubblico non se ne accorge, e fino a quando questi trucchi servono ai fini della narrazione. Altre volte questi trucchi sono utilizzati solo per accelerare i tempi di calcolo. Una delle sfide più grandi è l’illuminazione dell’incarnato dei personaggi, per fare in modo che appaia realistico. I personaggi sono di gran lunga la cosa più ardua da illuminare. Il metallo e la plastica sono molto più semplici dell’incarnato, perché esso possiede grandi proprietà di traslucenza e semitrasparenza come del resto anche i capelli. Si deve lavorare molto da vicino col dipartimento dei personaggi che fornisce gli shader per le superfici. Ci potrebbero essere aggiustamenti ad hoc per ciascuna ripresa. Dopo una prima sessione di doppiaggio da voci reali, viene la fase più lunga e laboriosa: l’animazione. Basandosi sugli animatic (anche essi prodotti da talentuosi 10 colleghi) e sulle voci registrate, gli animatori producono gli shot, uno a uno, utilizzando i rigging preparato per loro, e cercando di adeguarsi quando si deve miscelare l’animazione in computer grafica con scene riprese dal vivo. Talvolta per migliorare il realismo dei personaggi la prima fase di animazione è realizzata in Motion Capture. Questa tecnica, che da sola meriterebbe molto più di questa tesi per parlarne esaurientemente, permette di “catturare” i movimenti degli attori e di trasferirli sui personaggi. A partire da questi movimenti, gli animatori arricchiscono le animazioni correggendo i dati catturati ed aggiungendo i movimenti che non possono essere catturati adeguatamente (le piccole ossa come le dita o le espressioni facciali) con gli strumenti attuali. Figura 1.6 Motion Capturing Esiste poi tutta una sezione composta da varie figure professionali (TD, animatori, sviluppatori…) che si occupa degli effetti speciali propriamente detti: esplosioni, illusioni, scontri, e tutto ciò che rende spettacolare una pellicola e che non si può – o non conviene – riprendere dal vivo. Spesso si riconduce a questo staff anche l’animazione di masse di “comparse” digitali, cui si dedicano i programmatori per creare le cosiddette animazioni procedurali, che si basano su nozioni di fisica e di intelligenza artificiale. Si ha poi la fase di rendering. Questa fase viene eseguita interamente dai computer, ma le scene vengono pianificate e suddivise in layer prima di essere 11 mandate in rendering. Viene quindi la fase di compositing, che secondo molti professionisti è in grado di salvare o distruggere un film intero. I singoli layer renderizzati vengono passati separatamente ai compositor. Il layer di fondo spesso non è una immagine 3D. Gli scenari più lontani sono dipinti “manualmente” su computer, cioè si usano i Matte Painting descritti in precedenza. Spesso mettere insieme tutte le caratteristiche CG richiede più potenza artistica di quanta sia necessaria per un film dal vivo. Quando si lavora ad un film dal vivo, si prende la pellicola e si sa di ogni cosa quale colore necessita dal momento che risulta essere stato definito dal dipartimento di illuminazione.. Si sa che il cielo è blu, l’erba verde e così via. Ma in un mondo fantastico e virtuale, la prima volta che il layer e l’effetto finale vengono realmente messi insieme, è nella fase di compositing. Per cui è necessario che l’addetto al compositing concettualizzi ed immagini l’intera sequenza per poter prendere diverse decisioni artistiche. Gli addetti al compositing sono anche responsabili dell’eliminazione di errori non evidenti fino a tale stadio finale. Realizzano di tutto, dalla sistemazione della CG all’inserimento di key-light, alla creazione di elementi. Tirano fuori capelli dal mento del personaggio o da qualunque altro posto dove non era prevista la loro presenza. Correggono anche gli errori di ombre e adeguano il bilanciamento della pelle contro altre caratteristiche dei visi. Scovano punti nei personaggi dove risulta che l’interno delle narici od il bianco degli occhi appaia troppo brillante; mescolano il colore con quanto presente dietro facendo in modo che si adatti al meglio. Le sequenze composte vengono infine messe insieme in shot, quindi assemblate in sequenze più lunghe dal regista e dal tecnico del montaggio. Infine vengono le sessioni di registrazione della colonna sonora e dei suoni, ed il secondo doppiaggio, quello finale. Come si vede, le fasi descritte non sono compartimenti stagni e interagiscono pesantemente fra loro. Sono tutte vitali per il successo di una pellicola o di una produzione CG in generale. Ci concentreremo in questa tesi sulla figura dello shaderwriter. 12 2. Teoria del rendering. 2.1. Geometria Uno shaderwriter deve avere le idee molto chiare su come funziona la geometria e la matematica utilizzate nel processo di rendering. In questi paragrafi si farà un breve ripasso della teoria sottostante. 2.1.1. Equazioni primitive Le curve e le superfici che sono usate in computer grafica sono tutte derivate da vari tipi di equazioni matematiche. Inserendo valori nelle variabili delle equazioni, esse identificano quali punti sono sull’oggetto e quali no. Ci sono tre tipi di equazioni 13 che forniscono la base della maggior parte delle primitive in computer grafica: esplicite, implicite e parametriche. Una equazione esplicita è una equazione che valuta una coordinata della posizione dal valore delle altre coordinate. Per esempio, z = 2x + y è l’equazione esplicita di un piano. Una delle caratteristiche dell’equazione esplicita, è che matematicamente è una funzione, il che significa che ha un solo risultato per ogni insieme di coordinate di input. Questo significa che non può ripiegare su se stessa, come fa per esempio una circonferenza. In un’equazione implicita certi valori di input soddisfano una equazione del tipo: surface(x,y,z) = 0; I punti che soddisfano l’equazione sono sulla primitiva, mentre gli altri non lo sono. Per esempio x2 + y2 + z2 – 1 = 0 è l’equazione implicita di una sfera. Il punto (0.6,0,0.8) è sulla sfera perché soddisfa l’equazione, mentre il punto (0.4,0.8,0.2) non lo è. I punti che sono generati da equazioni implicite complesse non sono sempre connessi – ci possono essere piccole regioni isolate che soddisfino l’equazione. Questo rende difficoltoso trovarli tutti. Una superficie parametrica è una superficie generata da una equazione con due variabili: P=surface(u,v). Per esempio, una sfera può essere generata dalle equazioni parametriche x = cos(alpha)cos(beta) y = sin(alpha)cos(beta) z = sin(beta) Altre preziose superfici parametriche comprendono i piani, tutte le superfici quadratiche, bilineari e bicubiche, e le NURBS. In generale, non si è interessati in superfici parametriche infinite, ma in loro sottoinsiemi, che sono generati ponendo dei limiti ai parametri, tipicamente tra 0.0 e 1.0. Si noti che è semplice riparametrizzare le equazioni con altri limiti parametrici, con una semplice sostituzione di variabili, così che questa scelta non causa nessuna 14 restrizione reale. Per esempio, invece di avere la sfera nelle precedenti equazioni parametrizzate per alpha tra 0 e 2Pi e beta tra –Pi/2 e Pi/2, possiamo cambiare le equazioni in questo modo: x = cos(2Pi u) cos(Pi v – Pi/2), per valori di u e v tra 0 e 1. Alcune superfici, come le sfere, possono essere definite sia implicitamente sia parametricamente, ma la maggior parte delle equazioni parametriche non sono facilmente “implicitizzabili”. Le superfici parametriche hanno due proprietà interessanti che le rendono utili nella computer grafica. Primo, poiché l’equazione parametrica può essere calcolata direttamente, si può computare qualsiasi punto sull’oggetto assegnando dei valori ai parametri. E’ facile generare alcuni punti che sono sulla superficie e poi approssimare il resto della superficie con approssimazione lineare. Questa tecnica si chiama tassellazione. Secondo, poiché si ha un’equazione che mappa una coppia 2D di coordinate parametriche nel 3D, la superficie ha un sistema di coordinate 2D naturale. Questo rende facile mappare altri dati 2D sulla superficie. Il più ovvio di questi dati è una texture. 2.1.2. Tangenti e Normali Avere delle equazioni matematiche per le nostre primitive geometriche ci permette di usare i meccanismi della geometria analitica e l’analisi matematica per calcolare proprietà importanti delle equazioni, che a loro volta sono proprietà importanti delle primitive geometriche. Due delle più importanti di queste sono le tangenti e le normali. La tangente di un punto su un oggetto è un “oggetto piatto” che semplicemente tocca l’oggetto in quel punto ma non lo interseca né lo penetra, almeno non nelle immediate vicinanze di quel punto. In due dimensioni, la tangente a una curva è una linea ed è unica. Generalmente non si è interessati nella tangente di per se, ma in un vettore direzione che ha la stessa direzione. Questo vettore si definisce vettore 15 tangente. Il valore della direzione è calcolato valutando la derivata della curva in quel punto, una operazione generalmente semplice se abbiamo una equazione parametrica della curva. In tre dimensioni, la tangente a una superficie è un piano ed è unico. Ogni vettore che giace sul piano tangente è tangente alla superficie, perciò ci sono infiniti vettori tangenti, uscenti dal punto a tutte le direzioni del piano. Generalmente, è abbastanza facile trovare due vettori tangenti: si prendono le derivate parziali della superficie rispetto ai due parametri. Un altro concetto importante (che è probabilmente ovvio se ci si pensa su un attimo) è che c’è una unica direzione che è perpendicolare, o normale, a un piano. Questo vettore unico è detto vettore normale del piano. Di particolare interesse è il vettore normale al piano tangente ad un punto particolare sulla superficie. Questo vettore sarà detto normale del punto, e sarà denotato con N. Questa relazione tra piani e normali significa che si può derivare l’uno dall’altro. Ogni vettore perpendicolare alla normale deve essere nel piano tangente, mentre la normale è perpendicolare a tutto i vettori nel piano tangente. Ci vogliono due vettori per definire un piano (per esempio le derivate parziali che definiscono il piano tangente), così l’unico vettore perpendicolare ad entrambi i vettori deve essere la normale al piano. Vale a dire il prodotto vettoriale delle due derivate. Viceversa, se si ha un vettore normale ad un punto, si sa immediatamente il piano tangente in quel punto. 2.1.3. Curvatura Il concetto successivo oltre la tangente ad un punto è la curvatura. Come la tangente misura la direzione di una linea che tocca l’oggetto senza intersecarlo localmente, la curvatura misura il raggio di una circonferenza che tocca l’oggetto senza intersecarlo. Se la circonferenza è molto piccola, la superficie ha una alta 16 curvatura; se viceversa è molto grande, la superficie ha piccola curvatura. Come ci si può aspettare, la curvatura è calcolata usando le derivate seconde della superficie nel punto considerato. Si noti che la curvatura è una quantità con segno. Una curvatura positiva indica che la superficie curva verso la normale, a forma di coppa. Una curvatura negativa significa che la superficie si allontana dalla normale, come un ombrello aperto dalla sua punta. Una curvatura nulla indica una superficie piatta. Così come ci sono infiniti vettori tangenti ad un punto su una superficie, così ci sono infinite curvature, corrispondenti a tutte le circonferenze orientate a diversi angoli intorno al punto. Di queste, alcune in particolare sono degne di nota. Su una superficie parametrica le curvature nelle due direzioni parametriche sono interessanti perché facili da calcolare. Comunque, questi valori non sono necessariamente i “più curvati” della superficie nel punto. Se si vogliono ottenere questi, dobbiamo calcolare le curvature principali k-max e k-min. Nella maggior parte delle superfici, i due valori hanno lo stesso segno, oppure uno di loro è nullo. Se i segni sono differenti le superfici si dicono a “sella”. 2.1.4. Continuità Quando due primitive con diverse equazioni sono posizionate a contatto fra loro, concettualmente unite per essere parte dello stesso oggetto, si è spesso toccati dal problema della continuità della giunzione. Il tipo di continuità che esiste alla giunzione determina se la giunzione si può dire “morbida” o “smooth”. Ci sono quattro tipi di continuità che sono di interesse: • C0: la superficie è connessa ma potrebbe avere degli angoli. • C1: la prima derivata non ha discontinuità. Ma potrebbe avere dei cambi bruschi di curvatura. • C2: la derivata seconda, o curvatura, non ha discontinuità. La superficie appare “smooth” 17 • C∞: nessuna derivata ha discontinuità. La superficie è matematicamente continua. Per esempio, quando due poligoni hanno in comune un bordo ma c’è un angolo fra loro, la giunzione ha un angolo, e perciò la superficie è C1 continua al bordo ma non è C2 continua. 2.2. Fisica ed Ottica Molti algoritmi nella computer grafica, in particolare quelli di shading, si affidano alla simulazione di vari aspetti della fisica dei materiali e della luce per ottenere il loro realismo. Talvolta le proprietà fisiche sono duplicate esattamente, talvolta sono approssimate, spesso però sono ignorate interamente e rimpiazzate da regole inventate ad hoc. 2.2.1. Lo spettro luminoso La luce visibile è un’onda di energia elettromagnetica dentro un certo intervallo di lunghezze d’onda (dai 380 nanometri ai 750 nanometri, ovvero dai 790 ai 400 teraHertz). Infatti, la maggior parte delle forme di luce visibile contengono un continuum di frequenze, ciascuna a differenti intensità. Questa funzione di intensità a varie frequenze è detta “spettro” della luce. Ogni lunghezza d’onda corrisponde a un colore nell’arcobaleno, e i raggi di luce che sono dominati da un colore particolare appaiono alla vista di quel colore. I raggi di luce che hanno uno spettro simile a quello della luce solare, sostanzialmente piatti su un ampio intervallo di colori ma in qualche modo dominati dai colori vicini ai 530 nm (verde), appaiono bianchi alla vista, e sono detti “luce bianca”. 18 La maggior parte delle interazioni tra la luce ed i materiali sono dipendenti dalla lunghezza d’onda, il che significa che hanno diversi effetti su luci di diversa lunghezza d’onda. Per esempio, la rifrazione attraverso un prisma separa la luce in un arcobaleno di colori perché la direzione della rifrazione della luce dipende dalla lunghezza d’onda del raggio stesso. Le lunghezze d’onda blu sono rifratte più di quelle rosse. Quando si guarda ad un oggetto, si vede lo spettro della luce che è riflessa da quell’oggetto. Il colore della superficie dell’oggetto è dovuto al fatto che ogni materiale assorbe più luce a certe lunghezze d’onda e riflette più luce ad altre lunghezze d’onda. Questo processo, dove il colore è determinato dalla luce risultante, dopo che certe porzioni dello spettro sono state rimosse, si chiama colore sottrattivo. Il filtraggio della luce trasmessa è un altro esempio di un processo sottrattivo. Il colore di un filtro come un pezzo di vetro colorato, è principalmente basato sullo spettro che rimane, dopo che la luce passata attraverso è stata filtrata. Un filtro rosso è quel filtro che assorbe la maggior parte di tutto lo spettro, tranne il rosso. Il processo complementare, dove la luce è determinata sommando insieme i contributi di diverse sorgenti luminose colorate, è detto colore additivo. I monitor e le televisioni sono un esempio di processo additivo. Il colore su un monitor è la somma degli spettri che il fosforo emette (in realtà, questa è una situazione piuttosto complessa, dovuta a una sottile interazione con il nostro sistema di visione). 2.2.2. Riflessione e Rifrazione Quando la luce viene riflessa da una superficie specchiante, la direzione del raggio riflesso è facilmente calcolabile grazie alla ben nota massima che “l’angolo di riflessione è uguale all’angolo di incidenza”. Questa relazione è mostrata nella figura 2.1. Distillando questa relazione in una equazione, si approfitta del fatto che il vettore normale descrive il piano riflettente. 19 Figura 2.1 Calcolo dei vettori di riflessione Guardando alle relazioni dei vettori nella figura, è piuttosto facile da dire, solo guardando, che il vettore di riflessione può essere calcolato con R = I+2(αN) per qualche costante α. Richiamando un po’ di trigonometria, ed assumendo i vettori N e I normalizzati, si vede che cos(θ) = α/1.0. Ma ricordando la regola del prodotto scalare, si può affermare che α = (-I · N). Con un po’ di algebra, si conclude che R = I -2(I ·N)N. Si scopre che l’equazione è la stessa anche se I non è normalizzato, mentre è un po’ più complessa se N non lo è. Quando la luce si rifrange attraverso una superficie trasparente, la direzione del vettore rifratto è computata usando l’equazione ben nota, detta Legge di Snell. Questa legge specifica come la luce è piegata usando gli indici di rifrazione del materiale che la luce sta abbandonando e del materiale in cui la luce sta entrando. L’indice di rifrazione di un materiale, normalmente denotato con η (eta), è una costante fisica del materiale e può essere cercata in libri di riferimento di fisica. Per i materiali più comuni, l’indice di rifrazione è compreso tra 1 e circa 2.4. In parole semplici, quando la luce entra in un materiale che è più denso, è piegata verso la normale della superficie; mentre quando entra in un materiale meno denso, è piegata via dalla normale. L’equazione corretta è: ηleavesin(θleave) = ηentersin(θenter), dove θ è l’angolo tra la normale alla superficie ed il raggio di luce su quel lato. 20 Ci sono diverse importanti sottigliezze a proposito della rifrazione che uno shaderwriter deve conoscere. Primo, l’indice di rifrazione del materiale è in realtà dipendente dalla lunghezza d’onda. Questo significa che mentre la luce viaggia attraverso il materiale, alcuni colori vengono deviati più di altri. Per alcuni materiali questo effetto è trascurabile, ma per altri è piuttosto evidente. I prismi infatti lavorano in questo modo. Figura 2.2 Vettori di rifrazione Secondo, quando la luce colpisce un oggetto, non importa quanto possa essere pulito, non tutta entra interamente nel materiale. Un po’ di luce è assorbita, naturalmente, ma un po’ è anche riflessa. L’equazione di Fresnel ci dice l’intensità della luce che passerà attraverso, e l’intensità che verrà riflessa dalla superficie. L’equazione di Fresnel dipende pesantemente dall’angolazione della luce in entrata, perché la luce che colpisce perpendicolarmente la superficie verrà fortemente trasmessa, mentre la luce che colpisce molto di sbieco, verrà fortemente riflessa. Terzo, è interessante considerare la seguente situazione. La luce è dentro il materiale denso, e si avvicina al confine ad un angolo molto vicino al parallelismo con il confine stesso. Poiché la rifrazione piega la luce perfino più di quanto sia già distante dalla normale alla superficie, l’equazione di Snell implica che l’angolo di rifrazione potrebbe superare i 90 gradi. Questo significa che il vettore di luce rifratta 21 rimarrebbe dentro l’oggetto più denso. Questa non sarebbe rifrazione, naturalmente, così la luce rifiuta di andare in quella direzione. La rifrazione semplicemente non avviene, e la luce è invece interamente riflessa. Questa situazione è nota come “riflessione interna totale”, e le fibre ottiche la sfruttano per minimizzare la dispersione di energia sulle lunghe distanze. E’ anche utile notare che se la luce passa attraverso un solido piatto con i confini paralleli (ad esempio un pannello di vetro), la direzione finale della luce sul lato lontano sarà la stessa di quella originale. La luce viene deviata di lato e dopo viene deviata esattamente come prima, e l’unica differenza è che i raggi risultano spostati lateralmente. 2.2.3. Interazione della luce con le superfici Quando la luce colpisce la superficie di un oggetto, una qualche porzione della luce è assorbita dall’oggetto, e una altra porzione è riflessa in varie direzioni. Lo spettro che viene riflesso con più forza è visto come il colore dell’oggetto. Le direzioni ed i colori esatti della riflessione dipendono da molti fattori, come la direzione della luce in entrata, la struttura chimica ed elettrica del materiale, la geometria macroscopica e microscopica della superficie, e perfino gli effetti fisici, come la diffrazione e l’interferenza. I materiali che appaiono lisci tendono a riflettere la luce principalmente nella direzione del vettore di riflessione, ed a non rifletterne nelle altre direzioni. I materiali che appaiono più opachi o ruvidi tendono a riflettere luce in un ampio intervallo di direzioni. I materiali trasparenti, come la plastica ed il vetro, rifrangono un po’ di luce basandosi sulle equazioni di Fresnel. I materiali iridescenti riflettono colori diversi a diversi angoli di incidenza, a causa della interferenza distruttiva nella riflessione. Infatti, queste proprietà di riflessione della luce sono di fatto componenti di una caratteristica più comprensiva del materiale conosciuta come funzione di 22 distribuzione della riflessione bidirezionale, o BRDF. Il BRDF determina l’intensità di riflessione in ogni direzione ad ogni lunghezza d’onda, basandosi sulla direzione della luce. Non ci sono tecniche buone in generale per predire con esattezza il BRDF di un materiale basandosi sulla composizione chimica e sul processo di costruzione, così la tavola di BRDF per un materiale è quasi sempre creata dall’analisi attenta di un campione del materiale stesso. Capita spesso che a livello microscopico, la superficie di un materiale sia in realtà un complesso composto di diversi tipi di materiali mischiati insieme o sovrapposti l’uno sull’altro, ciascuno dei quali ha un diverso BRDF. Per esempio, la plastica comune è un miscuglio di un materiale di base bianco e trasparente con sospese all’interno delle piccole schegge di colore opaco. La pelle umana, d’altra parte, è una complessa sovrapposizione di cellule traslucenti, alcune vive altre morte, alcune brune altre rosse, coperte da sottili livelli di sebo e sudore, che nel complesso ha una complicatissima interazione con la luce che la colpisce. 2.2.4. Camera e Profondità di Campo Le macchine fotografiche hanno tre parti importanti: un sistema di lenti, un diaframma con un’apertura variabile, ed una pellicola per registrare l’immagine. Il sistema di lenti nelle fotocamere moderne e di solito piuttosto complicato – ingrandisce, è tipicamente regolabile in diversi modi, compensa per certi tipi di distorsione ottica, ecc… Comunque, ad ogni dato zoom e impostazione di fuoco, il sistema composto di lenti diventa effettivamente equivalente ad una singola lente perfetta. Il sistema di lenti focalizza la luce sulla pellicola, che si stende su un piano sul retro della camera, dietro l’occlusore. A causa del modo in cui lavorano le lenti, l’immagine sulla pellicola risulta invertita. Stringere l’apertura impedisce a parte della luce di raggiungere la pellicola, e perciò scurisce l’immagine. 23 La caratteristica primaria di una lente è la sua lunghezza focale, che è la distanza dal centro della lente al punto dove la luce proveniente da un oggetto posto all’infinito sarà messa a fuoco. La lunghezza focale di una lente semplice è determinata semplicemente da come è fatta, dal materiale, e dalla curvatura della lente, per cui è costante. Comunque la luce che non viene da un punto posto all’infinito sarà focalizzata ad una distanza diversa, come determinato dall’equazione della lente sottile (thin lens equation): 1/(distanza oggetto) + 1/(distanza immagine a fuoco) = 1/(lunghezza focale) Si noti da questa equazione che come un oggetto si avvicina alla camera, l’immagine si mette a fuoco più lontano dietro alla lente. Una camera focalizza sugli oggetti più vicini muovendo avanti e indietro la lente così che la distanza dalla pellicola coincida con la distanza dall’immagine a fuoco di quell’oggetto. Quando il piano della pellicola non è correttamente impostato per un dato oggetto, questo risulterà fuori fuoco. La luce in movimento verso il fuoco ha la forma di un cono, e un piano della pellicola non allineato taglia il cono in una più o meno grande area circolare. Questa area si chiama cerchio di confusione, e la sua dimensione dipende da due cose: la quantità di disallineamento tra il piano della pellicola ed il punto focale, e dal diametro della lente. Si noti che una lente più piccola avrebbe un cono di luce più piccolo, in modo che tutti i cerchi di confusione risulterebbero minori. La caratteristica interessante del cerchio di confusione è che se è minore di una certa dimensione – per esempio della grana della pellicola o del potere di risoluzione dell’occhio umano – non lo si nota, e l’oggetto appare ancora a fuoco. Per questa ragione, anche se c’è solo una unica distanza alla quale la lente mette esattamente a fuoco, c’è un intervallo di distanze per le quali gli oggetti sono così poco sfuocati che il cerchio di confusione non è rilevabile. Questo intervallo di distanze è noto come profondità di campo della camera. 24 Si noti che modificare l’apertura del diaframma ha l’effetto di cambiare il diametro della lente senza intervenire sulle sue altre caratteristiche fisiche. Diminuendo l’apertura, si tagliano i lati dei coni di fuoco, il che ha il doppio effetto di scurire l’immagine e di stringerne i cerchi di confusione. Avere cerchi più piccoli implica che ci sono più oggetti a fuoco, e quindi che la profondità di campo è aumentata. Se l’apertura fosse stretta fino a quasi zero, niente avrebbe un cerchio di confusione rilevante, e tutto risulterebbe a fuoco. Per questo le camere puntiformi hanno profondità di campo infinita. 2.3. Computer Grafica Nei trent’anni in cui la computer grafica è stata studiata, sono stati inventati molti algoritmi, tecniche, e trucchi del mestiere. Negli anni, molti sono stati raffinati, messi su una forte base teorica, e studiati estensivamente. Altri hanno dei trucchi, usati perché hanno un bell’aspetto. Spesso non è facile determinare (o ricordare) cosa è che cosa. Ma avere una ferma base di queste tecniche è vitale per scrivere degli shader. 2.3.1. Antialiasing L’Aliasing è forse il più fastidioso artefatto che infesta le immagini computerizzate. Anche noto come “salto di scala” o “jaggies”, l’alias è un termine che viene dalla teoria della sintesi dei segnali per descrivere artefatti che vengono dal campionamento inadeguato della scena (o funzione) sottostante. Una scena è continua, il che significa che la descrizione della scena fornisce sufficiente informazione perché ci sia un colore ad ogni punto infinitesimale del 25 piano dell’immagine. I pixel di una immagine invece sono campioni di colore della scena spaziati regolarmente. Quei pixel discreti che si decide di mettere nel frame buffer sono perciò solo rappresentativi dei colori, continuamente cangianti, sottostanti. Se si dovesse disegnare un grafico dei colori continui (in una o in due dimensioni), si avrebbe un segnale oscillatorio. Simili segnali, che rappresentino battiti cardiaci o suoni o colori, hanno tutti diverse frequenze in essi; i segnali che variano velocemente hanno frequenze più alte di quelli che variano più lentamente. Uno dei teoremi più importanti nell’elaborazione dei segnali, conosciuto come Teorema di Nyquist, afferma che rappresentare un segnale con accuratezza richiede un campionamento al doppio della massima frequenza presente nel segnale. Raramente le immagini computerizzate hanno una simile risoluzione. Senza sufficienti campioni si ottiene l’aliasing. L’informazione ad alta frequenza è persa ed è sostituita da una informazione inconsistente e visivamente fastidiosa a bassa frequenza, che non era parte della scena. Ci sono due modi per aggirare l’ostacolo. Primo, i campioni possono non essere discreti. Significa che possono rappresentare non uno specifico colore nella scena, ma una qualche media su una regione della scena. Il supercampionamento, dove ogni pixel è la media pesata di molti campioni che sono vicini tra loro, ed il campionamento ad area, dove ogni pixel è la media pesata delle regioni di colore in qualche area coperta da quel pixel, sono entrambe tecniche che possono essere usate per ridurre l’aliasing. Se queste tecniche sono usate bene, i dati ad alta frequenza saranno persi in ogni modo, ma non saranno aggiunti alias a bassa frequenza, e l’immagine apparirà leggermente sfocata. In realtà il supercampionamento alza soltanto la soglia di tolleranza, non elimina completamente il problema. Potrebbero esserci frequenze ancora superiori al tasso di supercampionamento, che creeranno alias anche con questa tecnica. 26 Figura 2.3. Aliasing La seconda tecnica è campionare in modo irregolare, una tecnica nota anche come campionamento stocastico. Sono di nuovo usati i supercampioni, ma il fatto che non siano spaziati regolarmente crea un effetto interessante. Usando questa tecnica, i dati ad alta frequenza sono comunque persi, ma sono rimpiazzati da un rumore bianco costante e di bassa intensità che rende l’immagine un po’ granulosa. Non è quantitativamente meglio dell’aliasing ottenuto con il supercampionamento semplice, ma a causa di certe caratteristiche percettive del sistema di visione umano, questo rumore bianco risulta spesso meno fastidioso rispetto all’aliasing. Questo processo ha senso solo quando sono disponibili molti supercampioni per costruire il pixel finale. Una volta che abbiamo i campioni richiesti del segnale dell’immagine, la seconda fase critica del processo di antialiasing è ricostruire il segnale. Questo è il 27 processo in cui i supercampioni sono miscelati assieme per creare i pixel finali. I pesi che si applicano ad ogni campione nella “media pesata” di cui sopra, vengono dal filtro di ricostruzione. Più precisamente, la ricostruzione crea un nuovo segnale continuo che si suppone essere la migliore rappresentazione del vero segnale, dati i campioni che si hanno. Si deducono i campioni finali (i pixel) da questo segnale ricostruito. La ricostruzione procede con la convoluzione del filtro con i campioni noti. Diversi filtri danno diversi risultati, introducendo altri artefatti nell’immagini, noti come blurring (sfocatura) e ringing (quando i bordi più duri creano delle onde nell’output). In realtà c’è un terzo modo per ridurre l’aliasing, che è costruire la scena in modo che i dati ad alta frequenza non esistano fin dall’inizio, e quindi non hanno mai bisogno di essere rimossi. Questa tecnica è nota come prefiltering della scena ed è facilmente realizzabile in situazioni dove il segnale è costruito da funzioni di altri segnali. Sarebbe un errore pensare che i renderizzatori si preoccupino solo dell’alias spaziale o geometrico. L’alias può avere luogo in ogni processo di renderizzazione dove si ha campionamento. Per esempio, renderizzare una scena in movimento in un momento del tempo causa l’aliasing temporale. Renderizzare i colori spettrali solo con tre campioni RGB causa l’alias di colore. L’alias può avere luogo in una grande varietà di dimensioni, e le tecniche per ridurre o migliorare gli effetti dell’alias sono simili in tutte queste dimensioni. 2.3.2. Quantizzazione e Gamma Le equazioni fisiche del trasporto della luce, e le approssimazioni che sono usate in computer grafica, calcolano l’intensità della luce ed i valori di colore con numeri reali. Tuttavia, la maggior parte dei dispositivi di output sono controllati da valori di pixel interi. Il processo di conversione da reale a virgola mobile ad intero è 28 detto quantizzazione. Ci sono tre dettagli speciali che devono essere considerati durante la quantizzazione: la profondità in bit, la correzione gamma, ed il dithering. La quantizzazione converte valori di intensità a virgola mobile in valori interi appropriati per il sistema di visualizzazione, sulla base della sua profondità in bit. Per esempio, la maggior parte dei monitor dei computer possono riprodurre solo 256 livelli di intensità per canale, laddove le pellicole sono molto più sensibili e possono riprodurre diverse migliaia di livelli di colore. Il risultato è che le immagini che sono calcolate per essere mostrate su monitor standard saranno tipicamente convertite in 8 bit per canale, mentre quelle calcolate per il cinema saranno convertite in 10 fino a 14 bit per canale. I numeri originali in virgola mobile sono scalati in modo da convertire 1.0, che richiede la massima intensità che il dispositivo può ottenere, nel valore intero più grande che il formato permette (tipicamente 2nbit – 1). Figura 2.4. Esempio di curva gamma Il sistema di visione umana non è lineare, cioè ad aumenti costanti di intensità di luce non corrispondono costanti aumenti della sua percezione. Tutti i sistemi di visualizzazione, allo stesso modo, siano essi pellicole, stampanti, o monitor, hanno 29 una risposta non lineare all’intensità dell’input. Piccoli incrementi nei valori del pixel nelle regioni scure creano un cambiamento minore in intensità di output rispetto allo stesso incremento in valori di pixel nelle aree più luminose. Un effetto di questo è che quando un apparecchio riceve un valore di pixel di 0.5, il risultato che l’apparecchio ritornerà, non sembrerà avere intensità 0.5, ma qualcosa di meno. Tuttavia queste due scale logaritmiche non sono mai allineate. Per questo, quando i valori interi dei pixel sono mostrati sul dispositivo, spesso hanno ricevuto una correzione-gamma seguendo la formula out = in1/γ. Tipicamente un monitor per computer avrà un gamma compreso tra 1.8 e 2.4. La correzione gamma ripristina la linearità apparente dell’immagine sull’intensità emessa dal dispositivo. Un effetto collaterale della correzione gamma è che i dispositivi di output hanno più valori disponibili nelle zone scure. Passando i dati attraverso una curva di correzione gamma si perderanno un buon numero di questi valori e si possono spesso vedere i salti di livello. Per compensare questo problema, alcune immagini sono memorizzate una risoluzione in bit superiore, in modo che c’è della precisione aggiuntiva nell’uso dei colori scuri. E’ comunque importante notare che la γ appropriata è una funzione del dispositivo sul quale l’immagine viene mostrata. L’immagine avrà bisogno di essere ricorretta se dovesse essere visualizzata su di un altro dispositivo. Inoltre, i calcoli tipici dell’elaborazione di immagini che potrebbero essere applicati ad un’immagine, come la sfocatura, il ridimensionamento, o la composizione, lavorano al meglio se il dato è “lineare”, vale a dire, non ha una correzione gamma già di per se. Per questa ragione è di solito meglio che le immagini ad alta qualità vengano memorizzate senza correzione gamma, e che la correzione sia applicata solo al momento della visualizzazione. Ci sono tre modi per convertire un reale in intero: troncamento, arrotondamento e dithering. Il troncamento è il più facile, basta usare la funzione floor per scartare i bit frazionari dopo la scalatura. Comunque è facile vedere che 30 questo farà scendere l’intera intensità dell’immagine di una piccola quantità, quindi forse l’arrotondamento è migliore. Arrotondare significa usare floor se la frazione è inferiore a 0.5 e ceiling se la frazione supera tale soglia. Comunque anche l’arrotondamento ha un effetto fastidioso sull’aspetto dell’immagine perché le aree dove i pixel in formato reale sono molto simili avranno una grande blocco di colore costante, dopo la quantizzazione. Al confine di questa regione il colore cambierà di colpo di un livello di pixel e prenderà l’aspetto del “salto di scala” laddove la regione dovrebbe avere un gradiente continuo. Questo effetto si può eliminare con il dithering. Il termine dithering è usato confusionalmente in computer grafica per significare diversi algoritmi che hanno una cosa in comune: alzare o abbassare il valore dei pixel in una regione costante di colore per simulare più profondità di bit in un dispositivo che non ha sufficienti livelli di output. Il dither di quantizzazione è un piccolo valore casuale che viene aggiunto al valore del pixel ancora in formato reale, appena prima che venga troncato. In un certo senso, randomizza la scelta tra l’uso di floor e di ceiling per fare la conversione. L’effetto è la rottura di queste aree colorate in modo costante, rendendole meno regolari e quasi “fuzzy”, così che in media i pixel nella regione abbiano l’intensità in virgola mobile voluta. Un altro algoritmo che raggiunge lo stesso obiettivo è il dither a diffusione di errore, che calcola la differenza tra il valore reale e la sua versione intera, e si assicura che tutta l’intensità dell’immagine ne tenga conto. 2.3.3. Le Bande di Mach L’occhio umano è estremamente sensibile ai bordi ed ai confini. La nostra visione accentua questi confini – un trucco percettivo che li rende più visibili. Infatti, ogni volta che ci sono delle aree costanti chiare e scure adiacenti, la visione umana percepisce l’area scura ancora più scura, e ancora più chiara la parte chiara vicino al confine, in modo da aumentare il contrasto tra i colori adiacenti. Questo effetto è 31 spesso così forte che di fatto sembra di vedere delle bande che percorrono i lati del bordo, di colore diverso dal vero colore dell’area. Queste bande sono dette di Mach, dopo che lo psicofisico Ernst Mach le studiò per primo nel tardo diciannovesimo secolo. Sfortunatamente, nelle immagini in computer grafica i confini tra regioni ampie di colori costanti, o poco mutevoli, sono piuttosto comuni, e le risultanti bande di Mach sono artefatti rilevanti (anche se, oggettivamente, non ci sono!). Le bande di Mach sono visibili anche quando la direzione (in qualsiasi dimensione) di un gradiente di colore cambia improvvisamente lungo un bordo. In altre parole, se c’è una discontinuità nella derivata del colore. 2.3.4. Il sistema di coordinate I sistemi di coordinate tridimensionali si dividono in due tipi: destrorsi e sinistrorsi. La differenza tra queste due varietà è basata sui versi degli assi coordinati, gli uni relativamente agli altri. Per esempio, se l’asse delle x punta a destra, e l’asse delle y punta in alto allora ci sono due possibilità per l’asse delle z: puntare in dentro oppure in fuori. Per esempio si ponga una delle mani, con pollice e indice aperti a forma di L maiuscola. Il pollice rappresenta l’asse delle x e l’indice quello delle y. Il medio sia esteso in modo da essere perpendicolare ad entrambe le dita. La direzione ed il verso del medio indica la direzione ed il verso dell’asse z. Nel caso della mano sinistra sarà il verso di un sistema sinistrorso, ed analogamente con la destra si avrà un sistema destrorso. Le trasformazioni che cambiano un sistema destrorso in uno sinistrorso e viceversa si dicono “mirror” o riflessioni. Anche una scalatura negativa su una dimensione o su tutte le tre dimensioni, o lo scambio di due qualsiasi delle dimensioni hanno l’effetto di invertire il tipo di sistema di riferimento. 32 2.3.5. Composizione e Alpha Spesso, in sintesi di immagini, l’immagine finale è costruita con una combinazione di svariate immagini, ciascuna contenente una parte dei dati. Per esempio, l’immagine potrebbe essere renderizzata a livelli, con gli oggetti più vicini alla camera renderizzati in una immagine, e con lo sfondo generato separatamente. Nella fotografia per gli effetti speciali convenzionali, combinare otticamente le immagini è una tecnica nota come “matte” o “fotografia composta”, ed è realizzato tramite una apparecchiatura detta “stampante ottica”. Comunque, su una stampante ottica sono possibili solo tre operazioni: la correzione dell’esposizione o della sfocatura di una immagine, la moltiplicazione di due immagini (usata spesso per ritagliare via un pezzo di immagine), e l’esposizione multipla (aggiunta di due immagini). Creare un effetto multilivello richiede diversi passaggi attraverso la stampante, con perdita di qualità ad ogni passo. La composizione di immagini digitali, invece, può fare qualsiasi cosa che si possa programmare, ad un numero qualsiasi di immagini, e senza perdita di qualità. L’operazione più comune è sovrapporre due immagini una sull’altra, con l’immagine di sfondo visibile solo dove l’immagine in primo piano è “vuota” – un’operazione detta over. Determinare dove l’immagine contenga dei dati e dove è vacante è un problema complesso nelle scene riprese dal vivo, e coinvolge diverse combinazioni di estrazioni blu/green-screen e di rotoscopìa, ma per le sequenze generate a computer è piuttosto facile. Il renderizzatore fornisce l’informazione, salvandola su un canale separato detto canale alpha (α). Nel 1984 Porter e Duff descrissero un’algebra per combinare le immagini usando il canale α di ciascuna immagine. I pacchetti di disegno moderni spesso includono i concetti di canali di trasparenza, ma α è una versione molto specifica. Primo, le trasparenze disegnate (matte) hanno spesso la profondità di un bit, che identifica se il pixel è dentro o fuori. Per essere utile in un mondo dove i pixel hanno bisogno di essere ben filtrati con antialiasing, solitamente il canale α invece ha tanti bit quanti gli altri canali di colore. 33 Secondo, le trasparenze disegnate con più bit (dette trasparenze fuzzy) sono salvate senza modificare il colore vero. Estrarre l’immagine voluta richiede che il programma moltiplichi il colore per il valore di trasparenza usando tutto il colore quando il pixel è opaco, una frazione quando è parzialmente trasparente, e scartandolo del tutto quando è trasparente. α invece, salva il colore premoltiplicato con il canale di trasparenza. Ci sono diversi vantaggi nella renderizzazione e nella composizione, che rendono questo schema di premoltiplicazione superiore per la codifica di immagini generate a computer. Generalmente le immagini sono ora memorizzate in quattro canali – rosso, verte, blu ed alpha, o RGBA. Naturalmente avere un quarto canale A non garantisce che contenga α, dato che qualche software potrebbe memorizzare un valore di trasparenza semplice in quel canale. In alcuni testi, l’alpha premoltiplicato è detto alpha associato, per distinguerlo dalla trasparenza semplice o da altri dati arbitrari che potrebbero essere memorizzati nel quarto canale di un’immagine. 2.3.6. Modelli di colore La luce è un fenomeno continuo che può essere rappresentato con precisione solo con uno spettro completo. Il colore invece è un concetto psicofisico, perché si riferisce al modo in cui percepiamo la luce. Negli anni, gli esperti nei disparati campi della colorimetria, fisiologia, ingegneria elettronica, computer grafica, e arte hanno sviluppato una varietà di maniere di rappresentare i colori. Con rare eccezioni, queste rappresentazioni hanno tutte tre valori numerici. L’occhio umano ha solo tre tipi di sensori al colore, detti coni. La luce stimola i coni secondo la loro sensibilità allo spettro di frequenze della luce stessa. Di fatto questo converte la rappresentazione spettrale continua della luce in tre campioni indipendenti, detti “valori tristimulus”, che il cervello percepisce come colore della luce. Siccome si percepisce la luce in questo spazio di colori tridimensionale, non sorprende che anche la maggior parte 34 degli altri spazi di colori richiedano tre dimensioni per coprire l’intero intervallo dei colori visibili. E’ interessante, anche se forse non sorprendente, che ci siano tante sottigliezze e tanti dettagli, nello studio psicofisico della percezione dei colori. Per esempio, spesso ci sono molti diversi spettri di luce che stimolano i coni con la stessa intensità, e pertanto sono percepiti come lo stesso colore. Questi spettri sono detti metameri, e senza di essi sarebbe impossibile ricreare l’aspetto di un colore su un display televisivo. Le televisioni (i monitor, i display al laser, ecc…) generano i colori usando tre cannoncini con caratteristiche spettrali molto specifiche, e a volte molto ristrette. Questi cannoncini sono fatti in modo da sembrare di riprodurre una grande varietà di colori, perché creano metameri per ogni spettro che il dispositivo di visualizzazione debba rappresentare. La rappresentazione più comune del colore nella computer grafica è RGB: rosso, verde e blu. Questo schema di colori è semplicemente il controllo diretto dei tubi catodici della televisione o del monitor. I canali di colore variano su un intervallo da 0.0 (cannoncino spento) a 1.0 (cannoncino al massimo). Ci sono molti altri modelli di colore che non sono altro che trasformazioni lineari del modello RGB. Alcuni di questi modelli, come per esempio HSL (tinta, saturazione, luminosità) e HSV (tinta, saturazione, intensità), sono stati creati per il fatto che le triple sono più intuitive per gli artisti rispetto ai valori tristimulus RGB. Alti modelli, come YUV e YIQ, sono stati creati perché modellizzano il colore per uno specifico dispositivo oppure per una codifica analogica del segnale. In ciascun caso, una semplice equazione lineare o una semplice procedura converte ogni valore in un modello in un valore in un altro modello. Questi modelli, comunque, non specificano colori esatti. Semplicemente descrivono l’intensità alla quale i tubi catodici (o altri dispositivi) debbano operare. Se i cannoncini su un apparecchio dovessero generare un “colore di base” diverso rispetto a quelli di un altro apparecchio – cosa peraltro abbastanza comune – allora i colori risultanti appariranno diversi nei due apparecchi. Ci sono dei modelli di colore 35 che cercano di risolvere questo problema legando certi colori del modello a certi spettri specifici. Per esempio CIE, una organizzazione internazionale di standardizzazione il cui proposito è quantificare il colore, ha creato diversi specifici modelli di colore che fissano i colori con esattezza. Il più usato di questi è CIE XYZ 1931. NTSC RGB 1953 cercò di risolvere lo stesso problema per la televisione specificando i valori esatti CIE dei “fosfori standard”. Sfortunatamente, come le tecnologie si sono evolute, questi valori divennero rapidamente obsoleti. I processi di stampa, che richiedono colori primari in uno spazio di colori sottrattivo, spesso specificano i colori dell’inchiostro nel sistema CMY (ciano, magenta, giallo). Le descrizioni di CMY spesso si appellano all’idea che il ciano sia assenza di rosso, e perciò CMY = (1,1,1)-RGB. In effetti, la stampa è un processo troppo sottile per essere catturato da una formula tanto semplicistica, e delle buone trasformazioni da RGB a CMY (o al modello CMYK, che è CMY aumentato di un canale per l’inchiostro nero) sono segreti del mestiere delle compagnie di stampa. Altri modelli di colore risolvono un problema diverso. Siccome l’occhio umano è più sensibile alla variazione dei colori in alcune parti dello spettro rispetto ad altre, la maggior parte dei modelli di colore non hanno la proprietà che un cambiamento costante nel valore di un canale abbia un cambiamento costante nel colore apparente. I modelli che prendono in considerazione questa non linearità della percezione dei colori sono detti spazi di colori percettivi. Gli artisti amano questi modelli, come quello di Munsell, perché rende più facile creare delle gradazioni di colore morbide. I modelli CIE Luv e CIE Lab cercano di realizzare la stessa funzione in una maniera matematicamente più rigorosa, con trasformazioni non lineari delle coordinate standard CIE. Recentemente, gli ingegneri della compressione delle immagini hanno iniziato a studiare questi modelli perché aiutano a determinare quali siano i bit importanti da salvare e quali bit non saranno nemmeno notati dal pubblico. Il gamut di un dispositivo si riferisce all’intervallo di colori che può riprodurre. Per esempio ci sono molti colori visibili su un monitor, che l’inchiostro sulla carta non può riprodurre. Si dice che l’inchiostro ha un gamut minore rispetto ai monitor. 36 Chi volesse riprodurre fedelmente un’immagine da un medium all’altro dovrà essere cosciente delle limitazioni dei gamut dei due media ed avere una strategia per approssimare i colori che sono fuori dal nuovo gamut. Figura 2.5 Confronto tra i gamut CIE, RGB e CMYK 2.3.7. Modelli di Geometria Gerarchica Quando si costruiscono modelli geometrici di oggetti complicati, succede spesso che una parte del modello sia connessa con un’altra parte attraverso qualche tipo di giuntura o altro meccanismo. Per esempio, la spalla, il gomito ed il polso connettono sezioni rigide del corpo con giunture che limitano il movimento a rotazioni particolari. Questo conduce al movimento gerarchico delle parti del corpo, dove ruotare la giuntura della spalla causa la rotazione unisona dell’intero braccio e della mano, mentre ruotare il gomito fa ruotare insieme solo l’avambraccio e la mano, e muovere il polso influisce solo sulla mano. La posizione di ogni parte del corpo è sempre relativa alle posizioni delle parti del corpo superiori. Invece che modellare ogni parte del corpo separatamente, e fare calcoli complessi per riottenere la posizione della mano ogni volta che qualcuna delle giunture del braccio si muova, è molto più semplice codificare la gerarchia di 37 movimento del modello direttamente in una struttura ad albero detta Modello di geometria gerarchica. Ogni parte del corpo è situata in un nodo nella gerarchia, e le trasformazioni memorizzate nel nodo sono relative al genitore immediato, invece che al sistema di coordinate del mondo. Per questo, un cambiamento alla trasformazione di un nodo particolare, modifica automaticamente tutte le geometrie legate ai nodi sotto quello in esame nell’albero, senza dover modificare nessuna delle loro trasformazioni. Questo facilita grandemente la modellazione di oggetti complessi. Questo concetto di parti con sottoparti che sono in generale la stessa cosa, ma che sono legate ai nodi al di sopra di esse, si può estendere per includere più caratteristiche che meramente le trasformazioni che controllano la loro posizione ed orientamento. E’ abbastanza comune che siano altrettanto utili delle gerarchie negli attributi dei materiali. Per esempio, il colore della vernice di una piccola parte di una macchina sarà di solito lo stesso della struttura al di sopra di essa. Un altro modo di vedere questo schema è che i nodi sotto una gerarchia normalmente ereditano gli attributi di base dei genitori, ma che possano modificarli secondo le necessità. La struttura dati ovvia per manipolare gli alberi gerarchici è una pila. Ad ogni nodo dell’albero, lo stato della gerarchia è aggiunto in cima alla pila. Il nodo ha la possibilità di fare qualsiasi modifica che sia richiesta per realizzare il suo scopo e per fornire lo stato appropriato ai suoi propri nodi figli. Quando il nodo è completato, la cima della pila viene rimossa, e perciò lo stato del genitore è ripristinato. I sottonodi fratelli possono quindi iniziare le operazioni con lo stesso stato iniziale che aveva il primo sottonodo. Un modello geometrico può avere una varietà di diverse utili gerarchie – gerarchie di trasformazioni, di attributi, di illuminazione, di dinamiche, perfino gerarchie di autori e di costo. Comunque, spesso le complesse relazioni che si formano, creano strutture più complicate di semplici gerarchie ad albero, e comunque i sistemi di renderizzazione sono interessati soltanto ad un piccolo sottoinsieme di questa lista. 38 2.3.8. Modelli di Ombreggiatura Il processo che un renderizzatore utilizza per determinare i colori degli oggetti nella scena è noto come shading (ombreggiatura). Come si è visto, il BRDF di un oggetto, e di conseguenza il colore dell’oggetto visto da un qualsiasi punto di vista, è una complessa interazione della luce con la struttura microscopica del materiale in superficie (ed a volte anche sotto la superficie) dell’oggetto. Per fortuna, non è di solito necessario modellare questa interazione con esatta correttezza fisica per ottenere nelle immagini un aspetto credibile o esteticamente piacevole. Infatti, un’ampia varietà di materiali può essere simulata con un po’ di approssimazioni, che sono state sviluppate negli anni. Le approssimazioni più popolari per i BRDF sono tipicamente modelli empirici (basati su esperimenti e osservazioni, senza basarsi su teorie scientifiche), anche se esistono molti modelli leggermente più complicati che hanno basi più solide nella fisica dei materiali. Due modelli empirici di riflessione luminosa fra i più usati e venerati nella computer grafica sono l’ombreggiatura diffusa di Lambert e quella speculare di Phong/Blinn. L’ombreggiatura di Lambert cattura l’idea di un riflettore diffuso ideale, una superficie estremamente ruvida e opaca. Un simile oggetto appare riflettere la luce in maniera uguale in ogni direzione. La sola differenza risultante nell’aspetto di un oggetto siffatto è in relazione con l’angolazione che ha con la sorgente di luce. Questa differenza è catturata dalla funzione coseno dell’angolo di illuminazione, che può essere calcolato con il prodotto scalare della normale alla superficie e la direzione della sorgente di luce, N·L. L’illuminazione di Phong simula l’aspetto dei punti più chiari che sono visibili sugli oggetti luminosi. Queste piccole aree sono create quando oggetti lisci riflettono la luce con preferenza in una direzione vicina alla direzione di riflessione, e sono noti 39 come punti di riflessione speculare (specular highlights). Phong notò che lo specular highlight di molti oggetti che esaminava appariva essere cerchio coi bordi sfumati, più luminoso al centro e meno sui bordi. Riconobbe che questa forma era simile al coseno elevato ad una potenza, e creò la famosa formula cos(R·L)roughness. Altri modelli sono stato proposti negli anni, alcuni fisicamente più motivati, altri puramente fenomenologici. Uno dei più importanti progressi fu l’osservazione che la principale differenza tra i materiali metallici e quelli plastici era il colore degli highlight (Cook e Torrance, 1981), uguale a quello diffuso nei metalli, bianco nei materiali plastici. Figura 2.6 Lambert, Phong ed entrambi combinati Lo shading è quasi sempre fatto nello spazio di colori RGB, anche se è chiaro che la maggior parte dei calcoli di riflessioni dovrebbero essere dipendenti dalla lunghezza d’onda, e quindi dovrebbero essere fatti più propriamente nello spazio continuo degli spettri. Tuttavia, esperimenti con calcoli su ombreggiatura spettrale, con 9 o 20 campioni per colore, hanno raramente mostrato migliorie significative nella qualità dell’immagine, tranne che negli esempi particolari che usavano prismi o materiali iridescenti. Per questa ragione, raramente ci si preoccupa che i calcoli dipendenti dalla lunghezza d’onda siano ignorati, e si usa qualche forma di filtraggio dei colori come approssimazione in ogni situazione dove la differenza risulterebbe evidente. 40 2.3.9. Ray Tracing Uno dei metodi più comuni per spiegare il processo di rendering è di richiamarsi all’intuizione sul processo fisico della fotografia: i raggi di luce sono emessi da sorgenti luminose, rimbalzano nella scena, riflessi da oggetti e da essi colorati, ed infine colpiscono la pellicola nella fotocamera. Questo paradigma di seguire i percorsi dei fotoni mentre attraversano una scena è detto ray tracing. In pratica, i renderizzatori in ray tracing non seguono i raggi in avanti, a partire dalla luce, nella speranza che alcuni di essi infine giungeranno alla camera. La maggioranza dei raggi non lo fanno, e ci vorrebbe moltissimo tempo per renderizzare una immagine. Al contrario, i raytracer seguono i raggi all’indietro, dalla camera, finché non raggiungono infine una luce. Curiosamente, gli antichi Greci credevano che il fenomeno della vista funzionasse proprio così, che cioè ciò che si vedeva dipendesse da dove fossero atterrati i raggi visivi partiti dai loro occhi. I fisici moderni confermano che la simulazione risulta essere la stessa, dato che il percorso di una luce è reversibile – la luce può andare ugualmente bene in entrambi i versi di un percorso, e segue lo stesso percorso in entrambi i versi. Siccome il ray tracing simula la propagazione della luce, è capace di creare immagini realistiche con molti effetti interessanti e sottili. Per esempio, le riflessioni di uno specchio e le rifrazioni attraverso un vetro sono semplici perché richiedono solo minimi cambiamenti al percorso del raggio che sono calcolabili con le leggi di riflessione e rifrazione viste prima. Sono state sviluppate tecniche per simulare una varietà di effetti ottici, come riflessioni “fuzzy” (riflessioni su superfici ruvide dove l’immagine risulta sfumata perché i raggi riflessi non vanno tutti nella stessa direzione) ed effetti volumetrici (la luce interagisce con il materiale nel quale sta passando). Uno dei più interessanti fenomeni è quello delle caustiche, il fenomeno della luce che viene focalizzata da oggetti riflessivi o rifrattivi nella scena, che causa aree più luminose o più scure sugli oggetti circostanti, come quelle su un tavolo sotto un bicchiere di vino. 41 L’operazione fondamentale dell’algoritmo di ray tracing è trovare l’intersezione di una linea con un oggetto geometrico. Questa semiretta rappresenta il raggio di luce. Si usa una semiretta in quanto si è interessati solo in quella regione di spazio di fronte all’origine della luce, non a quella dietro. Se diversi oggetti intersecano il raggio, l’intersezione voluta è solo quella più vicina all’origine del raggio. A seconda del tipo di primitiva geometrica (sfera, poligono, NURBS, …), potrebbe essere necessaria qualsiasi cosa, a partire da una semplice equazione matematica fino a complessi algoritmi di approssimazione geometrica, per calcolare l’intersezione del raggio con quel tipo di primitiva. I ray tracer reali hanno algoritmi elaborati per scartare gli oggetti che non sono per nulla vicini al raggio, per fare economia sui complessi calcoli di intersezione. Il processo di intersecare un singolo raggio con un insieme di primitive geometriche è propriamente noto come ray casting. Il ray tracing propriamente detto si riferisce alla tecnica di calcolare ricorsivamente la riflessione e la rifrazione e tutti gli altri raggi secondari partiti dal punto di intersezione del raggio originale, per seguire il cammino della luce che rimbalza nella scena. Non è raro che un renderizzatore che non usi il ray tracing come algoritmo di base, richieda occasionalmente il calcolo dell’intersezione di un raggio con un oggetto geometrico. Nell’uso comune si dicono frasi come “tracciare un raggio” o “lanciare un raggio” per descrivere questo tipo di calcoli. 2.3.10. Altri Algoritmi Siccome il ray tracing è intuitivo e cattura un’ampia varietà di effetti ottici interessanti, è una delle maniere più comuni per scrivere un renderizzatore. In alcuni ambienti i termini ray tracing e rendering sono ingenuamente usati come sinonimi. Tuttavia, il ray tracing è un processo computazionalmente costoso, e ci sono altri algoritmi per la sintesi di immagini che prendono scorciatoie computazionali per ridurre il tempo di calcolo complessivo. 42 Una delle principali operazioni che un renderizzatore effettua è determinare quali oggetti sono visibili nella scena e quali sono nascosti dietro altri oggetti. Questa operazione è detta eliminazione delle superfici nascoste. Esistono molti algoritmi che esaminano gli oggetti nella scena e determina quali siano visibili da un singolo punto nella scena – la posizione della camera. Gli algoritmi scanline, z-buffer e Reyes sono esempi di questo tipo. Gli oggetti sono tipicamente ordinati in tre dimensioni: la loro posizione x e y quando sono proiettati sul piano di vista della camera, e la distanza z dalla camera. Le differenze tra i molti algoritmi sono basate su fattori come il tipo di ordinamento, le strutture dati usate per mantenere il database geometrico, i tipi di primitive che possono essere manipolati, ed il modo in cui l’algoritmo di rimozione superfici nascoste e interfogliato con altri calcoli che il renderizzatore debba effettuare (come l’ombreggiatura) per creare l’immagine finale. Il vantaggio computazionale principale di questi algoritmi è che manipolano solo una volta ogni oggetto nella scena. Se è visibile dalla camera, è solo visibile in una posizione dello schermo e solo da quella angolazione. Non può apparire in altre parti dello schermo con diverse angolazioni o diversi ingrandimenti. Una volta che un oggetto è stato renderizzato, può essere scartato. Se non è visibile dalla camera in maniera diretta, lo si può scartare direttamente in quanto non c’è altro modo di vederlo. I ray tracer invece devono tenere traccia di tutti gli oggetti nella scena per l’intero rendering, siccome specchi o arrangiamenti complessi di lenti nell’immagine possono far si che qualsiasi oggetto possa apparire più volte nella scena da diverse angolazioni e diversi ingrandimenti. Si noti comunque, che siccome questi algoritmi di superfici nascosta calcolano la visibilità da un singolo punto di vista, non è in generale possibile calcolare informazioni su quali altri punti nella scena si possano vedere, come sarebbe necessario per calcolare vere riflessioni e rifrazioni. Si perde la capacità di simulare questi effetti ottici. Il ray tracing invece, mantiene le strutture dati necessarie per generare informazioni di visibilità tra due punti qualsiasi nella scena. Per questo motivo si dice che il ray tracing è un algoritmo di visibilità globale, e i calcoli di 43 illuminazione che usano queste utilità del renderizzatore sono detti calcoli di illuminazione globale. I renderizzatori senza illuminazione globale devono simularla con dei trucchi, come texture che contengano immagini della scena vista da altre angolazioni. Ci sono altri algoritmi e tecniche ancora più recenti per simulare l’illuminazione globale. Si tratta dell’Ambient Occlusion e soprattutto dell’Image Based Lighting, presentati al Siggraph dal prof. Paul Debevec nel 2000. L’image based lighting (IBL) è il processo di illuminare le scene e gli oggetti (reali o sintetici) con immagini di luce dal mondo reale. E’ l’evoluzione naturale della tecnica della mappatura riflessiva (reflection mapping) nella quale si usano immagini panoramiche come texture per mostrare oggetti lucidi riflettere ambienti reali e sintetici. IBL è analogo alla modellazione orientata alle immagini, nella quale si deriva la struttura geometrica di una scena 3D da immagini, ed al rendering orientato alle immagini, nel quale si produce l’aspetto renderizzato di una scena a partire dal suo aspetto in immagini. Quando usato efficacemente, l’IBL può produrre aspetti realistici di oggetti renderizzati, e può rivelarsi uno strumento efficace per integrare la computer grafica in scene reali. I passi base dell’IBL sono: 1. Catturare l’illuminazione reale in una immagine HDRI (high dynamic range image) omnidirezionale. 2. Mappare l’illuminazione in una rappresentazione dell’ambiente. 3. Piazzare l’oggetto 3D dentro l’ambiente. 4. Simulare la luce dell’ambiente che illumina l’oggetto digitale. 2.4. Renderer, shader e shading network Data la vastità della letteratura e delle implementazioni in circolazione, può capitare di fare confusione tra i vari termini ed i rispettivi ruoli. Un renderizzatore (o 44 renderer) può essere di diversi tipi ed avere moltissime caratteristiche, ma è generalmente scomponibile in parti ben distinte: • Motore (rendering engine) • Campionatore (sampler e filtri antialasing) • Render-Time modeller (opzionale, per operazioni di tassellazione e displacement) • Dati della scena • Nodi di Shading Il motore di rendering fa una serie di chiamate a dei suoi moduli, che sono concettualmente separati dal motore stesso, detti Nodi di Shading, che possono essere di diversi tipi: o Texture (immagini e procedurali) o Procedure (qualsiasi tipo di funzione può essere usata come nodo di shading) o Shader Uno shader è quindi un ben preciso nodo di shading che ha il ruolo di ombreggiare una superficie secondo determinati parametri di illuminazione. Ne sono degli esempi gli shader di Lambert, di Phong, e quelli anisotropici che si trovano nei pacchetti di disegno 3d. 45 Figura 2.7. Shader e renderer Una shading network è un grafo di nodi di shading. Nel suo insieme una shading network ha in sé ciò che serve per descrivere un materiale, ed in 3dsMax infatti si chiama materiale. In molti altri applicativi (es. Maya e XSI), e nell’uso comune, la shading network viene semplicemente chiamata shader, e l’intero processo di ombreggiatura, testurizzazione, composizione ecc… si chiama shading. Da qui il significato ambiguo del termine shading. 46 3. Texture procedurali Nel suo articolo al Siggraph del 1985, il prof. Perlin sviluppò il concetto comunemente noto oggi come noise (rumore). La teoria dell’elaborazione di immagini e di segnali, naturalmente, aveva già studiato molti tipi diversi di rumore, ciascuno con un nome che indicava il contenuto della sua frequenza (ad esempio il rumore bianco, il rumore rosa…). Ma quei tipi di rumore hanno tutti una caratteristica: sono intrinsecamente casuali. Perlin riconobbe che nella computer grafica si vuole che le funzioni siano ripetibili, e perciò pseudocasuali. Ma soprattutto, scoprì che si rivelano più utili le funzioni che sono casuali ad una certa scala ma sono prevedibili e perfino localmente “morbide” se viste ad una risoluzione molto più fine. Le funzioni di rumore che sviluppò Perlin, e quelle che furono più tardi sviluppate da altri ricercatori, hanno tutte delle proprietà in comune: 47 • Funzione deterministica (ripetibile) di uno o più input • Banda limitata (nessuna frequenza oltre una soglia scelta) • Visivamente casuale quando vista oltre una scelta frequenza • Continua e morbida quando vista al di sotto di tale frequenza • Intervallo di valori limitato Queste proprietà danno al rumore di Perlin due caratteristiche importanti, quando usato in computer grafica: può essere filtrato (e anche prefiltrato) in antialiasing e può essere combinato con altri rumori simili in una maniera simile alla sintesi additiva degli spettri. L’antialiasing viene dal fatto che questo rumore ha un contenuto in frequenze controllato, il che rende possibile escludere proceduralmente le frequenze che porterebbero ad aliasing nel processo di renderizzazione. La sintesi spettrale invece è la tecnica di sovrapporre diverse frequenze a diverse intensità per creare degli intrecci (pattern) complessi ed interessanti. Molti pattern hanno un tipo simile di aspetto pseudocasuale, casuale su un insieme di frequenze ma controllato a frequenze maggiori e minori. Il rumore di Perlin fornisce uno strumento fondamentale per simulare questi ed altri pattern. E su questa stessa tecnica si basa lo sviluppo di moltissime mappe procedurali. 3.1 Texture come immagine Solitamente, in computer grafica, con texture (o tessitura) si intende una immagine 2D in un qualche formato compresso o meno. Questa immagine ha delle dimensioni definite in numero di pixel, profondità di colore, e presenza o meno di un canale di trasparenza o più specificamente α. Per generalità, lo spazio delle due dimensioni spaziali viene normalizzato da 0.0 a 1.0 in modo da poter usare la texture come una funzione di due variabili: u e v, a prescindere dalla sua risoluzione. Se i due input fanno riferimento a un valore 48 compreso tra due o più pixel, a seconda dell’implementazione si avrà una qualche interpolazione o un arrotondamento al pixel più vicino. Se invece uno od entrambi i valori di input risultano fuori dai limiti 0.0 e 1.0 allora si usa la tecnica del wraparound: viene ignorata la parte intera del parametro reale, con il risultato che la texture appare più volte affiancata a se stessa. Si definisce tileable o seamless (affiancabile) una immagine fatta apposta per essere affiancata a se stessa senza avere discontinuità visibili. Ci sono svariate tecniche per ottenere immagini di questo tipo, che però si rifanno all’abilità di un artista delle texture. Figura 3.1 Texture non affiancabile Figura 3.2 Texture affiancabile 49 3.3 Texture come funzione L’uso di una immagine come fosse una funzione di due variabili suggerisce il fatto che in luogo di usare una immagine potremmo invece utilizzare degli algoritmi. Nascono da questa idea le texture procedurali. Le caratteristiche salienti delle texture procedurali sono molto interessanti. In primo luogo possono avere in input un qualsiasi numero di variabili. Avere più di due valori di input permette di creare texture a tre o più dimensioni. Se si sceglie di assegnare ad una di queste dimensioni il significato di tempo, si otterranno delle texture animate. In secondo luogo le variabili di input non devono necessariamente essere comprese tra 0.0 e 1.0. Anzi il tipo dei valori di input non sarà vincolato ad un tipo numerico reale normalizzato, ma potrà essere un intero, un booleano, un numero immaginario, un colore, una percentuale, o una texture (procedurale o immagine) che a sua volta restituirà uno di quei valori in base ai propri parametri di input. Questo implica che una texture procedurale, a seconda della sua implementazione, molto facilmente potrà avere la caratteristica di essere affiancabile con i parametri u e v oltre l’1.0 e sotto lo 0.0, anzi addirittura potrebbe non essere mai uguale a se stessa al loro variare. In terzo luogo, il fatto di essere calcolata al volo permette ad una texture procedurale di occupare uno spazio irrisorio fino alla sua valutazione, ovvero lo spazio che occupa il codice che la fa funzionare. L’altra faccia della medaglia è che spesso una texture procedurale richiede un tempo di calcolo superiore a quello di una bitmap per essere valutata. Per questo il suo uso nei motori grafici real-time è solitamente limitato alla generazione di immagini in tempo di caricamento. Tali immagini vengono poi salvate in memoria ed utilizzate come normali bitmap. Un’altra caratteristica che le rende vincenti in molte situazioni è, a seconda dell’implementazione, la possibilità di avere dettagli a qualsiasi livello di scala. Se 50 una texture procedurale è definita come un frattale sarà possibile aumentare il dettaglio e controllarlo a piacimento tramite ulteriori parametri di input. In nessun caso si avranno le sgranature dovute ad una risoluzione inadeguata, problema tipico delle bitmap. 3.4 Esempio: Costruzione del Perlin Noise Una funzione noise è essenzialmente un generatore di numeri casuali. Prende in input un intero e restituisce un numero casuale basandosi su quel parametro. Se si passa lo stesso parametro due volte, produce due volte lo stesso numero. E’ importante che si comporti in questo modo o la funzione di Perlin semplicemente produrrà risultati senza senso. Questo è il grafico di un esempio di funzione noise. Un valore casuale tra 0 e uno è assegnato ad ogni punto sull’asse X. Interpolando tra i valori, se può definire una funzione continua che prenda un valore reale come parametro. 51 Ora, prese un buon numero di simili funzioni continue, con varie frequenze ed ampiezze, possiamo aggiungerle fra loro per creare una funzione di rumore. Si definisce questa funzione Perlin Noise. Esempio in una dimensione: 52 Si può vedere che questa funzione ha variazioni grandi, piccole e medie. Ci si può immaginare che assomigli ad un paesaggio montano. Di fatti molti paesaggi generati a computer sono fatti con questo metodo. Naturalmente usano un noise 2D, come nell’esempio seguente: Dovendo aggiungere insieme queste funzioni di noise, ci si può chiedere esattamente quali ampiezze e frequenze usare per ciascuna. L’esempio unidimensionale di prima usava il doppio della frequenza e la metà dell’ampiezza per 53 ogni funzione successiva. E’ una scelta abbastanza comune. Tanto comune che di fatto molte persone non considerano nemmeno l’idea di usare altri approcci. Tuttavia, si possono creare funzioni di Perlin Noise con caratteristiche diverse usando altre frequenze e ampiezze ad ogni passo. Per esempio, per creare delle colline morbide, si potrebbe usare una funzione di Perlin Noise con grandi ampiezze a basse frequenze, e piccolissime ampiezze per frequenze maggiori. O si potrebbe creare un piano molto roccioso, ponendo ampiezze basse alle frequenze basse. Per rendere le cose più semplici, e per evitare di ripetere le parole “ampiezza” e “frequenza” ogni volta, è usato un solo numero per specificare l’ampiezza di ogni frequenza. Questo valore è noto come Persistenza. C’è un po’ di ambiguità a proposito del suo significato esatto. Il termine fu coniato originariamente da Mandelbrot, uno delle persone che stanno dietro la scoperta dei frattali. Egli definì che un rumore con poca persistenza ha le frequenze alte predominanti. Oggi invece si usa una definizione dal significato inverso: fissata la frequenza = 2 i si ha l’ampiezza = persistenza i Ogni funzione di noise che si aggiunge si dice anche ottava. La ragione è che ogni funzione di noise ha la frequenza doppia rispetto a quella precedente, ed in musica, le ottave hanno questa stessa proprietà. Il numero di ottave che si aggiungono è interamente arbitrario. Tuttavia, ci sono delle linee guida. Se si sta usando il Perlin Noise per renderizzare una immagine a schermo, si arriverà ad un punto in cui una ottava ha frequenza troppo alta per essere visibile. Semplicemente non ci sono abbastanza pixel sullo schermo per riprodurre tutto il dettaglio di una funzione noise ad altissima frequenza. Alcune implementazioni del Perlin Noise automaticamente aggiungono tante funzioni quanto si possa, finché non si raggiungono i limiti dello schermo (o del sistema di visualizzazione). 54 E’ anche saggio fermarsi quando l’ampiezza diventa troppo piccola per essere riprodotta. Quando questo accada esattamente, dipende dal livello di persistenza, dall’ampiezza complessiva della funzione e dalla profondità in bit a cui si sta renderizzando. La maggior parte delle texture procedurali, in 3DSMax, in Maya, ed in molti pacchetti 3d, si basano su questi principi e su questo tipo di texture. Dal più semplice noise fino alle texture procedurali più elaborate che simulino fenomeni naturali, come quelle dell’acqua, delle venature del legno, delle nuvole, ecc… Chi fosse interessato ad approfondire gli argomenti trattati in questo capitolo, è incoraggiato alla lettura degli articoli presenti sulla homepage di Ken Perlin (vedi bibliografia). 55 4. Shading in 3dsMax In 3dsMax lo shading si ha non programmando i singoli shader via testo, ma tramite una interfaccia grafica ed un concetto intermedio: i materiali. I materiali descrivono come un oggetto riflette o trasmette la luce. Dentro un materiale, le mappe (una generalizzazione delle texture procedurali e delle bitmap di cui si è discusso sopra) possono simulare texture, disegni applicati, riflessioni, rifrazioni ed altri effetti. Le mappe possono anche essere usate come ambienti e proiezioni da parte delle luci. Il Material Editor è l’interfaccia utente che si usa per creare, modificare ed applicare i materiali nella scena. Ogni tipo materiale può avere diverse varianti a seconda dello shader che gli si applica (costante, Phong, Blinn, metallico, anisotropico, Strauss, ecc…) 56 4.1 Il materiale Standard Per spiegare il funzionamento dei materiali in 3dsMax è utile prendere in esame il materiale più versatile e comune: il materiale Standard. Un materiale standard è il materiale di default negli slot campione del material editor. Ci sono diversi altri tipi di materiale, ma lo standard fornisce una maniera abbastanza diretta per modellare le superfici. Nel mondo reale, l’aspetto di una superficie dipende da come riflette la luce. In 3dsMax, un materiale standard simula le proprietà riflessive di una superficie. Se non si usano mappe, un materiale standard dà all’oggetto un colore uniforme. Una superficie di un singolo colore normalmente riflette molti colori. I materiali standard usano tipicamente un modello a quattro colori per simulare questa situazione. • Ambient: è il colore dell’oggetto nell’ombra (nel caso in cui sia presente una illuminazione ambientale) • Diffuse: è il colore dell’oggetto nella luce diretta (di solito usa il modello di ombreggiatura di Lambert) • Specular: è il colore delle parti più riflessive (es. modello di Phong) • Filter: è il colore trasmesso dalla luce che passa attraverso l’oggetto. Il colore di filtro non è visibile se l’oggetto non ha almeno una parte parzialmente trasparente. Quando si descrive il colore di un oggetto in una conversazione, di solito ci si riferisce alla sua componente diffusa. La scelta di un colore ambientale dipende dal tipo di illuminazione. Per una illuminazione moderata di interni, può essere un colore più scuro rispetto a quello diffuso, ma per la luce del giorno dovrebbe essere il complemento della luce principale. E’ anche una buona scelta usare lo stesso colore, leggermente meno saturato, della componente diffusa. 57 Il colore speculare di un materiale standard appare nei punti di massima illuminazione. Si può controllare la dimensione e la forma dei cosiddetti highlights. Una superficie liscia ha degli highlight piccoli ma marcati, mentre una superficie opaca li avrà più grandi ma più sfumati. O non ne avrà affatto. I materiali standard hanno anche controlli per far sì che l’oggetto appaia trasparente e per renderlo autoilluminato, in modo che sembri brillare (per incandescenza o fluorescenza ad esempio). Accanto a questi parametri base, i materiali standard hanno la possibilità di avere un gran numero di mappe, una per canale, che si affiancano o sovrascrivono l’effetto dei parametri numerici. I parametri di ombreggiatura che non restano costanti ma possono variare sulla superficie si dicono canali. Oltre ad i canali già visti (diffuse, ambient, specular, filter) si aggiungono i canali di Specular Level, Glossiness, Self Illumination, Opacity, Bump, Displace, Reflection, Refraction. A seconda del tipo di shader utilizzato possono anche esserci i canali di Anisotropy, Orientation oppure Translucent Color. Naturalmente l’effetto di ognuna delle mappe che si possano assegnare ai canali può essere disattivato, moltiplicato per un valore di “amount” (quantità). E ogni mappa può essere una composizione di altre mappe in maniera ricorsiva senza un limite prestabilito. Si esaminerà ora il significato dei vari canali, che non sono esclusivi di 3dsMax, ma che sono pressoché gli stessi in tutti i sistemi per scrivere shader. • Colore Ambientale: normalmente, la mappatura diffusa mappa anche la componente ambientale, così raramente si ha bisogno di usare una mappa differente. L’immagine è disegnata sulle parti in ombra dell’oggetto. • Colore Diffuso: I colori della mappa rimpiazzano la componente di colore diffusa. E’ il tipo più comune di mappatura. Mappare il colore diffuso è come dipingere un’immagine sulla superficie di un oggetto. 58 • Colore speculare: L’immagine della mappa appare solo nelle aree di highlight speculare. Quando lo spinner di quantità è a 100, tutto il colore speculare è sostituito dalla mappa. La mappatura speculare è usata principalmente per effetti speciali come piazzare una immagine in una riflessione. E’ importante ricordare che, diversamente da Specular Level e Glossiness, che alterano l’intensità e la posizione degli highlight, la mappatura speculare ne cambia il colore. • Glossiness: una mappa assegnata alla glossiness determina quali aree della superficie sono più levigate e quali più ruvide, a seconda dell’intensità dei colori della mappa. I pixel neri della mappa producono una massima levigatezza, mentre i pixel bianchi rendono la superficie completamente ruvida. Solitamente questa mappatura funziona meglio assegnando la stessa mappa allo Specular Level. • Specular level: aumenta o diminuisce sulla superficie l’intensità della componente speculare. • Self Illumination: fa in modo che porzioni dell’oggetto brillino. Le aree bianche della mappa sono considerate autoilluminate, mentre le aree nere riportano l’oggetto alla normalità. Una porzione autoilluminata di un oggetto non risente della luce e non riceve ombre. • Opacity: Le aree più chiare sono considerate opache, mentre le aree più scure sono trasparenti. Si noti che, a differenza degli altri canali, le riflessioni e gli highlight speculari non sono influenzati dalla trasparenza. • Filter: è il colore trasmesso attraverso materiali trasparenti o semitrasparenti. L’effetto sul materiale non è visibile direttamente, ma le ombre (solo se calcolate in ray tracing) e le rifrazioni che passano attraverso un materiale con il filter color mappato, subiranno l’influenza della mappa. • Bump: La mappa di rugosità fa sì che un oggetto appaia come se avesse la superficie rugosa o irregolare. Quando si renderizza un oggetto mappato con la 59 rugosità, le aree più chiare della mappa appariranno più in rilievo di quelle scure. I rilievi sono una simulazione creata perturbando le normali della faccia nel campione considerato, subito prima che venga renderizzato. Per questo motivo i rilievi non si vedono sul profilo di un oggetto con mappatura di rugosità. Questo è dovuto al fatto che la geometria (i vertici) dell’oggetto non sono minimamente influenzati. E in effetti questa mappatura è efficace anche su una singola faccia non tassellata, a differenza della mappatura di displacement. • Displacement: diversamente dalla rugosità, il displace cambia realmente la geometria della superficie. Le mappe di questo tipo applicano la versione in scala di grigio dell’immagine per generare il rilievo. I colori più chiari risulteranno più in fuori (seguendo la normale della superficie originale) di quelli più scuri. Questa tecnica richiede una grande densità di geometria, e per questo è più onerosa in termini di tempo e spazio rispetto alla rugosità. • Riflessione e rifrazione: sono i canali che gestiscono i fenomeni da cui prendono il nome. Se si applica una mappa Ray Trace, non si ha una mappatura reale ma al contrario vengono tracciati dei raggi per calcolare le riflessioni e le rifrazioni vere. Se al contrario si applicano delle mappe l’effetto riflessivo/rifrattivo è solo emulato. Ciò spesso non è un problema perché l’occhio umano non è in grado di vedere facilmente errori e imprecisioni in questi fenomeni, se non sono estremamente evidenti. 4.2 Gli Shader In un materiale, di qualsiasi tipo sia, la fase di ombreggiatura è delegata ad un suboggetto detto shader. Ci sono molti tipi di shader. Alcuni prendono il nome da quello che fanno, altri lo prendono dal loro creatore. Seguono i tipi di shader inclusi 60 nel pacchetto base di 3dsMax. In Natural:shaders sono stati usati per lo più il tipo Phong, più un altro modello di shader sviluppato internamente. • Anisotropico: per superfici con highlight ellittici, o anisotropici. Questi highlight sono utili per modellare i capelli, il vetro o il metallo rigato. • Blinn: una evoluzione dello shader Phong. Serve per ottenere degli highlight più rotondi e morbidi rispetto al predecessore. • Metal: per le superfici metalliche. L’algoritmo non ha basi fisiche, è puramente empirico, ed il suo uso è sconsigliato a livelli alti di realismo. • Multi-Layer: per le superfici composte più complesse di quelle anisotropiche. • Oren-Nayar-Blinn: per le superfici opache come i tessuti o la terracotta. • Phong: per superfici con highlight circolari e forti. • Strauss: per superfici metalliche e non metalliche. Ha un’interfaccia semplificata. • Traslucente: simile allo shader Blinn, ma permette di specificare una traslucenza, dove la luce è trasmessa dopo essere passata attraverso il materiale. 4.3 Programmare un materiale in 3ds Max 3DS Max mette a disposizione la possibilità di integrare nuove funzionalità dentro di sé, tramite un SDK. L’uso di tale strumento richiede però anche Visual C++ installato. I dettagli dell’integrazione in 3DS Max, in ogni aspetto, esulano dallo scopo di questa tesi, per cui ci si concentrerà sui concetti importanti della costruzione di un materiale. 61 4.3.1 Costruzione del framework La prima cosa da capire è il tipo di progetto che si vuole costruire. Per integrare funzionalità all’interno di 3dsMax, un pacchetto esclusivamente orientato a windows, è necessario avere delle solide basi di programmazione ad oggetti, in particolare C++, e delle nozioni di programmazione su piattaforma Windows. Una plugin in 3dsMax è una dll (libreria runtime). Un progetto si compone di un numero variabile di file, ma quello di partenza deve contenere un certo numero di funzioni: DLLMain() Questa funzione è il punto di partenza usato da Windows per inizializzare la DLL. Le plugin di 3dsMax la usano per inizializzare la libreria dei controlli comuni ed i controlli di 3dsMax. LibDescription() Questa funzione ritorna una stringa di testo da presentare all’utente quando la DLL non fosse disponibile. LibNumberClasses() Questa funzione ritorna il numero di classi plugin contenute nella DLL. LibClassDesc() Questa funzione ritorna un puntatore ad un oggetto chiamato Class Descriptor, per ogni classe esportata (e quindi per ogni plugin) della DLL. Questo Class Descriptor descrive le proprietà di ogni classe ed il modo per allocarne una istanza. LibVersion() Questa è una funzione che permette al sistema di lavorare con versioni obsolete della plugin. 62 Il class descriptor di fatto è una classe che dà dei dettagli sull’implementazione della classe plugin vera e propria. Nel caso di un materiale tale classe dovrà essere derivata da MtlBase, oppure da una delle sue sottoclassi, a seconda delle somiglianze e delle caratteristiche che si vogliano implementare, Mtl, StdMat, e StdMat2. 4.3.2 Shade() e EvalDisplacement() Il metodo più importante della classe, il cuore e lo scopo stesso di essa, è senza dubbio Shade(). Questo metodo è chiamato dal rederizzatore per calcolare il colore e la trasparenza dell’oggetto, ed all’occorrenza anche l’intensità ed il colore dell’ombra che proietta su altri oggetti. Riceve in input un unico parametro, oggetto della classe ShadeContext. Questo oggetto contiene tutti i dati necessari per renderizzare un singolo campione. Per esempio contiene una specifica per capire se si sta calcolando l’ombra oppure il colore dell’oggetto, indica se può essere mappato, se deve essere filtrato, se può ricevere ombre, se si sta calcolando lo shading di una faccia rovesciata, l’identificativo del sottomateriale (nel caso si tratti di un materiale multiplo), contiene le informazioni di ogni singola luce, il colore dell’illuminazione ambientale, il livello di ricorsione in caso di riflessioni/rifrazioni in raytrace, e mette a disposizione lo spazio per salvare l’output dei calcoli. Inoltre contiene le informazioni sulla posizione della camera, sulla posizione relativa all’immagine del pixel che si sta renderizzando (nel caso tale informazione abbia rilevanza), la normale e le coordinate del punto sulla faccia considerata, ecc… E’ importante capire che il metodo shade() non è, di per sé, la renderizzazione. Semplicemente fornisce il valore di colore e di trasparenza di un campione, che potrebbe non essere nemmeno destinato all’immagine finale, ma servire per calcoli intermedi che il renderizzatore riterrà di dover fare. Uno shading tipicamente può essere molto complesso, tuttavia si può schematizzare in alcuni passaggi. 63 1. Capire che tipo di campionamento si vuole. In particolare capire le richieste del renderizzatore. Si raccolgono le informazioni più importanti e si salvano in variabili a rapido accesso, possibilmente registri. 2. Calcolare la normale della superficie. In questa fase viene valutata la mappa di bump, o di rugosità. 3. Si calcola il colore diffuso, e lo si miscela secondo le specifiche del materiale con la mappa diffusa. 4. Si calcola il colore ambientale, e lo si miscela secondo le specifiche del materiale con la mappa ambientale, solitamente la stessa della componente diffusa. 5. Si calcola il colore speculare, e lo si miscela secondo le specifiche del materiale con la mappa di colore speculare. 6. Si raccolgono i dati (utilizzando anche le eventuali mappe) di Specular Level e di Glossiness. 7. Si raccolgono i dati di una eventuale autoilluminazione o incandescenza del materiale, che modifica l’uso che si fa delle luci e delle ombre. 8. Questo è il passo più importante. I dati raccolti vanno passati allo Shader. Come si è visto prima, lo Shader è un sotto oggetto del materiale che, utilizzando le intensità, i decadimenti, i colori e le posizioni delle luci, oltre alle informazioni di colore e di lucentezza della superficie, e seguendo i propri particolari algoritmi con i propri parametri, genera i tre colori (ambientale, diffuso e speculare) nelle loro versioni ombreggiate. 9. Si calcola la trasparenza dell’oggetto (utilizzando il valore e la eventuale mappa di opacità). In base al risultato di questa operazione si decide se è necessario applicare i calcoli di una eventuale rifrazione. 10. Si calcola il valore ed il colore della riflessione, e lo si aggiunge al risultato. Si noti che la mappa di rugosità, che ha deviato la normale della superficie, avrà 64 un forte effetto anche nel calcolo della riflessione e della rifrazione, in quanto la direzione dei raggi dipende molto dall’orientamento delle superfici che colpiscono. 11. Si miscelano (solitamente aggiungendoli) i colori di riflessione, di diffusione, ambientale, e speculare. Secondo le occorrenze ci possono essere molti altri canali personalizzati, e molti altri passaggi, con utilizzi arbitrari a seconda dello scopo del materiale stesso. Tuttavia, come si nota, la mappa di Displace non è stata presa in considerazione. Non è un errore, semplicemente non deve essere calcolata in questo metodo. In realtà il displacement non è una operazione propria del rendering, perché viene effettuata subito prima che esso abbia inizio. Questo perché l’applicazione dell’algoritmo di displace cambia fisicamente la geometria, e quindi cambierebbe i valori stessi di input al metodo Shade(), se non la necessità stessa di chiamare tale metodo. Per questo un materiale deve implementare un altro metodo, separato da Shade(), che calcoli la validità e l’ammontare del displacement. Il metodo, per chiarezza, si chiama EvalDisplacement(), e prende in input lo stesso unico oggetto ShadeContext. Non stupisce questo, perché ShadeContext contiene tutto ciò che serve a un materiale per sapere come debba comportarsi. Lo stesso oggetto viene anche passato alle mappe procedurali, nel momento in cui debbano essere valutate, fornendo loro molte informazioni. Di conseguenza si ha la possibilità di creare comportamenti molto complessi ed interessanti nelle texture procedurali, i cui limiti teorici risiedono soprattutto nella immaginazione di chi le implementa. 65 5. Natural:shaders Da gennaio mi sono unito alla casa di post-produzione rebelThink, localizzata a Roma, e da Torino ho assunto la responsabilità dello sviluppo del loro software commerciale pilota, una plugin per 3dsMax, Natural:shaders. Si tratta di una collezione di materiali che simulano l’aspetto di materiali comuni in natura, quali la sabbia, la neve, o la superficie del mare. Dato lo specifico contenuto semantico di questi shader, per nessuno di essi sono state rispettate con rigore le caratteristiche standard specificate nel paragrafo 4.3.2. Infatti tali caratteristiche standard sono fatte per dare ad un materiale standard la flessibilità massima tipica di un materiale “general purpose”. Sapendo invece a priori le caratteristiche fissate e quelle parametriche di un materiale, è possibile utilizzare un buon numero di ottimizzazioni, e concentrarsi su caratteristiche specifiche più complesse, che vanno oltre quelle standard. 66 Per tutti i materiali sono state usate esclusivamente mappe procedurali, in modo che non perdessero di qualità all’avvicinamento del punto di vista. Questo significa che la descrizione della scena sarà sempre abbastanza ricca da avere informazioni per qualsiasi livello di dettaglio, risoluzione, punto di vista. D’altra parte allontanandosi o riducendo la risoluzione, con mappe procedurali si riduce il rischio di mettere in evidenza artefatti come pattern ed alias. Un’altra caratteristica molto richiesta dalla comunità di artisti e shading TD è la possibilità di salvare e caricare rapidamente dei preset di tutti i parametri, separatamente dalla scena stessa, per ottenere con facilità la consistenza nei passaggi tra una scena e l’altra. 5.1. Il sistema di licenza Natural:shaders è un prodotto che verrà messo in commercio a partire dall’estate 2004, per cui ha bisogno di un sistema anti pirateria. Si sono studiati diversi approcci al problema. Dopo aver scartato la possibilità di affidarsi a moduli sviluppati da terzi, come Flexlm, il primo passo è stato esaminare il funzionamento della licenza di 3dsMax stesso. Infatti, se non dovesse essere autorizzato 3dsMax, non si porrebbe neppure il problema di far funzionare una sua plugin. Le versioni precedenti alla 5 utilizzavano un meccanismo che generava una chiave alfanumerica a partire dall’hardware della macchina sul quale 3dsMax veniva installato. Questa chiave prese il nome di Hardware Lock ID (HLID). Si poneva tuttavia il problema per il quale cambiando un solo pezzo del computer, 3dsMax andava riautorizzato – talvolta addirittura ricomprato. Ora 3dsMax ha un complesso sistema di generazione di tale ID, che può essere “migrato” tramite una apposita utility (Discreet License Configuration Switcher) da un computer all’altro. A partire dall’HLID, che non ha cambiato nome sebbene non 67 sia più basato sull’hardware, 3dsMax all’installazione genera un request ID, che viene inviato alla Discreet, che in cambio invia un authorization code. Natural:shaders utilizza grosso modo lo stesso schema. A partire dall’hardware lock – e dalle richieste dell’utente in caso di beta testing – viene generato un request ID, che viene spedito via mail alla rebelThink insieme con i dati del richiedente, tramite un programmino in MaxScript. Gli operatori in rebelThink potranno esaminare la richiesta e tramite un’altra utility, scritta apposta in Visual Basic, generano un codice di autorizzazione che viene rimandato all’utente che potrà così utilizzare la plugin. Figura 5.1. Schema di licenza per Natural:shaders L’unico problema che si è posto è dovuto allo scopo di Natural:shaders. E’ una plugin di tipo “materiale”, il che significa che per funzionare deve essere installata su tutte le macchine che dovranno renderizzare le scene in cui sono presenti tali materiali. Cioè su intere render farm. Le render farm che usano 3dsMax hanno 68 installata una licenza di rete, il che significa che prendono la licenza dal loro server. Quindi risultano avere tutte lo stesso codice HLID, e che avendo acquistato una sola copia possono farla funzionare su un numero teoricamente enorme di macchine. La soluzione è risultata dall’aggiungere altri dati al request ID, criptando al suo interno anche l’indirizzo hardware della scheda di rete principale installata sulla macchina. Tale codice è verificato solo in presenza di una licenza di rete, per cui non sarà necessario riautorizzare la plugin in caso di cambiamento della scheda di rete su una versione stand-alone di 3dsMax. Infine, in caso di beta testing, si ha la scadenza della licenza, nel giro di alcuni mesi dalla concessione della stessa. In alcuni programmi è sufficiente modificare la data di sistema per prolungare tale periodo in maniera teoricamente illimitata. Con Natural:Shaders si è scelto di implementare un controllo per cui non sia possibile avere due esecuzioni consecutive della plugin in cui la seconda abbia una data precedente alla prima. Nel momento in cui si dovesse verificare una simile situazione sarà richiesto all’utente di ripristinare la data di sistema. Una volta ripristinata, la plugin tornerà a funzionare correttamente fino alla scadenza della licenza. Si esamineranno ora più in dettaglio i singoli materiali. 69 5.2 Natural:sand Natural:sand è stato il primo materiale ad essere sviluppato. In quanto tale è stato oggetto di studio approfondito, per capire le potenzialità dell’SDK di Max, e per identificare quanto si potesse andare oltre le possibilità di una rete, anche complessa, di nodi standard. Il primo approccio infatti è stato quello di creare dentro Natural:sand un materiale standard nascosto, e delegare ad esso molti dei calcoli, modificando un po’ la rugosità ed il displace. Ma questo non era il nostro scopo. Così si è reimplementato un materiale da zero, con un numero maggiore di canali di mappatura, utilizzati per funzioni talvolta differenti da quelle specificate in un materiale standard. Figura 5.2. Natural:sand 70 Inoltre è stata data la possibilità di specificare delle mappature personalizzabili dagli utenti più esperti, per alcune caratteristiche il cui comportamento potesse variare molto, come per esempio quello di impronte sulla superficie della sabbia, o l’irradianza dei granelli rispetto alla luce più trasversale. Oltre alle ovvie impostazioni del colore, è possibile specificare la composizione della sabbia, la dimensione dei granelli, la loro visibilità ed il comportamento che prendono con l’incidenza della luce. Ci sono impostazioni per le dune di sabbia, la loro grandezza, la loro altezza, l’erosione del vento, l’orientamento, e, naturalmente, per la loro animazione. 71 5.3. Natural:snow Per quanto rappresenta una situazione in natura opposta a quella della sabbia, la neve strutturalmente non ne è molto dissimile. La neve è leggermente meno esposta agli agenti atmosferici come il vento, ma in compenso può avere dei fenomeni di trasparenza dove si stia sciogliendo. Inoltre è possibile definire delle situazioni in cui la neve si sia sporcata, un fenomeno comune nelle nevicate in città, per esempio. Il tipo di sporcizia, data la varietà di fenomeni nel mondo reale è stato lasciato all’immaginazione dell’utente, lasciando uno slot libero per inserire immagini oppure texture procedurali. Figura 5.3. Natural:snow 72 Così come la sabbia, la neve può mostrare le impronte di ciò che ci si appoggia sopra, sia sotto forma di rugosità, sia sotto forma di deformazione della geometria cui è applicata. Nei parametri inoltre ci sono molte possibilità di intervenire sulla riflessione della luce, in maniera fotorealistica, per simulare la realtà, oppure surrealistica, in modo da ottenere effetti artistici, gradevoli, oppure funzionali alle richieste della narrazione. Figura 5.4. Natural:snow 73 5.4 Natural:rock Data la varietà di materiali e di fenomeni che un materiale come Natural:rock vuole rappresentare, questo shader è stata una sfida molto impegnativa. Sono state implementate un gran numero di mappe, valutate solo quando servono. Data la sua complessità, nonostante gli sforzi volti ad ottimizzare il codice, questo è anche uno dei materiali più costosi in termini di tempi di calcolo. Figura 5.5. Natural:rock Il materiale rappresenta una roccia che contiene fino a quattro minerali: quello principale, altre due grane mescolate all’interno, più un materiale presente solo dentro i buchi e le scalfitture del materiale. Inoltre è possibile aggiungere l’effetto di riflessione ambrata, con un algoritmo di composizione scritto ad hoc, che somiglia vagamente alla riflessione speculare di Blinn. Per ogni minerale è possibile impostare 74 la dimensione della grana, la sua preponderanza nel materiale e la sua visibilità, oltre ovviamente al colore ed alla rugosità che causa sulla superficie. Anche la lucentezza del materiale è parametrizzata, per simulare pietre più lisce oppure bagnate. Inoltre è possibile specificare la quantità, la forma e il tipo delle scalfitture. In alcuni casi sarà anche necessario trasmettere questo effetto al canale di displace, quando le scalfitture fossero troppo grandi per essere simulate solo dall’orientamento delle normali della superficie. Come si vede dalla figura 5.5, è possibile aggiungere al materiale una venatura di minerale metallico (come l’oro), più o meno marcata, più o meno spessa, visibile solo sotto determinate condizioni di illuminazione speculare. 75 5.5 Natural:ice Questo materiale permette di realizzare superfici ghiacciate realistiche. L’implementazione è impostata diversamente dagli altri materiali della raccolta, in quanto non si basa sulla logica architetturale del materiale standard, bensì fa un uso estensivo di algoritmi di raytrace, per il calcolo della densità, delle bollicine, della rifrazione della luce e per la sua colorazione, e per la riflessione differenziata dei fasci di luce. Figura 5.6. Natural:ice ghiacciaio Ci sono due impostazioni iniziali tra le quali si può scegliere: il ghiaccio puro ed il ghiacciaio. Il ghiaccio puro ha una trasparenza molto più marcata, e può essere utile per riprodurre cubetti di ghiaccio, lastre trasparenti, stalattiti e stalagmiti in via di scioglimento. Il ghiacciaio è una versione sensibilmente più opaca, e si può usare 76 per riprodurre ghiaccioli colorati, interni di caverne congelate, o, appunto, ghiacciai ed iceberg. Figura 5.7. Natural:ice puro Sono presenti nell’interfaccia numerosi controlli, con i quali si può controllare l’aspetto delle superfici ghiacciate e del volume ghiacciato, come le crepe, le bollicine, la densità, il grado di scioglimento, ecc… Ci sono diversi parametri a cui possono essere assegnate mappe personalizzate aggiuntive, per gli utenti più esperti. Con Natural:ice, portando agli estremi alcuni parametri è infine possibile simulare anche cristalli di minerali diversi dal ghiaccio, come il quarzo o l’ametista. Tuttavia per realizzare al meglio questo tipo di minerali sono previsti in un futuro prossimo altri materiali, che verranno ad arricchire Natural:shaders. 77 5.6 Natural:sea Natural:sea Shader è finora il materiale della raccolta più ricco di parametri in assoluto. Permette di realizzare superfici marine (o fluviali), viste tanto dall’alto quanto dal basso, a scopi fotorealistici ma anche surreali. Data infatti la ricchezza di personalizzazioni che si possono fare allo shader, il materiale si presta anche ad interpretazioni più artistiche e creative dello stesso fenomeno Figura 5.8. Natural:sea Viene rispettata la rifrazione tipica dell’acqua salata, sia vista dall’alto che dal basso. Inoltre la visibilità in trasparenza diminuisce con la profondità, data la densità dell’acqua. Anche le riflessioni in lontananza si attenuano, mentre viene riflesso 78 maggiormente il colore dell’orizzonte. E’ possibile impostare tre tipi diversi di onde, separabili a piacere, ed il livello più grande può essere utilizzato anche in displacement. Le onde sono naturalmente animabili a piacere e separatamente su tutti i tre livelli. Figura 5.9. Natural:sea, superficie inferiore Natural:sea in realtà è solo il primo passo per una plugin molto più grande e complessa, Natural:sea Ocean System, che presenterà oltre al materiale, una grande quantità di utilità per animare e gestire scene con oceani o mari in movimento. 79 5.7 Natural:magma Natural magma è un materiale complesso che presenta la possibilità di creare ed animare colate laviche, solidificate oppure ancora liquide. E’ anche possibile combinare le due cose in uno stato ibrido, così come avviene in natura. Figura 5.10. Natural:magma I controlli comprendono la quantità (e la posizione) delle parti più liquide o più solide, anche a seconda della loro inclinazione rispetto alla gravità. Per effetti artistici particolari, è possibile variare i colori delle varie parti del materiale, e la dinamicità con cui si evolvono. 80 6. Usabilità Per definire l’approccio con il quale si sviluppano le interfacce grafiche, e le utilità a disposizione degli utenti, è necessario chiarire la fascia media di utenti alla quale punta il prodotto, ovvero il target di Natural:shaders. Parte di questo chiarimento è già fatta definendo il target della sua piattaforma: Windows e 3dsMax. Gran parte degli utenti di 3dsMax sono liberi professionisti che lavorano in proprio per realizzare progetti di rendering architetturali. Ci sono piccoli studi che lavorano su presentazioni di prodotti e su pubblicità. Ci sono grandi studi che trattano di videogiochi ed in alcuni casi di serie televisive. Alcuni anni fa 3dsMax era ancora largamente usato nel campo del cinema ma la sua struttura interna relativamente rigida impediva ai TD più esperti di ottenere alcuni tipi di effetti, in assenza di un team dedicato alla ricerca e sviluppo. Per questo motivo ultimamente 3dsMax ha perso parte di questa fascia di mercato. 81 Natural:shaders, per contro, non fornisce strumenti di basso livello, matematici, privi di semantica, ad uso di TD esperti e che hanno molto tempo ed alti budget. Natural:shaders è una raccolta di materiali ad alto livello, ricchi di contenuto semantico e per questo ottimizzati e migliorati per rendere al meglio tale contenuto. Sono materiali che, utilizzando un paio di algoritmi inediti in 3dsMax, sono dei pacchetti personalizzabili di shading network. Figura 6.1. Esempio di interfaccia 82 Natural:shaders, quindi, è una grande risorsa per gli studi o i professionisti che non hanno grandi budget né molto tempo, situazione estremamente comune in Italia, comune anche laddove si utilizzi 3dsMax, ed ormai frequente in numerosi ambiti della computer grafica in generale. Inoltre si sono studiate le interfacce in modo che chi le usi non debba avere conoscenze di ottica o di matematica, come si richiede ad un TD di livello medioalto. Natural:shaders è stato progettato da artisti, per artisti. Per esempio, in un pacchetto 3d un artista medio che voglia fare “una roccia” deve stare ore a provare infinite combinazioni di parametri e di nodi di shading prima di essere soddisfatto del proprio lavoro. Che tuttavia, in assenza di molta esperienza, nella maggior parte dei casi non sarà eccelso. Al contrario, con Natural:shaders sarà sufficiente aprire il materiale scelto, caricare il preset che più si avvicini alle richieste, e modificare i parametri per perfezionare l’aspetto voluto. Il tutto in pochi minuti, e con risultati sorprendenti. Questo è lo scopo per cui è stata sviluppata la plugin, ed è anche stata la linea guida per il disegno delle nostre interfacce. Ogni singolo parametro ha un nome significativo ed un effetto corrispondente all’interno della semantica del materiale. Per esempio non si troveranno parametri astratti come “soglia maggiore” oppure “iterazioni” ma si avranno valori come “visibilità delle dune”, oppure “densità dell’acqua”. Parametri cioè comprensibili ed intuitivi per un artista. Durante il disegno delle interfacce sono stati considerati gli elementi di psicologia percettiva studiati nel corso della carriera accademica. In particolare sono stati rispettati i principi di Gestalt di raggruppamento, colore e vicinanza. Tutti gli insiemi di parametri riguardanti una stessa caratteristica di un materiale sono raggruppati per vicinanza, poi riquadrati da un controllo win32 groupbox. L’intero materiale è poi suddiviso in una serie di rollup che ne separano le caratteristiche in gruppi più grandi, per omogeneità semantica. Per esempio tutto ciò che riguarda le 83 dune, in Natural:sand, è racchiuso in un unico rollup, così come i parametri della superficie inferiore del mare o le scalfitture della roccia. La costruzione e l’ordine dei rollup è omogeneo in tutti i materiali, in modo da mantenere una consistenza riconoscibile all’interno dei vari prodotti componenti Natural:shaders. In 3dsMax, esiste la possibilità di salvare e caricare materiali dalle cosiddette “material library”. Tuttavia dalla community internazionale e dai beta tester è venuta frequentemente la richiesta di poter usare dei preset dedicati, semplici e veloci da usare, ed in formato testuale. E’ ora possibile perciò salvare e caricare delle impostazioni predefinite. I preset sono dei file in formato testuale, e quindi facilmente leggibili e modificabili, e sono comuni a tutti i Natural:shaders. Per esempio è possibile salvare alcuni parametri di Natural:sand e poi caricarli da Natural:snow per ottenere alcuni effetti in comune. Naturalmente ciò è possibile solo tra i parametri omonimi, e di conseguenza semanticamente equivalenti. E’ inoltre possibile modificare testualmente i parametri eliminando alcuni preset. Questo risulta vantaggioso quando si voglia salvare l’impostazione di solo alcune caratteristiche del materiale mantenendo invariate le altre. L’uso più frequente per il quale questa caratteristica è stata scritta, sarà l’utilizzo dello stesso materiale con leggere varianti in molte scene che abbiano lo stesso paesaggio naturale. Il risultato è l’aumento della produttività e del riutilizzo delle combinazioni di parametri trovate più utili o più efficaci, in maniera trasversale alle varie scene di una o più produzioni. 84 7. Il futuro di Natural:shaders E’ necessaria una premessa: rebelThink è una casa di post-produzione e di visual FX per il cinema e la televisione, non una software house. Natural:shaders è nato dalla necessità di tali materiali per uso interno. Il successo che hanno avuto hanno indotto a farne una versione commerciale, e l’esito delle vendite ne determineranno ulteriormente il destino. Accanto a Natural:shaders usciranno presto anche Artistic:shaders e Industrial:shaders, progetti che ho seguito di persona solo in minima parte. Un altro prodotto della stessa famiglia sarà Natural:sea Ocean System, un progetto molto ampio che mi vedrà impegnato nello sviluppo di strumenti per la simulazione di fluidodinamiche e di molte utilità per la creazione di superfici e profondità marine. Per quanto riguarda il futuro di Natural:shaders, sono pronte le bozze per molti altri materiali, e per il porting di tale plugin su altre piattaforme, in primis su Mentalray. 85 Il vantaggio di sviluppare su un motore di rendering come Mentalray è che si ha molta più libertà per le interconnessioni nelle shading network. Si possono sviluppare shader più potenti, e soprattutto molto più veloci. Questo perché le ultime versioni di Mentalray, così come di alcuni linguaggi di livello più basso come CG e RenderMonkey, utilizzano la possibilità delle nuove GPU (i processori presenti nelle schede video) di essere programmate. Ora è possibile creare i cosiddetti shader hardware, cioè microprogrammi, o shading network, che sono salvati direttamente nella memoria delle GPU. Il risultato è duplice. In primo luogo, un rendering di qualità allo stato dell’arte, che ieri impiegava ore, se non giorni, oggi impiega minuti, quando non secondi. In secondo luogo, i motori realtime di nuova generazione riescono a generare immagini ed animazioni interattive che rasentano il fotorealistico. Per vederne degli esempi si suggerisce la visita di alcuni dei nuovi motori, come Unreal Engine 3 (cfr. bibliografia). Cosa ha reso possibile una simile rivoluzione? Il presidente attuale dell’ACM SIGGRAPH, Alain Chesnais, alla conferenza di Montecarlo, Imagina 2004, ha chiarito questo punto. “La tecnologia nel campo della computer grafica si è evoluta ad un ritmo sempre più veloce. Gli effetti più complessi, che in questo campo erano disponibili solo nei laboratori più equipaggiati, ora sono direttamente disponibili ai nostri bambini sui PC e sulle console in commercio. Questo ha avuto un effetto stupefacente, sia nel livello di sofisticatezza che i consumatori si aspettano nella computer grafica che vedono, sia in ciò che l’industria può di fatto produrre.” I processori centrali (CPU), spiega, si evolvono ad un ritmo teorico finora abbastanza costante, si è visto che raddoppiano di velocità ogni 18 mesi. Le moderne GPU invece hanno un altro tipo di tecnologia che le fa accelerare del doppio addirittura ogni 6 mesi. E si prevede che questo processo potrà andare avanti per almeno tre o quattro anni. Questo significa che fra cinque anni, se le cose restano 86 così, le schede video saranno circa 1000 volte più veloci di adesso. Perché non devolvere a loro dunque i calcoli di shading? La sfida del futuro è fare ciò che si fa adesso negli effetti del cinema, ma farlo 60 volte al secondo, su una singola macchina, possibilmente piccola e portatile. Un altro quesito che ci si può porre è: perché non applicare la stessa tecnologia anche alla CPU? Le CPU sono contraddistinte dal fatto che devono essere “general purpose”, cioè devono poter affrontare un vastissimo numero di calcoli, e di programmi il cui flusso non è predeterminato, ma può cambiare in base a molte operazioni condizionali, il cui esito è predicibile solo in termini statistici. Al contrario il processo di rendering è in gran parte predicibile, ed il risultato di un pixel in generale non influenzerà quello degli altri, e per questo si può dividere il carico di lavoro e farlo eseguire in parallelo su molte pipeline contemporanee, che hanno accesso agli stessi dati ed allo stesso programma. Questa è una spiegazione semplicistica, ma può rendere l’idea del perché non sarà possibile, nei prossimi anni, far evolvere le CPU al ritmo delle GPU. Questo è il futuro dello shading, e probabilmente Natural:shaders seguirà questo stesso corso, se un successo commerciale ne stimolasse l’ulteriore sviluppo. 87 Glossario: • Artista: in questa tesi con “artista” si fa riferimento a tutti gli artisti nel 3d digitale con limitate conoscenze di matematica, fisica, geometria e informatica, ma con un notevole senso estetico e con talento artistico. Il termine è usato in opposizione a Technical Director. • BRDF: è la funzione di distribuzione della riflessione bidirezionale e determina l’intensità di riflessione in ogni direzione ad ogni lunghezza d’onda, basandosi sulla direzione della luce. • Displacement: operazione che sposta i vertici di una geometria subito prima del rendering e subito dopo la tassellazione. I vertici vengono spostati lungo la propria normale di una certa quantità calcolata a partire da una mappa, moltiplicata per una costante. 88 • Geometria: con geometria si intendono i dati riguardanti la struttura geometrica di un oggetto, solitamente consistenti di informazioni sui vertici, sui poligoni, sulle normali, e sulle coordinate di mappatura. • HDRI: una immagine HDRI è una immagine il cui valore dei singoli canali non varia semplicemente in scala lineare da 0 a 255 ma può variare di molto, in maniera esponenziale, così come la luce nel mondo reale. Per catturare dal mondo reale immagini con questi dati è necessario scattare diverse fotografie della stessa scena con diversi tempi di esposizione, in modo da avere le informazioni necessarie sia ad alte intensità di luce sia con zone in penombra. • Matte: una immagine si dice anche Matte quando viene disegnata per essere da sfondo ad una scena in 3D, composta su più livelli. Tipicamente il Matte si trova all’ultimo livello, quello più lontano. • Pipeline: è la sequenza di attività che si svolgono (a volte in serie, a volte in parallelo, a volte un ibrido di entrambe le cose) dall’ideazione di un prodotto in computer grafica, fino alla sua uscita. • Rigging: detta anche character setup, questa è una fase cruciale, in quanto crea tutti gli strumenti che l’animatore avrà a disposizione. Trasforma un oggetto tridimensionale statico in una “marionetta” facile da animare, con tutti i controlli, “fili” e le “levette” ben in vista. • Shader: in senso stretto è un algoritmo che, in base alle condizioni e le angolazioni di illuminazione, restituisce una certa quantità di luce riflessa. In senso lato (più usato modernamente) uno shader è tutta la shading network (che comprende anche shader in senso stretto) che definisce tutte le caratteristiche di un materiale. • Shot: sequenza completa molto breve, durante la quale la camera, anche se si può spostare, non cambia mai bruscamente. 89 • Tassellazione: si possono intendere due cose diverse con questo termine. La prima è l’operazione di creazione di un oggetto poligonale a partire dal campionamento di funzioni matematiche. La seconda è una operazione fatta subito prima del rendering che aggiunge un gran numero di poligoni suddividendo quelli presenti, per dare maggiore risoluzione all’operazione di displacement. • Technical Director (TD): E’ uno dei ruoli più versatili in una pipeline produttiva. Si tratta di una figura a metà tra l’artista ed il tecnico, in quanto deve avere conoscenze in entrambi i campi. Nonostante il nome, un technical director non necessariamente dirige qualcun altro. Ci sono molti tipi di TD: gli shading TD (o shaderwriter) si occupano degli shader, i character TD si occupano di rigging, i lighting TD si occupano dell’illuminazione. • Texture: una qualsiasi immagine, quando viene mappata su un oggetto tridimensionale, prende il nome di texture. A volte invece di una immagine viene mappata sull’oggetto una funzione che a seconda di certi parametri restituisce dei valori di colore. 90 Bibliografia: • Anthony A. Apodoca, Larry Gritz: Advanced RenderMan – creating CGI for Motion Pictures. Morgan Kaufmann. • Paul Debevec: Image-Based Lighting. IEEE Computer Graphics and Applications, 2002. • Associazione della Teoria della Gestalt e delle sue applicazioni http://www.enabling.org/ia/gestalt/ • Homepage del prof. Ken Perlin, http://mrl.nyu.edu/~perlin/ • Unreal Engine, http://www.unrealtechnology.com/html/technology/ue30.shtml • Thomas Porter – Tom Duff, LucasFilm. Composizione con canale alpha (1984): http://keithp.com/~keithp/porterduff/p253-porter.pdf • Modello di colori di Munsell: http://www.cis.rit.edu/mcsl/ 91