ALTRI MODELLI LUCE
PER LA RESA DI UNA SCENA 3D
per il calcolo del valore di luminosita' (e colore) di un pixel ovvero di un punto (x,y) dell'immagine 2D sullo schermo si
puo' procedere in vari modi:
un modo e' dato dai modelli di Gouraud e Phong,
dove si calcola il valore dell' intensita' RGB nel pixel PX(x,y) da
considerazioni locali
riguardo la posizione del punto PS(x,y,z)
nello spazio 3D della scena
rispetto le sorgenti di luce,
con PS(x,y,z) punto della scena corrispondente al pixel-punto
PX(x,y) considerato;
diffetto: non sono calcolate le ombre, ne' sono calcolate
le rifrazioni (luce attraverso oggetto trasparente), ne'
riflessioni di oggetti
ombre in OpenGL
dal manuale dell' OpenGL :
per ottenere un effetto ombra si deve
calcolare la matrice di proiezione dalla
luce al piano su cui si vuole l'ombra,
moltiplicarla per la matrice corrente sul
matrix stack e poi disegnare l'oggetto che
risultera' in prospettiva su quel piano, e
dare all'oggetto il colore dell' ombra
voluta sul piano
ombre in OpenGL
OpenGL :
per ottenere un effetto ombra si deve ...
non riportiamo il procedimento
(vedi lavori studenti AA 06 e 07,
ed es. EGD3D_39dinoshade)
per ottenere una resa piu' realistica di una
scena, che tenga conto
delle ombre,
della illuminazione indiretta riflessa
della riflessione di oggetti in altre
supefici riflettenti e
delle trasparenze
bisogna tener conto della propagazione dei
raggi in tutta la scena, quindi di tutti gli
oggetti della scena
un metodo potrebbe essere il seguente:
si seguono i raggi di luce che escono dalle sorgenti di luce
fino ad un oggetto della scena, e poi fino all'osservatore;
-- ma: la maggior parte dei raggi che escono dalla sorgente di
luce finisce fuori dal piano di proiezione che ci interessa, e non
interessano l'osservatore: gran parte del lavoro e' a vuoto.
fuori
fuori
sorgente
di luce
osservatore
(punto di proiez)
dentro
PS(x,y,z)
PX(x,y)
scena 3D
fuori
fuori
invece di seguire i raggi di luce che escono dalle sorgenti
di luce fino ad un oggetto della scena, e poi fino
all'osservatore;
dove ... la maggior parte dei raggi che escono dalla sorgente
di luce finisce fuori dal piano di proiezione che ci interessa,
e non interessano l'osservatore)
meglio:
seguo il cammino inverso, ovvero inizio dal punto
di vista o punto di proiezione e seguo il raggio all'indietro
- dall' osservatore (dal punto di proiezione) - attraverso i
pixel dello schermo - fino alle superfici o - alle sorgenti di
luce della scena.
S1
r.secondario r
S2
(x,y,2-1)
sorgenti
r.secondario r
(x,y,2-2)
n
osservatore
PX(x,y)
r.primario r
PS(x,y,z)
(x,y,1)
il raggio primario r (x,y,1) deriva dalla
luce che arriva
dalle sorgenti, diretta/indiretta: I = amb.+spec.+trasp.+diffusa =
I = ka Ia + Somma( ks Is + kt It + kd Ipi(n.Li) )
qui sono presenti due luci,ciascuna contribuisce alla luce I (che
esce dal punto PS(x,y,z), per il raggio primario r (x,y,1) verso
l'osserv.) con due raggi (secondari rispetto l'osservatore) che
arrivano dalle luci al punto PS (da cui poi si diffondono)
si seguono i raggi di luce che interessano l'osservatore,
partendo dall'occhio dell'osservatore all' indietro:
per tutti i pixel dello schermo si calcolano le intersezioni con gli
oggetti della scena 3D del raggio che unisce il punto di vista
(osservatore) con il pixel sul piano di proiezione (schermo);
sorgente
PX1(x,y)
osservatore
PX2(x,y)
PX3(x,y)
PS2(x,y,z)
PS3(x,y,z)
scena 3D
sorgente
P2
P1
osservatore
PX(x,y)
scena 3D
un raggio che esce dal punto di vista puo' incontrare piu'
oggetti della scena - si sceglie il punto P1 dell'oggetto piu'
vicino all'osservatore (superfici nascoste! P2 non si vede) e
per tale punto si calcola la luce che dal punto va verso
l'osservatore (ad es con la formula di Phong)
- nella versione piu' semplice di questo metodo mi fermo qui -
sorgente
r (x,y,3)
Pi2
a
a
osservatore
PX(x,y)
r (x,y,1)
r (x,y,2)
Pi1
diremo raggio primario r (x,y,1) un raggio che unisce il punto di
vista con un oggetto; dopo l'intersezione Pi1 possiamo
seguire il raggio all' indietro considerando la riflessione
speculare, e ottengo il raggio r (x,y,2) secondario che incontra
un secondo oggetto in Pi2 e da questo secondo un raggio
terziario r (x,y,3) che ad es. qui incontra la sorgente di luce
Luce
O3
O1
r3
z
Pvista
r2
O2
nota: con il metodo di ray-tracing vediamo anche oggetti
nascosti da altri che stanno loro davanti, ma che si vedono
riflessi in altri oggetti: qui l'osservatore vede gli oggetti O1 e
O2, non vede direttamente O3 (nascosto da O1); ma vede O3
riflesso in O2 (raggio r3), e anche lo stesso O3 riflesso due
volte in O1 e in O2 (raggio r2)
Luce
rd
O1
O3
rL
ri
z
Pvista
r2
O2
ancora, l' osservatore vede la luce L riflessa in O2, raggio rL, e
vede il lato dietro di O1 (riflesso in O2) illuminato dalla luce L
direttamente (rd) e indirettamente (ri)
MA:
in un punto generico di una superficie di un oggetto della
scena dobbiamo tener conto di piu' effetti: finora abbiamo
parlato solo delle componenti ambiente, diffusa e
speculare (Gouraud, Phong) :
Idiffusa = Iambiente + I RiflessaDiffusa + IRiflessaSpeculare =
= Ka * Ia + I Incidente Kd * cos(a) + W(a) * IIncidente * Ks * cosn(x)
a queste tre
componenti dobbiamo
aggiungere la
componente rifratta
che viene trasmessa
attraverso un oggetto
osservatore
raggio luce
incidente
L
a
x
P
oggetto
R
N
O
ogni raggio incidente L produce (tra altri)
un raggio R riflesso specularmente e
un raggio T rifratto e trasmesso attraverso l'oggetto :
il raggio trasmesso per rifrazione T ha un angolo ar con la
normale N nel punto di incidenza che e' determinato dagli
indici di rifrazione dei due mezzi, ni e nr come segue:
legge di Snell
nr *sin(ar) = ni * sin(ai)
dove nr e ni sono coefficienti
di rifrazione del materiale in
cui viaggia la luce, e che per
materiali trasparenti diversi
sono diversi...
osservatore
raggio luce
incidente
L
N
ai
R
ai
P
oggetto
ar
T
Vacuum
1.0000
Air
1.0003
Ice
1.31
Water
1.333
Ethyl Alcohol 1.36
Plexiglas
1.51
Crown Glass
1.52 (*)
LightFlintGlass 1.58 (**)
DenseFlintGlass 1.66
HeavyFlintGlass 1.92 (***)
Zircon
1.923
Diamond
2.417
Rutile
2.907
GalliumPhosphide 3.50
(*)vetro senza additivi (**) flint=selce,pietra
focaia(silice) (***) da Comp.Graphics di
Hearn e Baker
tabella di indici di
rifrazione (da rete, con
Google cerca "Snell" e
"law"), dal mezzo di
densita' ottica piu' bassa
(dove la luce viaggia piu'
veloce) ai mezzi di densita'
ottica piu' elevata
(Tom Henderson,
http: //www. glenbrook. k12.
il. us/gbssci/ phys/ Class/
refrn/ u14l2b. html )
legge di Snell = legame tra
angolo rifratto e incidente:
nr *sin(ar) = ni * sin(ai)
un esempio di immagine resa con ray-tracing, di Jamis Buck,
http://www.geocities.com/jamisbuck/raytracing.html
legge di Snell da' l' angolo t=ar
per il raggio T trasmesso per
rifrazione (t angolo del raggio T
con la normale N nel punto di
incidenza con il raggio incidente
L); angoli ai e ar determinati
dagli indici di rifrazione dei due
mezzi, ni e nr
nr *sin(ar) = ni * sin(ai)
osservatore
raggio luce
incidente
L
nr e ni sono i coefficienti di
rifrazione del materiale in cui
viaggia la luce, con t=a r e a=ai
da qui si ricava l'angolo del
raggio rifratto t rispetto la
normale N
oggetto
N
a
R
a
x
P
t
T
O
nr e ni sono i coefficienti di rifrazione del materiale in cui
viaggia la luce, con t=a r e a=ai ;
l'angolo del raggio rifratto a r rispetto la normale N e' dato
dalla legge di Snell:
nr *sin(ar) = ni * sin(ai)
NOTA: i due indici di
rifrazione (luce incidente nie
luce rifratta nr) cambiano in
funzione della temperatura e
della lunghezza d'onda della
luce (raggio->prisma->colori)
in alcuni casi (quarzo) gli
indici variano a seconda della
direzione nel materiale, altri
generano due o piu' raggi
rifratti... ma:
per la maggior parte dei casi
la legge di Snell e' sufficiente
osservatore
raggio luce
incidente
L
N
ai
R
ai
x
P
oggetto
ar
T
O
la legge di Snell lega t=ar= angolo (con la normale N) del
raggio T trasmesso per rifrazione con il raggio incidente L,
nr *sin(ar) = ni * sin(ai), ( t=a r a=ai )
dove nr e ni sono gli indici di rifrazione dei due mezzi in cui
viaggia la luce; la formula fornisce l'angolo del raggio rifratto
rispetto la normale;
cos2 (t) + sin2 (t) = 1, cos(t) = sqrt( 1-sin2(t) ), essendo
sin(t) = ni / nr * sin(ai),
e
sin(ai)=sqrt(1-cos(ai) ), allora
cos( t) = sqrt(1-f2(1-cos2a))
osservatore
raggio luce
incidente
L
dove il fattore f e' il rapporto
f = ni / nr
da cui si ricava la formula per
calcolare il vettore T:
T= f1 * L + f2 * N, con f1 e f2:
T= f * L - (cos(t)-f*cos(a) ) *N oggetto
N
a
R
a
x
P
t
T
O
un esempio di calcolo per la luce rifratta
luce incidente a 300
(rispetto la N) e superficie
che separa aria/vetro
(indice 1.6) ottengo un
angolo di rifrazione di 180
ma: spesso si ignora lo
spostamento del raggio
che attraversa un mezzo
trasparente, o lo si calcola
in modo fisso;
per la trasparenza spesso tengo conto del contributo
all'intensita'di luce con una formula del tipo: I = Ixx+kt*It
vediamo...
sorgente
r (x,y,3)
n
asorg
aoss
osservatore
PX(x,y)
r (x,y,1)
r (s/x,y,2)
PS
r (t/x,y,2)
per passare dal raggio primario r(x,y,1) ai raggi secondari si
tiene conto che la luce in PS(x,y,z) e' data da 4 componenti
I = ka Ia + ks Is + kt It + kd Somma(Ipi(n.Li))
= ambiente+speculare+trasparenza+diffusa
da cui i raggi secondari da seguire:
primo, il r (s/x,y,2) raggio riflesso specularmente
secondo, r (t/x,y,2) raggio trasmesso per trasparenza o rifrazione
r (x,y,2)
n
osservatore
r (x,y,1)
sorgente
PX(x,y)
a
r (s/x,y,2)
PS(x,y,z)
t
r (t/x,y,2)
sorgente
dal raggio primario r(x,y,1), calcolo i raggi secondari r(x,y,2) - qui r
speculare r(s/x,y,2) e r riflesso per trasparenza r(t/x,y,2) dalla luce
in PS(x,y,z), e inoltre il raggio che e' rifratto :
I = ka Ia + ks Is + kt It + kd Somma(Ipi(n.Li))
= ambiente+speculare+trasparenza+diffusa
MA: il raggio secondario in genere NON incontra una
sorgente, ma altri oggetti ... il tutto si ripete !
n
osservatore
sorgente
r (x,y,1)
PS2(x,y,z)
PX(x,y)
r s(x,y,2)
r s(x,y,3)
PS1(x,y,z)
b
r d(x,y,k)
sorgente
seguendo il raggio primario r(x,y,1) , dalla
I = ambiente+speculare+trasparenza+diffusa calcolo i due
raggi secondari (speculare+trasparenza), e sono di nuovo a
seguire un raggio (secondario) all'indietro, rs(x,y,2) per
arrivare ad un punto di un oggetto o di una sorgente; calcolo
intensita' di luce del punto PS2 al passo due,come prima:
IPS2 = ambiente2+spec2+rifratt2+diff2
e arrivo al raggio rs(x,y,3), terziario
al passo k avremo IPSk = ambientek+speck+rifrattk+diffk
• dal raggio primario
vado all'indietro e
calcolo i due raggi
secondari (riflesso
e rifratto), poi da
ciascun raggio
secondario
all'indietro calcolo i
terziari ecc...
r4r
• abbiamo un albero
dei raggi rifratti, che
aumenta molto
rapidamente ...
r1
r2r
r3r
r2t
r3t
r4t
r3r
r3t
r4r
r4t
es. qui il raggio r1 e' seguito (dal Pvista) oltre
l'oggetto O2 , raggio r2 , poi oltre l'oggetto O1 ,
raggio r3 e poi oltre O3 - raggio r4, finche' si
arriva alla sorgente S1:
S1
r3
r4
O3
r2
r1
r3 r
2
O1
r2
Pvista
r2
r1
r1
O2
r2
z
si seguono i raggi di luce che interessano l'osservatore,
partendo dall'occhio dell'osservatore all'indietro:
al passo zero = il raggio che esce dal punto di vista verso la
scena ("attraverso" i pixel schermo)...
al passo k (punto della scena Pk(x,y,z) l'illuminazione e'
calcolata con la nota formula, e' data dalle varie componenti di
luce al passo k+1, di cui seguo due (speculare e rifratto);
mi fermo quando arrivo alla sorgente di luce
oppure quando esco di scena ... MA:
in pratica si segue il raggio per 4 o 5 iterazioni al
massimo, trascurando i contributi ai passi successivi
(anche perche' il costo di calcolo diventa eccessivo)
questo e' il metodo di ray-tracing ("inseguire il raggio")
proposto da Whitted nel 1980 (siamo ai tempi del VAX-780)
appare abbastanza evidente che
il costo di questo metodo e' elevato.
l'algoritmo per il ray-tracing quindi e:
intensita_in_ Pk(x,y,z), passo k-esimo, IPSk , e' data da
speck+1 = intensita' del raggio
proveniente da direzione speculare
rifrattk+1= intensita' del raggio proveniente
da direzione rifratta
IPSk = ambientek+diffk +
+speck+1
+rifrattk+1
dove k e' il passo k-esimo partendo dall'osservatore
schema:
void raytrace( traggio r, tspaziooggetti scena, tcolore& rgb){
tcolore illumin, illumin2; traggio rsecond; tpunto P, mindistinters;
/*chiamata per ogni pixel del piano di proiezione */
for each oggetto O della scena do{
calcola se c'e' intersez P tra oggetto O e raggio r , e event.
aggiorna il punto min_dist_inters (se P e' piu'vicino);
end for each;
with min_dist_inters do /*al punto di minima distanza di inters*/
if esistono raggi secondari then
do{ calcola il raggio secondario rsecond, e chiama
raytrace( rsecond, scena, illumin2 );
accumula valore dell'illuminazione illumin2 in illumin
} while( ci sono ancora raggi secondari)
else calcola l'illumin nel punto dalle proprieta'locali e dalle luci
esci con risultato in rgb = illumin
} // raytrace
curiosita' storiche: nel 1991 uno studente (3.o anno) ha fatto
una tesina di visualizzazione di due sfere e una luce con un
suo programma scritto in Borland Turbo Pascal ambiente
DOS su una macchina Olivetti M24 (Intel 80286):
l'algoritmo di ray-tracing si presta all'esecuzione parallela,
dividendo lo schermo in rettangoli e lanciando
l'esecuzione in parallelo per ogni rettangolo (si potrebbe
fare per ogni pixel); il programma e' stato fatto eseguire su 4
macchine in parallelo (suddivisione "a mano"), per due giorni
durante un weekend; la precisione era di 64 x 64 pixel.
Simile l'approccio di varie persone/ditte, ad es. un film di
animazione con ray-tracing di 3 minuti aveva richiesto (1988)
un mese su 50 workstation Sun (esec. solo nei tempi morti su
macchine di una ditta); [oggi le macchine sono 1000x + veloci]
il testo di Hearn&Baker del 1994 ha in copertina una scena
prodotta con un Macintosh II (Motorola 68030 a 30Mhz) resa
con 26Mega raggi primari in 213 ore... oggi ('05), un Power PC
ha un clock 50 volte piu' veloce, quindi si scende a 4 ore ...
r4a
S4
r3a
S3
r2b
r4b
t2b
t3b
S1
S2
I0=r1
S1
punto di vista (projection
reference point)
dobbiamo tenere traccia (mem)
dei raggi ottenuti nel percorso
di raytracing (per ogni pixel),
da cui un albero di traccia : in
genere si ferma al 4.o livello.
r1
S2a
S3a
t1
S2b
una delle parti piu' critiche (quella che occupa maggior tempo
di calcolo) per il metodo di ray-tracing e' il calcolo
dell'intersezione di un raggio con un oggetto:
se P0 e' il punto da cui esce il raggio (all'inizio P e' il punto di
vista o centro di proiezione) e u e' il raggio (unitario) di
direzione, allora ogni punto sul raggio e' dato da:
P = P0 + s * u (s=scalare, e' equaz.parametrica del raggio)
u si e' dato dal pixel in esame
e dal punto di vista o projection reference point:
u = (Ppix - Pprp) / |Ppix - Pprp|
se l'oggetto e' una sfera (caso piu'semplice) allora
dall'equazione per i punti P della sfera di centro Pc e raggio r :
| P - Pc | 2 - r2 = 0
se in questa eq. sostituisco la P=P0+s*u di sopra, ottengo:
| P0 + s * u - Pc | 2 - r2 = 0
ripeto: punto del raggio:
P = P0 + s * u
equazione per i punti della sfera:
| P - Pc | 2 - r2 = 0
sostituisco P, ottengo:
| P0 + s * u - Pc | 2 - r2 = 0
da cui se DP = Pc - P0
ho l'equaz di 2.o grado in s:
s2 - 2*(u.DP) * s + ( | DP |2 - r 2 ) = 0
da cui le due radici
s= u.DP +/- sqrt( (u.DP)2 - |DP| 2 + r2)
se il discriminante (sotto radice) e'
negativo allora il raggio non interseca
la sfera, altrimenti
s e' data dalla radice piu' piccola
(due punti di intersezione)
y
P
P0
u
r
DP
Pc
x
z
per un oggetto piu' complicato conviene fare un test
preliminare con una sfera contenente l'oggetto:
se il raggio non interseca la sfera, si esclude l'oggetto
senz'altro;
se invece il raggio interseca la sfera, allora si dovranno
esaminare tutte le faccie "davanti" rispetto il raggio (escludo le
faccie dietro, con normale N tali che u.N < 0 [culling] ),
e per ciascuna calcolo il punto di intersezione
raggio - piano in cui sta il poligono (la faccia),
dall'equazione del piano
N.P = -D
con N normale al piano, P punto del piano, D distanza pianoorigine),
trovata intersezione raggio - piano del poligono
vado a verificare se il punto di intersezione sta nel poligono o
se e' esterno al poligono (test punto dentro/fuori poligono)
si puo' vedere che per il test di intersezione raggio - sfera
devo eseguire 3 sottrazioni o addizioni e tre prodotti; se il test
e' positivo devo controllare meglio, con 8 somme o sottrazioni
e 7 prodotti;
qualche miglioramento si puo' avere considerando il test di
intersezione non in 3D ma in un piano in 2D (5 somme e 5
prodotti) ... ma
un guadagno vero nella velocita' di calcolo si ha strutturando
gli oggetti e procedendo per volumi contenenti piu' oggetti...
ancora un'osservazione: la scelta di sfera o parallelepipedo
come volume che racchiude uno o piu oggetti per fare il test
preliminare dipende anche dalla forma dell'oggetto:
per oggetti di circa pari dimensione in x,y,z conviene la sfera,
per oggetti sottili (una penna, una torre...) converra' un
parallelepipedo per evitare - se questo test risulta positivo - di
dover fare poi molti test a vuoto.
di seguito uno dei moltissimi esempi di immagini ottenute con il
metodo di ray-tracing (il metodo risale al 1981, queste
immagini sono piu' recenti);
dall'articolo (da cui l'immagine)
http://www.geocities.com/jamisbuck/raytracing.html
la Pixar presento' nel 1986 le sue prime animazioni molto
realistiche (Luxo jr) - non usava ray-tracing, ma un metodo
simile ma piu' veloce...
ancora un' immagine prodotta con ray-tracing, di Jamis Buck,
http://www.geocities.com/jamisbuck/raytracing.html
da Hearn&Baker :
il calcolo delle intersezioni raggio-superficie puo'
rappresentare fino al 95 % del tempo complessivo del metodo,
e' quindi importante introdurre dei metodi per ridurre questi
calcoli
gli oggetti di una scena sono organizzati gerarchicamente
(albero della scena), e posso specificare per ogni parte della
scena (gruppo di oggetti della scena) una sfera o un cubo, e
poi eseguo dei test preliminari su questi volumi (sfere o cubi),
e elimino parti che non intersecano il raggio, e solo per le parti
che intersecano il raggio approfondisco i test a parti piu'
piccole fino ai singoli oggetti anzi fino alle singole superfici
(triangoli);
si ottengono guadagni di un fattore 10;
anche per il ray tracing si possono usare metodi che sfruttano la
localita' della scena: in genere se mi sposto di pochi pixel nello
schermo i raggi incontreranno circa gli stessi oggetti di prima; ad
es. si puo' usare l'algoritmo della scan-line con liste di facce
attive:
O1
per questo y
sono attivi O2
ymax
e O3
A
xp
O2
(intersecano il
yp
ymin
piano P-A-B)
P
B
O3
O4
per ogni valore della y (scan line y) ho una lista di oggetti
attivi che sono intersecati dal piano definito dalla scan line e
dal punto di vista P, ovvero tali che il loro ymin<y e il ymax>y;
questi non cambiano al variare di x (per tutti i pixel della linea);
O1
per questo y
sono attivi O2
e O3
(intersecano il
piano P-A-B)
A
P
A
yp
xp
O2
B
B
O3
O4
per ogni valore della y (scan line y) ho una lista di oggetti attivi
che sono intersecati dal piano definito dalla scan line e dal
punto di vista P,(per ognuno e' ymin<y e il ymax>y)
quando passo alla prossima scan line (y+1) controllo quali
oggetti non sono piu' intersecati (in figura, O3) e quali invece
entrano in intersezione (in figura, O1), la lista degli oggetti attivi
della scan line e' ordinata per x (agevola test di intersez), e per
ogni x (per ogni pixel) devo anche determinare quale oggetto
e' il piu' vicino (nel senso delle z)
un altro modo per sveltire i test di
intersezione e' la suddivisione dello spazio
della scena in cubi; si considera
separatamente ogni cubetto, e si codifica
una struttura che mantiene un elenco degli
oggetti che intersecano (o appartengono)
un cubetto: si ha una lista di "oggetti attivi"
per ogni cubetto, lista che deve essere
aggiornata passando da un cubetto i,j,k ad
un cubetto adiacente; si noti che le liste
degli oggetti attivi per una scena data
possono essere calcolate una volta per
ogni cubetto, e non cambiano per i raggi
che interessano quel cubetto (pixel per
pixel); inoltre alcune regioni saranno vuote
- test immediato;
5
4
0
7
27
20
2
1
3
ricordiamo un modo per codificare la
posizione di un oggetto in un reticolo di
cubi :
un cubo viene suddiviso in otto cubi,
(oct-alberi!!) numerati come nella figura a
fianco:
ciascuno degli otto cubetti viene a sua volta
suddiviso in otto cubi piu' piccoli, eccetera;
ad es. il cubetto 2 della prima divisione
sara' diviso in 8 cubetti numerati
20, 21, 22, 23, 24, .. 27, il cubetto 20 sara'
ancora suddiviso in 8 cubetti numerati 200,
201..207, eccetera...
la codifica assume che i cubetti 0,1,2,3
siano davanti, e quindi i primi a essere
visibili (incontrati dal raggio);
5
4
0
7
27
20
2
1
3
una variante: suddivisione adattativa, simile alla suddivisione
nello spazio 2D per determinare le intersezioni :
si infittisce la suddivisione solo
nei rettangoli dove e' presente
un oggetto un ragionamento simile si puo'
fare per lo spazio 3D
ancora
un es.
di
ray-tracing
antialiasing
qualita' dell'immagine:
anti - aliasing
vediamo...
antialiasing
nota:
abbiamo visto che per una migliore qualita' dell'immagine si usa
il raytracing
(esame della scena partendo dallo schermo, pixel per pixel: c'e' un
raggio che si deve seguire per ogni pixel della scena ecc)
questo non basta per ottenere un'immagine di alta qualita',
per la presenza degli effetti dei bordi a scalino (aliasing);
si osservi che vi sono diversi tipi di disturbi alias:
antialiasing
si osservi che vi sono diversi tipi di disturbi alias:
alias spaziale, che e'
l'effetto dei bordi a scaletta o seghettati,
che e' tanto meno visibile quanto piu' grande e' la precisione
dello schermo; un oggetto piu' piccolo di un pixel non si vede, a
meno di non essere centrato al pixel, e allora occupa tutto il
pixel;
ma una linea curva vicino all'orizzontale o alla verticale appare
seghettata, a scalini; con opportune tecniche si puo' rimediare,
e la slide seguente (demo Java 2D) ne e' un esempio -->>
antialiasing
alias spaziale, e' l' effetto dei bordi a scaletta o seghettati,
tanto meno visibile quanto piu' grande e' la precisione dello
schermo; un oggetto piu' piccolo di un pixel non si vede, a meno
di non essere centrato al pixel, e allora occupa tutto il pixel; qui
a sinistra senza "anti-aliasing",
a destra con "anti-aliasing"
antialiasing
alias temporale
vari effetti,
ad es. scena ben nota della proiezione di film in un cinema,
con diligenza in film western, le ruote del carro che appaiono
ruotare all'indietro, dovuto all' interferenza tra velocita' delle
ruote e velocita' di campionamento (o di visualizzazione);
alias temporale per oggetti piccoli che si spostano sullo
schermo, l'oggetto piccolo sara' in qualche istante centrato dal
raggio che esce da un pixel, e in un altro istante no; l'effetto
visivo e' un pixel pulsante che si sposta a scatti (uno scatto
per pixel) sullo schermo.
antialiasing
tra molti metodi per ridurre l'aliasing ricordiamo:
* supersampling - uso piu' raggi per pixel
*
regolare: piu' raggi per pixel,
disposti in reticolo a passo costante
*
casuale, piu' raggi per pixel ma in posizione casuale,
* altre tecniche (anti-aliasing con parziale smussatura delle
intensita' di colore, con sfumature di toni intermedi)
* ...
antialiasing
Hearn e Baker nel loro libro "Computer Graphics with OpenGL
del 2004 ricordano
* "antialiased ray-tracing"
super-sampling
adaptive sampling,
distributed (stochastic) sampling
antialiasing
altre tecniche: l'effetto di sfumatura per velocita',
("foto "mossa"),
“motion - blurr"
(che esiste in OpenGL)
in OpenGL: tecniche di uso dell'accumulation buffer
(piu' immagini del color-buffer si accumulano nell' acc.buffer, da
dove sono poi copiate nel color buffer) - tecnica simile
all'esposizione multipla di una foto
OpenGL: glAccum(GLenum op, GLfloat value);
vedi esempi:
accpersp.c , (jittering (antialiasing) with perspective)
accanti.c (jittering with orthogr.projection)
dof.c (depth-of-field effect)
blurr effect
da Fig.10-87, HearnBaker,
scena con parti
sfocate, antialising,
con resa con
combinazione di raytracing e radiosity
(Peter Shirley,
C.S.Dep, Utah Univ.)
esistono molte altre tecniche, tra cui menzioniamo
radiosity
(equilibrio dell'energia della luce nella scena),
tecniche miste:
environment mapping
("the poorperson ray-tracing method")
photon mapping
(ray-tracing with separate scene / illumination model)
...
rimandate ad un altro anno o ad un altro corso ;-)
(radiosity - vedi la presentazione di Cossutta, a.a.2006)
...
fine di EGD27_RAYTRACE
Scarica

EGD27_RAYTRACE