LWita 
Home
Articoli
Forums
Gallery
Tutorials
Downloads
Links
Competizioni
Archivio News
About

Tutorials

Creare il fianco di una montagna - Node displacementStampa/PrintPDF
by Gabriele Rescaldani aka vashts


 Questo tutorial fornisce un esempio da seguire passo passo per iniziare a prendere confidenza con il nuovo Node Editor di LightWave v9; in particolare, si farà uso di quello fornito per il displacement degli oggetti.


1) Creazione dell'oggetto nel Modeler

 Aprendo il Modeler, creiamo un semplice oggetto che sarà la base per il nostro displacement. Ognuno crei la forma che ha in mente: io ho riprodotto a grandi linee il pendio di una montagna, semplificandolo al massimo. L'unica considerazione da seguire è quella di creare un oggetto con un discreto numero di suddivisioni poligonali, create con gli strumenti che si prefesce (Knife, Julienne, Bandsaw, ...).

In seguito, scegliamo Catmull-Clark come SubD-Type (in basso a destra) e convertiamo il nostro oggetto in superifici di suddivisione mediante il tasto Tab della tastiera.

Nota: la scelta delle Catmull-Clark non è obbligatoria; si tenga però presente che il livello di suddivisione delle Catmull-Clark sale molto più rapidamente rispetto a quello delle Subpatch classiche, che richiedono quindi alti valori per pareggiare quelli delle nuove SubD.

Ecco come si presenta l'oggetto da me creato:


Figura 1: la mesh nel Modeler in versione poligonale e suddivisa con Catmull-Clark SubD


2) Caricamento dell'oggetto, posizionamento e alcune operazioni preliminari

 Dopo aver salvato l'oggetto, passiamolo al Layout e chiudiamo pure il Modeler (non ne avremo più bisogno). A seconda di quello che avete creato, posizionate oggetto e telecamera in modo che il primo riempia la visuale, preoccupandosi di lasciare un po' di geometria fuori dall'inquadratura: questo perchè il displacement potrebbe deformare la mesh a tal punto da spostare i poligoni e lasciare degli spazi vuoti nel nostro render.

Ecco come si presenta nel mio caso la viewport OpenGL in Wireframe:


Figura 2: l'oggetto posizionato senza displacement visto dalla telecamera


Ora selezioniamo il nostro oggetto, apriamo le proprietà (tasto p) ed aumentiamo nel tab Geometry il Display SubPatch Level a 4, così da osservare meglio in realtime le deformazioni che andremo ad applicare. Passando al tab Deform, attiviamo il check di fianco a Edit Nodes, quindi clicchiamo sul pulsante: si aprirà quindi il Node Editor con già un nodo presente, quello di Displacement, ovvero quello che si occupa di ricevere le deformazioni da applicare alla mesh (ha infatti solo un campo di input).


Un procedimento di base da effettuare ogni qual volta vogliamo fare Normal Displacement, ovvero deformazioni che si propagano sulla normale di ogni poligono (e non quindi su un asse predefinito come X, Y o Z), è quello di aggiungere 2 nodi: Spot Info e Scale.

Spot Info (Add Node > Spot > Spot Info) fornisce i dati sulla mesh corrente; in particolare, a noi servirà quello relativo alle normali del nostro oggetto (output Normal).

Scale (Add Node > Math > Vector > Scale) è invece una funzione matematica che consente di scalare un vettore tramite un valore numerico: nel nostro caso, i vettori saranno le normali dell'oggetto e i valori numerici saranno invece forniti dalle mappe di displacement, le quali producono sia valori di colore (che noi ignoreremo) che valori scalari (ovvero numeri, che a loro volta possono essere visti come le tonalità di grigio che vanno dal nero, valore 0.0, al bianco, valore 1.0).

Colleghiamo quindi l'output Normal del nodo Spot Info all'input Vector del nodo Scale; l'output Result di quest'ultimo lo colleghiamo invece all'input Input del nodo Displacement: siamo così pronti (Figura 3) per applicare le nostre deformazioni, le quali andranno tutte nell'input Scale del nodo omonimo.


Figura 3: il Node Editor dopo le operazioni preliminari

3) Primo passo di displacement

 La prima idea che mi viene in mente osservando l'oggetto è di rompere la regolarità della mesh originale applicando un displacement non particolareggiato e di scala piuttosto grande: nel Node Editor, aggiungiamo un nodo di tipo Turbulence (Add Node > 3D Textures > Turbulence) con le impostazioni in Figura 4 e colleghiamo l'output Alpha all'input Scale del nodo Scale.


Figura 4: il nodo Turbulence fornisce le informazioni di scala del displacement


Avendo usato l'output Alpha per fornire le informazioni di scala, i primi 3 campi del nodo Turbulence, ovvero Bg Color, Fg Color e Blending sono per noi ininfluenti, visto che l'alpha prescinde da qualsiasi informazione di colore. Infatti, essa opera come se impostasse automaticamente il Bg Color col colore nero ed il Fg Color col colore bianco, fornendo quindi una mappa in scala di grigi secondo i parametri Small Scale, Contrast e Frequencies. Bump Amplitude è un altro campo ininfluente, visto che non useremo l'output Bump. Infine, la scala è impostata sui 3m per ogni asse.

Il risultato di questo passaggio sul mio oggetto è visibile in Figura 5.


Figura 5: il risultato del displacement dato dal nodo Turbulence


Tale risultato presenta un primo effetto non voluto, dato dal significato che LightWave assegna alla gamma di grigi di una mappa di displacement: infatti, il nero significa nessun displacement (il punto rimane nella sua posizione originale), il bianco significa massimo displacement, mentre tutti i grigi forniscono valori intermedi a questi due. Ciò porta il nodo Turbulence esclusivamente a “gonfiare” la mesh sulla direzione delle normali dei poligoni dell'oggetto originale; invece, io voglio che la mappa a volte gonfi la mesh, e a volte la sposti nel verso opposto rispetto alla normale. Come posso fare? Molto semplice: poiché la mappa procedurale varia tra il colore nero, il quale ha valore numerico pari a 0% o, meglio, 0.0, e tra il colore bianco, che ha valore numerico 100% o 1.0, allora sottraendo ad ogni punto di tale mappa il valore medio 0.5 ne otterrò una con range da -0.5 a 0.5, che è proprio quello che voglio per a volte gonfiare la mesh e a volte sgonfiarla.

Nel Node Editor, aggiungiamo un nodo di tipo Subtract (Add Node > Math > Scalar > Subtract), colleghiamo l'output Alpha del nodo Turbulence all'input A del nodo Subtract, quindi apriamo tale nodo (doppio click su di esso) ed impostiamo nel campo B il valore 0.5; infine, colleghiamo l'output Result all'input Scale del nodo Scale.


Figura 6: l'aggiunta del nodo Subtract per variare l'output di Turbulence da 0.0__0.1 a -0.5__0.5


Ora la nostra mesh ha un displacement migliore:


Figura 7: il displacement dopo l'aggiunta del nodo Subtract

4) Aggiungere dettaglio

 Ora che abbiamo una buona deformazione generica del fianco della montagna, passiamo ad aggiungere i dettagli. Ci affidiamo ad una texture procedurale Crackle (Add Node > 3D Textures > Crackle) modificandone i valori come in Figura 8. Come abbiamo fatto per Turbulence, l'outpu Alpha di questo nodo verrà collegato all'input A di un nodo Subtract, mentre in B metteremo il valore 0.5.

Come collegare quindi l'effetto dato da questa texture con quello della Turbulence? La risposta dipende da quello che vogliamo fare.. noi, in questo caso, stiamo aggiungendo dettaglio, e per raggiungere il nostro scopo posizioniamo un nodo Add (Add Node > Math > Scalar > Add), i cui input saranno il Result dei 2 Subtract (che a loro volta sono “filtri” delle 2 texture procedurali), ed il cui output finirà come valore di scalatura del nodo Scale.


Figura 8: l'aggiunta di una seconda texture procedurale per i dettagli di displacement


Guardiamo ora la mesh:


Figura 9: il risultato del displacement di Figura 8


Beh.. interessante, ma esagerato: Crackle influisce troppo sul displacement. Come possiamo fare per diminuirne l'intensità? Semplicemente prendendone una sua percentuale: aggiungiamo un nodo Multiply (Add Node > Math > Scalar > Multiply) da sistemare tra Subtract e Add come in Figura 10, ed assegnamo il valore 0.1 (ovvero il 10%) a B.


Figura 10: la procedurale Crackle "pesata" dal nodo Multiply


Figura 11: il dettaglio è ora meno invasivo


Con l'aggiunta della Crackle, siamo già arrivati ad un grado di dettaglio difficilmente visibile in realtime nella viewport OpenGL senza avere un Layout pesante e lento (bisognerebbe infatti alzare il livello di suddivisione Display SubPatch Level per aumentare il numero di poligoni dell'oggetto); perciò, per renderci conto di quello che abbiamo fatto, dobbiamo affidarci ad un render di prova: nelle proprietà dell'oggetto, impostiamo Render SubPatch su Per Object Level, quindi inseriamo un valore di 5 o 6 nel campo sottostante e premiamo F9.


Figura 12: primo test di rendering


Come si vede, c'è molta differenza tra quanto visualizzato dalla viewport OpenGL ed il render.

Il risultato non è male, ma troppo omogeneo. Per spezzare questa omogeneità ci sono diversi metodi; noi proviamo a variare l'influenza della Crackle a seconda della pendenza del poligono su cui viene applicata, lasciando l'attuale valore di displacement quando tale poligono è in piano, mentre lo diminuiamo man mano che esso si trova in posizione verticale. Per fare questo, aggiungiamo un nodo Gradient (Add Node > Gradient > Gradient), apriamolo e settiamo l'input su Slope; ci serviremo per il nostro scopo dell'alpha di ogni chiave, quindi il colore che andremo ad assegnare è ininfluente. Nella prima chiave, lasciamo l'Alpha al 100%, mentre aggiungiamone una in fondo (Position = 1.0) e mettiamo l'Alpha al 30%. Aggiungiamo anche un nodo Multiply e colleghiamo l'output di quello già presente nel Node Editor nell'input A di questo nuovo, mentre l'output Alpha del gradiente deve puntare all'input B di questo nodo (Figura 13).


Figura 13: il gradiente con input Slope e il suo inserimento nella rete dei nodi mediante un nuovo nodo Multiply


Ecco il render di prova:


Figura 14: il render con il nuovo nodo Gradient di tipo Slope


Ora che abbiamo un po' di diversità, aggiungiamo ulteriore dettaglio al nostro displacement. L'idea è quella di aggiungere particolari non nelle fessure già presenti, ma solo nelle parti che la texture Crackle fa sporgere. Per fare questo, aggiungiamo un altro nodo Crackle con le impostazioni che vedete in Figura 15; colleghiamo quindi l'output Alpha del vecchio nodo Crackle all'input Opacity di questo nuovo nodo, in modo che quest'ultimo agisca solo nelle parti grigio/bianche del vecchio, ovvero nelle parti della mesh che già sporgono. Aggiungiamo anche un nodo Add, quindi leghiamo l'output Result dell'ultimo nodo Multiply aggiunto precedentemente al suo input A e l'output Alpha del nuovo nodo Crackle nell'input B; Result punterà invece all'input B dell'altro nodo Add in scena, quello che lega il ramo delle Crackle al ramo della Turbulence e che finisce nel nodo Scale.

Come si può notare, al nuovo nodo Crackle non ne è stato aggiunto uno di tipo Subtract: questo perchè vogliamo che questa procedurale aggiunga dettaglio sempre in positivo, e non a volte in positivo e a volte in negativo.

Guardando la viewport OpenGL, però, ci accorgiamo nuovamente (era già successo in precedenza) come l'effetto ottenuto sia eccessivo. Aggiungiamo quindi un nodo Multiply (Add Node > Math > Scalar > Multiply) e settiamone il valore B a 0.1, quindi lo interponiamo tra la seconda Crackle e il nodo Add cui esso è collegato come in Figura 15.


Figura 15: il quadro completo dei nodi di displacement


Abbiamo quindi terminato; ecco il render finale col semplice displacement applicato alla nostra mesh:


Figura 16: render col solo displacement


Per conferire ulteriore realismo alla mesh, sarebbe ora indispensabile agire sullo shading delle superfici. Questa parte non è affrontata nel tutorial, ma il consiglio è quello di partire da una copia dei nodi Turbulence e i 2 Crackle ed impostare nel Node Editor di shading una superficie che segua come base il displacement. Di seguito, un esempio di quanto ottenuto seguendo questa idea:


Figura 17: il render finale con alcune impostazioni di shading

5) Conclusioni

 L'editor nodale ha delle notevoli potenzialità, che permettono la realizzazione di qualsiasi idea ci passi per la mente. Questo può però ben presto rivelarsi controproducente, poiché il rischio di perdersi è altrettanto elevato: ecco perchè prima bisogna avere bene in testa cosa si intende raggiungere, quindi trovare il modo più semplice ed immediato per soddisfare l'obiettivo. Questo tutorial è stato strutturato proprio in questo modo, spiegando prima quello che si vuole ottenere nei vari passaggi, e solo in seguito il modo e con quali strumenti è stato raggiunto lo scopo: un metodo lineare che permette soprattutto il controllo del proprio operato minimizzando il rischio di perdersi.



www.lwita.com

LightWaveŽ and LightWave3DŽ are registered trademarks of NewTek, Inc.