1
Computer Graphics
Marco Tarini Università dell’Insubria
Facoltà di Scienze MFN di Varese Corso di Laurea in Informatica Anno Accademico 2011/12
Lezione Lezione Lezione
Lezione 12: 12: 12: 12: davanti e dietro.
rimozione delle superfici nascoste
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Rimozioni delle superfici nascoste
• Gli oggetti più vicini devono coprire quelli più lontani
– gli oggetti lontani sono "occlusi"
da quelli più vicini
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Rimozioni delle superfici nascoste
• Non e' occlusion culling
– che puo' solo rimuovere
interi triangoli occlusi (magari a gruppi) – che è solo una ottimizzazione
• Back-face culling non basta – esempio:
superfici non back-facing, non totalmente occluse ma parzialemnte occluse
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Rimozioni delle superfici nascoste
• Soluzione 1:
– dividere ogni triangolo parzialmente occluso
in parte visibile e parte occlusa?
• facendo una operazione di clipping Come si trovano le coppie occluso/occlusore?
Clipping di un triangolo e un altro?
E dove, nel pipeline HW?
SOLUZIONE IMPROPONIBILE
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Rimozioni delle superfici nascoste
• Soluzione 2:
– disegnare solo poligoni interi, ma nell' ordine giusto
• (back-to-front)
– noto come "algoritmo del pittore"
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
• Data una scena (composta da primitive) – ordinare le primitive per profondità
• dalla più remota alla più vicina al punto di vista – mandarle tutte (in ordine)
Scomodo!
Poco efficente!
Pensare al progetto
che abbiamo fatto.
2
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
Fr am m en ti & at tri bu ti & at tri bu ti & at tri bu ti & at tri bu ti in te rp ol at i in te rp ol at i in te rp ol at i in te rp ol at i Ve rti ci & lo ro a ttr ib ut i & lo ro a ttr ib ut i & lo ro a ttr ib ut i & lo ro a ttr ib ut i
Screen buffer Ve rti ci p or ie tta ti & at tri bu ti & at tri bu ti & at tri bu ti & at tri bu ti co m pu ta ti co m pu ta ti co m pu ta ti co m pu ta ti
rasterizer triangoli
co m pu ta zi on i pe r f ra m m en to set- up
rasterizer segmenti set- up
rasterizer punti set- up
co m pu ta zi on i pe r v er tic e
DOVE?
x y
z v0 v1
v2
v0 v1
v2
prima di mandare i triangoli.
Fatto dalla CPU !
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
• Data una scena (composta da primitive) – ordinare le primitive per profondità
• (cioe’ in ordine di z… in spazio vista!) – mandarle tutte (in ordine)
Sorting Sorting Sorting Sorting!
Complessità pesudolineare (n log(n) n log(n) n log(n)) n log(n) col numero di primitive.
in comp graph, peggio di lineare vuol
dire MALE
Una primitiva non ha una sola profondità!
piuttosto ha una profondità max
max max max e una min min min min
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
• Ma va prima C o D?
• Ma poi, esiste sempre
un "ordine giusto"? P ro fo
n d it à
z
minPrimitive B
z
maxA
E D
C
• La primitiva A può essere disegnata per prima
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
• La primitiva A può essere disegnata per prima
• Ma va prima C o D?
• Ma poi, esiste sempre un "ordine giusto"?
– NO:
• intersezioni – NO:
• cicli di sovrapposizioni
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
• Oneroso – sorting: (n log (n)) – e nella parte software!
• Mal adattato allo schema HW – deve lavorare in spazio occhio
...ma prima della proiezione HW ?!
– lavorare globalmente su tutta la scena prima di mandare la prima primitiva
• Scomodo all'atto pratico
– le primitive sono già "ordinate" semanticamente (scene-graph)
• Test difficili
– in alcuni casi (quando gli intervalli min z e max z non sono disgiunti)
• Bisogna comunque fare clipping – in altri casi (intersezione, cicli)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo del pittore (depth sorting)
• usabile sse è
facile ordinare preventivamente le primitive – in fase di preprocessing
• Esempio: terreno come campo di altezza
3
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Rimozioni delle superfici nascoste
• Soluzione 3:
– rimuovere le superfici nascoste con un TEST PER FRAMMENTO
– algoritmo dello "Z-buffer"
• o "Depth-buffer"
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo dello zzzz----buffer buffer buffer buffer
Fr am m en ti & at tri bu ti in te rp ol at i
Ve rti ci & lo ro a ttr ib ut i Screen
buffer Ve rti ci & at tri bu ti co m pu ta ti
rasterizer triangoli set- up
rasterizer segmenti set- up
rasterizer punti set- up
co m pu ta zi on i pe r v er tic e
Depth Depth Depth Depth buffer buffer buffer buffer
co m pu ta zi on i pe r f ra m m en to
profondit profondit profondit profonditàààà di ogni pixel
RGB finale RGB finale RGB finale RGB finale per ogni pixel
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo dello zzzz----buffer buffer buffer buffer
Fr am m en ti & at tri bu ti in te rp ol at i
Ve rti ci & lo ro a ttr ib ut i Screen
buffer Ve rti ci & at tri bu ti co m pu ta ti
rasterizer triangoli set- up
rasterizer segmenti set- up
rasterizer punti set- up
co m pu ta zi on i pe r v er tic e
Depth Depth Depth Depth buffer buffer buffer buffer
co m pu ta zi on i pe r f ra m m en to
Transform.
Metti la z finale come
attributo aggiuntivo
Interpola (come tutti la z gli attributi)
per un frammento con screen coordinates (x,y), colore (r,g,b) e profondità z:
if ( z <= DepthBuffer[x,y] ) { ScreenBuffer[x,y] = (r , g , b) ; DepthBuffer[x,y] = z ; } else scarta (“discard”, “kill”) frammento
depth test
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo dello zzzz----buffer buffer buffer buffer
Fr am m en ti & at tri bu ti in te rp ol at i
Ve rti ci & lo ro a ttr ib ut i Screen
buffer Ve rti ci & at tri bu ti co m pu ta ti
rasterizer triangoli set- up
rasterizer segmenti set- up
rasterizer punti set- up
co m pu ta zi on i pe r v er tic e
Depth Depth Depth Depth buffer buffer buffer buffer
co m pu ta zi on i pe r f ra m m en to
ho ho ho
ho bisogno bisogno bisogno di bisogno di di precisione di precisione precisione!!!! precisione floats
floats floats
floats di di di di almeno almeno almeno almeno 16 o 24 16 o 24 16 o 24 16 o 24 bits bits bits bits
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo dello zzzz----buffer: buffer: buffer: buffer:
esempio
(con depth buffer ipotetico di interi a 6 bit: valori da 0 a 63) 63 63 63 63 63 63 63 6363 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
5 5
5
5 5 5 5 5 5 5 63 5 5 5 5 5 5 63 63 5 5 5 5 5 63 63 63 5 5 5 5 63 63 63 63 5 5 5 63 63 63 63 63 5 5 63 63 63 63 63 63 5 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
+ =
5 5 5 5 5 5 5 63 5 5 5 5 5 5 63 63 5 5 5 5 5 63 63 63 5 5 5 5 63 63 63 63 5 5 5 63 63 63 63 63 5 5 63 63 63 63 63 63 5 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
7
2 7
5 5 5 5 5 5 5 63 5 5 5 5 5 5 63 63 5 5 5 5 5 63 63 63 5 5 5 5 63 63 63 63 4 5 5 7 63 63 63 63 3 4 5 6 7 63 63 63 2 3 4 5 6 7 63 63 63 63 63 63 63 63 63 63
+ =
5 5
5 5
5 5
5 5
5 5
5 5 5
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
7 6 7
5 7
4 7
3 7
2 7
7 6 7 5 6 7 4 5 6 7 3 4 5 6 7 2 3 4 5 6 7
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo dello zzzz----buffer: buffer: buffer: buffer:
proprietà
• il rendering diventa “order independent” ☺!!!
• Funziona su tutto ☺ – anche su:
• Operazione per frammento – Viene svolto durante
"computazioni per frammento"
• Adatto all'implementazione HW ☺
5 5 5 5 5 5 5 63 5 5 5 5 5 5 63 63 5 5 5 5 5 63 63 63 5 5 5 5 63 63 63 63 4 5 5 7 63 63 63 63 3 4 5 6 7 63 63 63 2 3 4 5 6 7 63 63 63 63 63 63 63 63 63 63
4
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Algoritmo dello zzzz----buffer: buffer: buffer: buffer:
costi
• Costa un po’ di memoria (GPU)
– spesso: sizeof( depth buffer ) = sizeof(screen buffer ) / 2
• Problemi di aliasing sulla z
– causa problema detto: “z-fighting”
– avviene quando la precisione non è sufficiente
es., se si renderizzano due superfici parallele molto vicine
• Assume superfici del tutto opache
– problemi con le superfici semitrasparenti (come vedremo…)
• Dati condivisi in lettura e scrittura
– complicazione per chi implementa HW
– efficienza ameno in parte impattata (ma test molto ottimizzato) – è un test HardWired in GPU HardWired in GPU HardWired in GPU HardWired in GPU
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Depth test, in OpenGL
• Devo abilitare il depth test:
glEnable(GL_DEPTH_TEST);
primitivequipixels tutto il pipeline
(proiezione, setup, rasterizzazione...) stato di OpenGL manipolazioni di stato (es. settare la matrice)
Posso anche decidere le condizioni per passare il test:
glDepthFunc( GL_LESS ) GL_NEVER GL_EQUAL GL_LEQUAL GL_GREATER GL_NOTEQUAL GL_LESS GL_GEQUAL GL_ALWAYS
(dafault) (dafault) (dafault) (dafault)
• Depth test: viene eseguito automaticamente alla fine del nostro fragment shader
– (se abilitato)
– motivo: è un op. critica, read/write su dati condiviso – motivo: HW deve poter fare le sue ottimizzazioni
• (es depth buffer gerarchico)
==> il fragment shader
dovrà determinare in output:
– un valore RGB, – un valore di depth un valore di depth un valore di depth un valore di depth
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Depth test, in OpenGL Depth test, in OpenGL
• Il rasterizzatore produce un valore di depth di default
– per ogni frammento prodotto
– interpolando la Z dei vertici proiettati in input
• Possiamo sovrascrivere questo valore se vogliamo nel fragment shader
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
// fragment shader void main() {
...
gl_FragColor = ... // un vec4 gl_FragDepth = ... // un float }
assegnamento opzionale.
(ha un costo grande farlo! depth test va rimandato e alcune ottimizzazioni HW disabilitate
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 1 / 1 2 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a