RAYTRACING, COME GODO :-) Corso di Ray-Tracing per principianti Parte 1/7 di Alfonso Martone (alfmar) "Papa' ora che abbiamo una piastra Doppio Pentium (Doppio Bug) a 120MHz, si puo' sapere che ce ne facciamo?" --> "Zitto che sto lanciando Wordstar 3.3". Non staro' a fare una discussione computerfilosofica del raytracing, mi limito a dire solo un paio di cosucce a chi si sente preso da un brivido ancestrale di sentirsi un "incompetente in materia", prima di entrare in azione. Raytracing per fortuna non e' il diminutivo di Raymond Tracing l'americano che ha inventato l'algoritmo e ha scritto il primo programma a risoluzione 240x120 in bianco e nero su Apple II nel lontano 1983 in una notte di pioggia. Il raytracing, che io sappia, e' il processo di disegno (bidimensionale) di una scena (tridimensionale) descritta per "primitive" (cubi, sfere, coni, etc). Ad ogni oggetto e' associata una posizione nello spazio (quindi le coordinate 3D) nonche' altri parametri caratteristici (riflettenza, brillanza, etc). L'osservatore della scena e' in una certa posizione dello spazio e guarda in una certa direzione; nello spazio esistono uno o piu' punti dove "comincia" la luce che forma, con gli oggetti, i vari giochi di ombre, trasparenza, etc. Un "normale" programma di disegno 3D (e pressoche' tutti i giochi in grafica vettoriale 3D) si preoccupa al piu' di ricolorare in modo uniforme le zone ombrate e di eliminare le superfici nascoste; il raytracing e' assai piu' evoluto perche' prevede appunto ombre (superfici opache), trasparenza (acqua), riflessione (specchi), rifrazione (vetro), etc, per cui "modellando" i parametri si puo' ottenere un disegno di un realismo estremo. Il raytracing si basa su un concetto tanto semplice quanto dispendioso in termini di potenza di calcolo richiesta: per ogni punto vengono generati i raggi (rays) da tutte le sorgenti di luce e a furia di intersezioni e riflessioni con gli oggetti (chi ha studiato ottica sapra' di riflessione diffusa, speculare, luce ritrasmessa, specchi "quasi perfetti", rifrazione, etc) si determina il colore finale del pixel nell'immagine. Un programma di raytracing fa proprio tutto questo. Fa definire gli oggetti (in termini di posizioni e di caratteristiche) nello spazio tridimensionale; fa definire la posizione dell'osservatore e delle sorgenti di luce ed infine calcola l'immagine (rendering). Non conosco 3D-Studio ma so che lo fa :-)... quello che invece vi presento in questo messaggio e' il POVray (Persistence Of Vision raytracer, v2.2), per gli amici: POV. I risultati migliori, per la visualizzazione, li ottengo - inutile a dirsi - con una scheda truecolor (24 bit per pixel); con una scheda hicolor a 32000 o 64000 colori si ottengono ancora dei risultati decenti, ma a 256 colori non si vede proprio niente. I miei lavori sono tutti a 640x480 a 16 milioni di colori per punto - ho una 2-The-Max con Tseng ET4000 e AcuMos ADAC1 a 15-16-24 bit per pixel, comprata un paio di anni fa abbondanti; il monitor e' un Mitsubishi a colori (14 pollici) e i risultati sono eccellenti. POV mi genera delle immagini in formato Targa-uncompressed di oltre 900k l'una (640x480x3=...), passandole in JPEG si scende fino a 20k, ma si rischia di perdere qualcosa per la solita storiaccia della compressione "lossy" (le immagini generate sono di una perfezione da paranoia)... ma questo e' un problema che tratteremo a parte - e comunque si tratta solo di spazio su hard disk. In area P_UNIX do' qualche consiglio per compilare ed usare massicciamente il POV sotto Linux; chi ha un DX4/100 si deliziera' con al piu' qualche ora di calcolo; io ho uno stupido 386/40 senza coprocessore e per un rendering "pesante" (con molti oggetti) devo far girare il programma anche per una quindicina di giorni. POV fa semplicemente il "calcolo". Vuole in input un file ascii in una specie di linguaggio di programmazione che descrive la scena e genera - previo uso intensivo della cpu per un mostruoso numero di ore - l'immagine in formato Targa-uncompressed (.TGA), visualizzabile sotto DOS col CSHOW 8.xx (per il Linux ho scritto un programmino io per la mia scheda, ne parliamo in P_UNIX). Vediamo l'esempio piu' semplice (il mio mitico "pittura.pov"), di appena quattro righe: #include "colors.inc" camera { location <0, 2, -3> look_at <0, 1, 2> } sphere { <0, 1, 2>, 2 texture { pigment {color Yellow} } } light_source { <2, 4, -3> color White } (gli spazi non sono troppo importanti). All'inizio includo ovviamente il file che ha tutti i colori predefiniti (ho usato solo Yellow e White). La seconda riga definisce dov'e' l'osservatore, pardon, dov'e' la sua telecamera: alla locazione x=0, y=2, z=-3 (prendeteli per metri, centimetri, quello che volete) e guarda esattamente il punto x=0, y=1, z=2(che dunque nel rendering corrispondera' proprio al centro dell'immagine). Nella terza riga finalmente ci metto un oggetto: una sfera, di centro x=0, y=1, z=2 (proprio dove sto puntando la telecamera) di raggio 2 (centimetri, metri o quel che vi pare: stessa unita' di misura per tutti), che ha uno stupendo colore giallognolo. Nella quarta riga dico che la lampadina (pardon, sorgente di luce di colore bianco) e' posizionata a x=2, y=4, z=-3. L'asse x e' l'asse orizzontale del video che abbiamo davanti. L'asse y e' quello verticale (quindi il video pare proprio in coordinate cartesiane) e l'asse z e' quello che parte da noi e va verso l'interno dello schermo. Dunque la sorgente di luce e' 2 metri piu' a destra di noi (2-0=2), 2 metri piu' su di noi (4-2=2), e non e' ne' piu' avanti ne' piu' indietro ((-3)-(-3)=0). Spero non si siano offesi i bimbi delle elementari per questa considerazione algebrico-matematica. Il modo preoccupante di definire il colore della sfera: sphere { <0, 1, 2>, 2 texture { pigment { color Yellow } } } era semplicemente perche' il secondo esempio e': sphere { <0, 1, 2>, 2 texture { Bronze_Texture } } Le caratteristiche di un oggetto si definiscono proprio nel blocco parametri "texture"; il "pigment" e' solo il gruppo parametri "colore"+"trasparenza". Nel primo esempio la sfera era gialla e basta (tutti gli altri hanno un default, nel nostro primo esempio la sfera e' opaca e sembra dipinta col pennarello); aggiungendo altri parametri (brillanza, riflessione) si ottiene un effetto "cambio materiale": nel secondo esempio il materiale e' appunto il bronzo, di colore "bronzeo" (55/100 di rosso, 47/100 di verde, 14/100 di blu, nessuna trasparenza), brillanza 6, riflessione 25%, etc. I parametri su cui si puo' intervenire sono veramente numerosi e si possono ovviamente dare valori assurdi (un oggetto che riflette troppo e rifrange ancora di piu'; non so se esista in natura un materiale che specchi gli oggetti intorno lasciando passare la luce da tutti gli altri lati...). C'e' per esempio la finitura "phong" che fa "specchiare" la luce in maniera plastica; la caretterizzazione "metallic", l'effetto "marble" (marmo?), etc; un oggetto puo' anche essere ruvido ("roughness"); si puo' dare un po' di "turbulence" nella colorazione o nella definizione dell'oggetto; si possono cambiare i gia' citati parametri di brillanza, riflettenza, rifrazione e cambiare, in POV, anche l'indice di rifrazione che normalmente vale 1.33 per l'acqua, 2.5 per i diamanti etc. Nei prossimi articoli parlero' un po' piu' diffusamente di POV e di quel poco che ho imparato finora (il manuale appare a prima vista ostico, invece e' di una chiarezza e di una semplicita' deliziose). Nel frattempo scaldate pure i processori perche' finalmente avrete modo di usare la CPU per piu' di venti secondi totali al giorno (aho', ogni operazione vi finisce in un centesimo di secondo, sarebbe pure ora di sfruttare tanta potenza di calcolo, no?).