3D, transformationer och visualisering Föreläsning 6 Innehåll 3D grunder och matematiska verktyg Lite om 3D-transformationer Introduktion till 3D-visualisering Algoritmer i objekt respektive bildrymden
Tredimensionella metoder Kamerametafor Man brukar använda en analogi med en kamera som placeras, riktas och flyttas i världen Visualisering Vi kan visualisera "realistiskt" med texturer/material, belysning, reflektion, skuggor, borttagning av skymda ytor osv eller mha tex ståltrådsmodeller Vi kan visa objekt i perspektiv- eller parallell projektion Vid kan använda ledtrådar om avstånd genom att variera färgtonen Vi kan visa spränskisser Stereobilder kan användas osv
Grundläggande typer av objekt I datorgrafik jobbar vi med dom grundläggande matematiska objekten (och datatyperna) punkt skalär vektor
Matematiska verktyg Skalärprodukt Kryssprodukt Planets ekvation Normal cosinus för vinkeln mellan två vektorer Kryssprodukt ger ortogonal vektor Planets ekvation Koplanära vektorer Normal ytans riktning
... Matriser Koordinatsystem vi använder matriser för att beskriva transformationer Koordinatsystem objekt definieras i förhållande till koordinatsystem
Omslutande volymer För att reducera arbetsmängden vid test av skärning Två objekt och deras projektion på xy-planet där normalisering och perspektivtransformation redan gjord I bilden överlappar ej rektanglarna så inga vidare tester för skymda ytor behöver göras y x z Konvexa höljet
forts om omslutande rektanglarna överlappar finns två möjligheter objekten skär varandra objekten skär inte varandra
Dom tredimensionella primitiverna I tre dimensioner har vi flera olika primitiva objekt som: kurvor och linjer ytor av olika slag olika typer av tredimensionella objekt sfär, rätblock, pyramid, etc
Exempel: konstruera roterande kub Några distinkta steg som måste utföras modellera sätt upp kamera och visualiseringsvolym klipp projicera ta bort skymda ytor rastrera
Definiera ytor och normaler Högerhandsregeln tummen i normalens riktning typedef point float[3]; point node[8] = { {-1.0,-1.0,-1.0},{1.0,-1.0,-1.0}, {1.0,1.0,-1.0},{-1.0,1.0,-1.0}, {-1.0,-1.0,1.0},{1.0,-1.0,1.0}, {1.0,1.0,1.0},{-1.0,1.0,1.0}}; glBegin(GL_POLYGON); glVertex3fv(node[0]); glVertex3fv(node[3]); glVertex3fv(node[2]); glVertex3fv(node[1]); glEnd();
Beskrivning av polyeder Objektet beskrivet som en följd av ytor där var och en av ytorna beskrivna som ordnade listor med vertex. Högerhandsregeln ger normalen.
Färg given för vissa vertex Färgen på ytor mellan hörnen beräknas genom bilinjär interpolation GLfloat colors[][3] = { {0.0,0.0,0.0},{1.0,0.0,0.0}, {1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {1.0,1.0,1.0}, {0.0,1.0,1.0}}; glBegin(GL_POLYGON); glColor3fv(colors[0]); glVertex3fv(node[0]); glColor3fv(colors[3]); glVertex3fv(node[3]); /* och så vidare ... glEnd();
Ibland effektivt ”beräkna” färg vid utritningen Vid varje sveplinje interpoleras aktuell färg fram från färgen på hörnen och kanterna
I tre dimensioner använder vi precis som i 2D homogena koordinater Därmed kan vi behandla transformationer på ett uniformt sätt Matrisen och representationen av punkterna i 3D blir i stil med
Som i 2D, fast en dimension till Translation Som i 2D, fast en dimension till
Rotation kring z-axeln kring x-axeln kring y-axeln
Rotation kring fixpunkt 1. Flytta fixpunkt till origo 2. Rotera 3. Flytta tillbaks fixpunkt
...
Generell rotation kring rotationsaxel 1. Translatera objektet så att rotations- axeln passerar genom origo 2. Rotera objektet så att rotationsaxeln sammanfaller med önskad koordinataxel 3. Rotera specificerad vinkel runt axeln 4. Invertera rotationen från steg 2 5. Invertera translationen från steg 1
...
Skalning med avseende på fixpunkt På ungefär samma sätt som i 2D 1. Translatera fixpunkten till origo 2. Skala objektet 3. Invertera translationen från 1
Visualiseringspipeline Modell koordinater Vytransformation Modelltrans- formation Världs-koordinater Vykoordinater Projektions- koordinater Projektions- transformtion Transfomation till arbetstation Enhets-koordinater
Specificera utritningsplanet Vi börjar med att ansätta ett koordinatsystem genom att: ange referenskoordinatsystem relativt världskoordinatsystemet definiera projektionsplan välja positiv riktning för projektionsplanet, genom att ange en normalvektor vi ger en vektor som anger vad som är uppåt
Exempel: Vi positionerar kameran i OpenGL I OpenGL kan vi ange var ögat finns, vart vi tittar och vad som är uppåt
Transformation från världs- till vykoordinater Görs på liknande sätt som vid transformationer av enskilda objekt dvs använd en transformationsmatris för att transformera det ena korrdinatsystemet till det andra
Perspektivprojektion Projektioner Perspektivprojektion projektionscentrum
... Parallellprojektion
Parallella projektioner projektionsplan
Perspektivprojektioner projektionscentrum
”Klassiska” visualiserinssätt
Ortografisk projektion Projektorerna vinkelräta mot projektionsplanet
... Ett tempel och tre ortografiska projektioner av det
Axonometrisk projektion Projektorerna (fortfarande) ortogonala mot projektionsplanet, men projektionsplanet kan ha godtycklig orientering i förhållande till objektet
Symmetriska projektioner Om vinkel projektionsplanets normal bildar med koordinataxlarna uppfyller vissa villkor har projektionen eget namn Dimetrisk symmetrisk med avseende på två axlar Isometrisk symmetrisk med avseende på alla tre axlarna Trimetrisk generella fallet
Oblique projektion Projektorerna parallella men ej ortogonala mot projektionsplanet Specialfall Cabinet (med djupet = halva bredden)
Perspektiv tvåpunkts trepunkts enpunkts
Ortogonal projektion z-komponenten sätts till noll
Utritningsvolymer och generella projektionstransformationer I OpenGL anger vi visualiseringsvolym Objekt utanför denna volym klipps bort Man talar om att kameran har en vinkel för visualiseringsplanet (angle of view)
Vi anger klipplan Den resulterande trunkerade pyramiden brukar kallas för frustum
Alternativa sätt att ange volymen Vi kan istället ange vyvolumen genom att ange en vinkel och ett förhållande mellan bredd och höjd
Perspektivtransformation Punkter på samma projektionslinje Två punkter på samma projektionslinje i perspektivprojektion om: i parallellprojektion om: Om vi normaliserar vyvolymen och (perspektiv-) transformerar projektionspunkten till oändligheten så blir problemet med att avgöra om en punkt skymmer en annan detsamma som vid parallellprojektion dvs enklare beräkningar p3 projektions- centrum p1 p2
Normaliserade koordinater Många algoritmer förenklas om tester utförs först efter transformation till normaliserade enhetskoordinater (kanonisk form)
Borttagning av skymda ytor Problem Avgöra vad i scenen som syns från en given punkt Alternativ formulering Avgöra vilka delar av scenen som INTE syns
Typer av algoritmer Algoritmerna är av två olika huvudtyper som beror av om dom baseras direkt på objektens definition eller deras projektioner. Nämligen om avgörandet sker i: Objektrummet Jämför objekt och delar av dem för att avgöra vad som syns Bildrymden Vad som syns avgörs pixel för pixel på projektionsplanet
Algoritmer i objektrummet Också kända som objektprecisionsalgoritmer Algoritm (principskiss) for (varje objekt i världen){ hitta delar av objektet som inte är skymda av andra delar eller andra objekt; rita dessa delar} Komplexitet jämföra varje (n) objekt med varje annat n ** 2
Sammanfattning: principer för att rita objekt ”objektorienterade” också kända som ”sortera först” För varje objekt rita objektet ”avbildningsorienterade” också kända som ”sortera sist” för varje pixel tildela en färg
Olika fall Ett objekt skymmer helt ett annat Objekten skymmer inte varandra Det ena objektet skymmer delvis det andra eller vice versa Det sista fallet är mest komplicerat
Borttagning av ytor med normalen riktad bort från betraktaren Om projektionscentrum i (x’, y’, z’) är varje plan som uppfyller Ax’ + By’ + Cz’ + D < 0 bortriktat Normalen för ett bortriktat plan bildar en icke negativ skalärprodukt med vektorn från projektionscentrum till någon punkt på planet B A C D E H F G
...forts Om projektionsriktningen är längs z-axeln kan vi göra ett enklare test genom att enbart betrakta planets normalvektorer (A, B, C) Om C < 0 så är normalen riktad bort från betraktaren och därmed är planet en “baksida” Om världen endast består av en enda konvex polyeder så är testet tillräckligt annars kan “framsidor” som C och E i figuren ändå vara skymda och vi måste testa vidare i medeltal elimineras i alla fall hälften av ytorna
Algoritmer i bildrymden Också kända som bildprecisionsalgoritmer Algoritm (principskiss) for (varje pixel i bilden){ hitta det objekt som är närmast betraktaren på en projektionslinje genom pixeln; rita pixeln} Komplexitet (brutal metod) kräver att vi för varje pixel undersöker alla n objekt för att avgöra vilket som är närmast, dvs för p pixlar krävs np jämförelser
Vilken typ av algoritm är bäst? Man kan tro att objektalgoritmer är bättre än bildalgoritmer då n < p. Men i objektalgoritmer är ofta varje steg betydligt mer komplext och tidskrävande än i bildalgoritmer. Ofta är objektalgoritmer också svårare att implementera. Objektalgoritmer är bättre då vi tex vill ändra upplösning Bildalgoritmer är förutom att dom oftast enklare att implementera också snabbare. Det finns också algoritmer som kombinerar de två strategierna.
Z-buffer-algoritmen Synonym: djupbuffertalgoritmen Idé testa en punkt (x, y) i taget ytan med största z-koordinat är synlig y x (x, y) z
...z-buffer forts Algoritm /* Initiera */ sätt alla pixlar till bakgrundsfärgen, dvs WritePixel(x, y, bakgrundsfärg); WriteZ(x, y, 0) för varje punkt; /* gå igenom alla polygoner */ for (varje polygon){ for (varje pixel i polygonens projektion){ pz = polygonens z-värde i (x, y); if (pz >= ReadZ(x, y)){ WriteZ(x, y, pz); WritePixel(x,y, färg(poly, x, y)) }
... Vi kan lösa z ur Vi kan utnyttja djupkoherens, dvs utnyttja att en polygon är planär Vi kan konstruera en inkrementell algoritm som därmed är beräkningsmässigt mer effektiv Om polygonen inte är planär kan z-värdet interpoleras fram från olika kantpar
... z-värdet för en position (x, y) fås ur nästa z-värde (med sveplinje i x-led) kan sen beräknas ur nästa värde i y-led kan fås på samma sätt, dvs
...z-buffer forts Fördelar Problem enkel att implementera snabbheten oberoende av antal polygoner (antal pixlar som täcks av viss polygon minskar då antalet polygoner ökar) kan enkelt hantera “layers” (som inte lagras i z-bufferten) kan sparas Problem minneskrävande kan klaras av genom att ett “band” i taget av bilden beaktas objekt långt bort kan avrundas (transformeras) till samma z-värde även om dom inte hade gjort det om dom var närmare vypunkten aliasing, avrundningar kan ge upphov till att delade kanter kan få olika z-värden. Kan lösas genom att nya vertex införs.