Grafica e Geometria Computazionale Andrea Torsello e Giuseppe Maggiore DAIS, CdL Informatica Via Torino, 155, Venezia Mestre Slides scaricabili da http://www.dsi.unive.it/~grafica/pls/slides.pdf
Cos è la Computer Graphics? Film Videogiochi Visualizzazione Scientifica Architettura Visualizzazione Medica CAD/CAM Beni Culturali
Rappresentazioni La rappresentazione di modelli 3D si può suddividere in due categorie: Boundary-based: (Mesh poligonali, superfici parametriche, superfici implicite) Volume-based: (Voxel, CSG)
Mesh Poligonali La superficie dell oggetto 3D è rappresentata da un insieme di poligoni (triangoli) nello spazio.
Rappresentazione Parametrica La superficie viene definita in forma parametrica utilizzando tre funzioni bi-variate: S(u,v) = (X(u,v), Y(u,v), Z(u,v)) Rappresentazione implicita La superficie viene definita in termine delle sue coordinate cartesiane: f (x, y, z) = 0
Voxels Utilizzati quando è importante l informazione volumetrica (applicazioni mediche). Geometria Solida Costruttiva (CSG) La forma viene ottenuta combinando i volumi tramite operazioni booleane (unione, differenza, intersezione).
Pipeline di Rendering serie di stages di elaborazione che I dati della scena attraversano per diventare immagine
Pipeline di Rendering La pipeline di rendering si suddivide in due parti: Sottosistema geometrico: porta la geometria del modello nelle coordinate dello schermo; Sottosistema raster: accende I pixel dello schermo del giusto colore in funzione della geometria, dell'illuminazione e delle texture. Nei sistemi moderni queste due parti sono affidate a due programmi eseguiti nelle schede video (shader): Vertex shader: fa i conti delle trasformate geometriche per ogni vetice del modello Pixel shader: calcola il colore per ogni pixel
Pipeline di Rendering Pipeline di Rendering Applicazione Grafica Schermo
Trasformazioni Geometriche Le trasformazioni geometriche sono lo strumento che consente di manipolare punti e vettori all interno dell applicazione grafica: sono funzioni che mappano un punto (o un vettore) in un altro punto; La trasformazione di una mesh poligonale si riduce alla trasformazione dei vertici che la compongono Ci permettono di istanziare una stesso oggetto con attributi (posizione, orientamento, scala) diversi. Ci permettono, di definire un oggetto o una scena tridimensionale componendo varie parti.
Vettori e Coordinate Omogenee Per rappresentare punti nello spazio usiamo le coordinate omogenee, i.e., un vettore (x,y,z,1)t di 4 coordinate in cui la ultima è sempre uguale a 1; Questa rappresentazione ci permette di scrivere sia somme (traslazioni) che altre operazioni lineari come prodotti matriciali; Traslazione: Scalatura: Questa uniformità ci permette di gestire la concatenazione di trasformazioni come semplici prodotti: T = T4 T3 T2 T1; L ordine di concatenazione è importante perché le trasformazioni geometriche sono associative ma non sono (di solito) commutative;
Rotazione Teorema di Eulero: ogni trasformazione rigida 3D in cui un punto rimane fisso è equivalente ad una rotazione attorno ad un asse Ogni composizione di rotazioni e traslazioni può essere espresso come una unica rotazione attorno ad un asse Viceversa ogni trasformazione rigida può essere espressa come la composizione di 3 rotazioni attorno agli assi cartesiani (Euler angles) ed una traslazione
Trasformazioni Geometriche I vertici delle mesh subiscono una sequenza di trasformazioni per essere portati in coordinate schermo World: prende i vertici nel sistema di riferimento usato per la modellazione e li porta nella posizione voluta nella scena View: prende i vertici nel sistema di riferimento della scena e li mette nel sistema di riferimento dell'osservatore Projection: applica la proiezione prospettica Viewport: trasforma le coordinate del piano immagine nelle coordinate effettive dei pixel
Dal modello allo schermo 0) trasformazione di modellazione 1) trasformazione di vista 2) trasformazione di proiezione 3) trasformazione di viewport
Pinhole Camera La metafora utilizzata per descrivere le relazioni scena/osservatore è quella della pinhole camera La luce entra da un foro di dimensioni infinitesime e sulla faccia posteriore si formano le immagini Immagini nitide, nessun problema di luminosità Per evitare l effetto di ribaltamento si assume l esistenza di un piano immagine tra la scena ed il centro di proiezione
Normalized Device Coordinates
Illuminazione Modelli di illuminazione Modello di illuminazione: formulazione matematica dell equazione del trasporto dell energia luminosa Generalmente i modelli di illuminazione sono approssimazioni (locali) della Rendering Equation Lighting: calcolo del bilancio luminoso Shading: calcolo del colore di ogni pixel dell immagine Effetti Globali Per motivi di efficienza nella grafica interattiva si modellano gli effetti della luce soltanto localmente Alcuni effetti sono dovuti da interazioni multiple tra materiali e non possono essere resi da modelli locali Riflessioni Ombre Color bleeding Caustics
Legge di Lambert (oggetti opachi) Materiali molto opachi (es. gesso e legno) hanno una superficie che, a livello microscopico, ha piccole sfaccettature che riflettono la luce in una direzione casuale
Legge di Lambert (oggetti opachi) Integrando su scala macroscopica: la luce si riflette uniformemente verso tutte le direzioni, con intensità proporzionale al rapporto tra la direzione del raggio incidente e la normale alla superficie in quel punto L'intensità della luce riflessa dipende (solo) dal coseno dell'angolo di incidenza della luce e non dipende dalla posizione dell'osservatore
Riflessione speculare Con una riflessione perfetta l'angolo di incidenza è uguale all angolo di riflessione Per ottenere una riflessione diffusa (specular highlight) permettiamo riflessioni anche in direzioni diverse da quella ideale Abbiamo una dipendenza dall angolo tra la direzione di riflessione ideale e la direzione di vista
Componente Ambientale Le inter-riflessioni tra oggetti diversi nella scena non sono modellate in modo accurato da un modello locale Le approssimiamo come una componente ambientale costante La componente ambientale aggiunge realismo alla scena anche se è una grossolana approssimazione dell effetto della luce indiretta
Shading I modelli di illuminazione ci dicono come calcolare l interazione tra luce e materia Adesso vediamo dove calcolarla Una soluzione è data dal flat shading: l'illuminazione viene calcolata per ogni triangolo
Flat Shading Problema: Il modello discreto rappresenta solo in modo approssimato una superficie curva e continua
Phong Shading Un'alternativa è quella di calcolare l'illuminazione per pixel Le normali si calcolano per vertice e poi il sistema le interpola per ogni pixel del triangolo
Texturing Una Texture permette di modulare un qualsiasi attributo della superficie in modo da ottenere l effetto visivo desiderato Attributi modulabili: colore, normali, trasparenza, un parametro del modello di illuminazione
Multitexturing Per ottenere effetti complessi più texture vengono combinate in un singolo passo
Texture Mapping Ad ogni vertice (di ogni triangolo) assegno le sue coordinate u,v nello spazio tessitura Così in pratica definisco un mapping fra i punti del triangolo e la tessitura
Skybox Uno skybox è un metodo per creare lo sfondo di una scena tridimensionale in modo da dare l illusione dei dintorni (distanti) della scena. Si utilizza una serie di texture opportune che rappresentano gli oggetti distanti nella scena (cielo, nuvole, montagne, ecc). La tecnica prevede che le texture siano disposte su un cubo di lato unitario con l osservatore si trova al centro del cubo.
Cube Mapping Generazione coordinate uvm, sia n=(nx, ny, nz)t il vettore normale Si sceglie la coordinata massima in valore assoluto di n, la coordinata ed il segno indicano la faccia: Esempio (-3.2, 5.1, -8.4)T, la faccia è -Z Le rimanenti coordinate, divise per il valore massimo, danno le coordinate UV nel range [-1; 1] Esempio (-3.2/8.4, 5.1/8.4)T=(-0.38, 0.61)T Per passare da un range di valori in [-1, 1] ad uno in [0, 1] si aggiunge 1 e si divide per 2 Esempio: ( (-0.38 + 1) / 2, (0.61 + 1) / 2 ) = (0.31, 0.80)
Environment Mapping Possiamo emulare le riflessioni utilizzando la direzione del raggio riflesso per indicizzare una texture map posta all'infinito Assumiamo che tutti i raggi riflessi inizino dallo stesso punto No parallasse (oggetti lontani) Illuminazione fissa Environment map: una tessitura che memorizza il colore dell ambiente riflesso
Environment Mapping
Cube Mapping Memorizziamo 6 viste dell'ambiente: una per ogni faccia di un cubo
Qual'è la differenza tra un muro di mattoni ed una fotografia di un muro di mattoni mappata su di un piano? Cosa succede se cambiamo la illuminazione o la posizione dell'osservatore? Le texture non sono efficaci nel modellare superfici ruvide Il modello di Phong funziona perché siamo ricettivi a variazioni nelle normali Perturbiamo le normali => alteriamo l'illuminazione ottenendo l'illusione di dettaglio.
Bump Mapping Usiamo le texture per modulare le normali. Una bump map è una funzione b(u,v) che rappresenta la variazione della superficie rispetto al piano del triangolo (mappa di altezze) Sia p un punto sul triangolo di coordiante texture (u,v) n la normale in (u,v) La superficie ideale passa per p+b(u,v)n La normale nel punto perturbato sarà n' = n - bv(u,v)(nxpu) + bu(u,v)(nxpv)
Esperienza Pratica
Cosa Vedremo... Geometria Definire dei modelli Metterli nella scena Ottica Effetti dell'illuminazine Shading Materiali (textures) Image Based Rendering Sfondo Riflessione Bump animate
Guida per iniziare Scaricare e decomprimere il progetto dell'esercitazione http://www.dsi.unive.it/~grafica/pls/esercitazione-orientamento.zip Aprire il file Esercitazione Orientamento - Grafica.sln
Guida per iniziare I files che vi interessano sono solo due: Scene.fs, in cui definiremo la geometria della scena Shader.fs, in cui scriveremo gli shaders dell esercitazione Dentro il file Scene.fs troviamo una serie di definizioni di vertici e indici di alcune mesh triangolari nonché la loro posizione all'interno della scena e l'effetto (shader) usato per disegnarli a schermo
Vertici Definiamo un oggetto trasformando una rappresentazione parametrica S(u,v)=(X(u,v),Y(u,v),Z(u,v)) in vertici e triangoli let plane_vertices = seq{ let pos u v = Vector3(u - 0.5f,0.0f,v - 0.5f) for i in 0..width do let u = (float32 i) / (float32 width) for j in 0..height do let v = (float32 j) / (float32 height) let p = pos u v let n = compute_normal pos u v let uv = Vector2(u,v) yield VertexPositionNormalTexture(p,n,uv) }
Indici Gli indici indicano quali terne di vertici formano un triangolo let indices = seq{ for i in 0..(width-1) do for j in 0..(height-1) do let A = (i + 0) * (width+1) + (j + 0) let B = (i + 1) * (width+1) + (j + 0) let C = (i + 0) * (width+1) + (j + 1) let D = (i + 1) * (width+1) + (j + 1) yield! [A; B; C; C; B; D] } A C B D
Oggetti e scena Un oggetto è dato da un insieme di vertici, di indici, un effetto con cui disegnarlo a schermo (illuminazione) e da una trasformazione che lo posiziona nella scena let plane = { Vertices = plane_vertices; Indices = indices; Effect = Shader.uniform_red; Transform = { Position = -Vector3.UnitY; Scale = 1.0f; Rotation = Vector3(0.75f,0.0f,0.0f) } } La scena è definita come una sequenza di let scene = seq{ yield plane }
Shader Gli shaders sono definiti nel file shader.fs. Uno shader è composto di: Una serie di dichiarazioni di parametri globali Una serie di dichiarazioni di textures Un vertex e un pixel shader let uv_mapping = <@@ let World let View let Projection = parameter() : Matrix = parameter() : Matrix = parameter() : Matrix Parametri globali let ColorTexture = parameter() : Texture2D let ColorSampler = { Texture = ColorTexture } Textures let vertex_shader (InputPosition(pos)) (InputTexCoord(uv)) = let worldposition = pos * World let viewposition = worldposition * View let pos' = viewposition * Projection Vertex shader in OutputPosition(pos'), OutputTexCoord(uv) let pixel_shader (InputTexCoord(uv)) = OutputColor(ColorSampler.Lookup(uv)) in () @@> Pixel shader
Parametri globali let World let View let Projection = parameter() : Matrix = parameter() : Matrix = parameter() : Matrix let LightPosition = parameter() : Vector3 let Time = parameter() : float32 let ColorTexture = parameter() : Texture2D let ColorSampler = { Texture = ColorTexture } let HeightmapTexture = parameter() : Texture2D let HeightmapSampler = { Texture = HeightmapTexture } let BoxTexture = parameter() : TextureCube let BoxSampler = { TextureCube = BoxTexture }
Parametri degli shader Parametri di input InputPosition InputWorldPosition InputWorldNormal InputTexCoord InputNormal InputColor of of of of of of Vector4 Vector4 Vector3 Vector2 Vector3 Vector4 of of of of of of Vector4 Vector4 Vector3 Vector2 Vector3 Vector4 Parametri di output OutputPosition OutputWorldPosition OutputWorldNormal OutputTexCoord OutputNormal OutputColor
Mesh con Colore Uniforme Inserire una mesh nella scena e attaccarci uno shader che colora ogni pixel di rosso Partire dal plane_vertices e cambiare la funzione pos in modo da alterare la mesh (e.g. 0.2f*cos(pi*u)*sin(pi*v) ) Completare lo shader uniform_red
Illuminazione di Lambert Modificate lo shader in modo da aggiungere l'illuminazione diffusa (Lambert) Portate la normale in world e calcolate le direzione di luce nello stesso sistema di riferimetno let L = Vector3.Normalize(LightPosition - WorldPosition.XYZ)
Illuminazione Completa Aggiungere le componenti speculari e ambiente Calcolare la posizione dell'osservatore nella scena dalla trasformazione view: eye_position = -Vector3(View.M41, View.M42, View.M43) Per calcolare la riflessione esiste la funzione Vector3.Reflect: R = Vector3.Reflect(-V,N) Altre funzioni utili sono: Vector3.Dot(v,w): Calcola il prodotto scalare tra v e w Vector3.Saturate(x): limita x tra 0 e 1
Texture Creare un nuovo shader che assegna il colore prendendolo da una texture Definire texture e texture sampler: let ColorTexture = parameter() : Texture2D let ColorSampler = { Texture = ColorTexture } Ottenere il colore della texture alla coordinata uv con ColorSampler.Lookup(uv)
Texture e Illuminazione Alterare lo shader in modo da aggiungere il modello di iluminazione completo Fate in modo che a texture moduli le componenti diffusive ed ambientali
Skybox Cambiate lo sfondo copiando il file Game Host\Game HostContent\mountains.dds in Game Host\Game HostContent\background.dds Cambiate la mesh con sphere_vertices
Environment Mapping Fate in modo che la sfera rifletta lo sfondo Definite i nuovi texture e texture sampler: let BoxTexture = parameter() : TextureCube let BoxSampler = { TextureCube = BoxTexture }
Gran Finale Create la pozza d'acqua animata Rimettete come unico oggetto una mesh piana Campionate le normali ottenute dalla bumpmap attraverso la funzione sample_normal