Försättsblad till skriftlig tentamen vid Linköpings Universitet (fylls i av ansvarig) Datum för tentamen Sal Tid Kurskod Provkod Kursnamn/benämning Institution Antal uppgifter i tentamen Antal sidor på tentamen (inkl. försättsbladet) Jour/Kursansvarig Telefon under skrivtid Besöker salen ca kl. Kursadministratör (namn + tfnnr + mailadress) Tillåtna hjälpmedel Övrigt 2015-06-03 TP51, TP53, TP56 8-12 TNM061 TEN1 3D datorgrafik ITN 8 6 Stefan Gustavson 011-363191 Kontinuerligt Lesley Bornhöft, 011-363254, lesley.g.bornhoft@liu.se Inga
Tentamen TNM061, 3D-grafik och animering för MT2 Onsdag 3/6 2015 kl 8-12 Inga hjälpmedel Tentamen innehåller 8 uppgifter, vilka tillsammans kan ge maximalt 50 poäng. För betyg G (registreras som sifferbetyg 3) erfordras minst 25 poäng. För betyg VG (registreras som sifferbetyg 5) erfordras minst 36 poäng. Deluppgifterna bygger inte alltid direkt på varandra, så läs t ex b) även om du inte svarar på a). Svara kortfattat men rimligt fullständigt på uppgifterna. Förutsätt inte att läsaren redan kan svaret, utan visa med ditt svar att du kan ämnet och att du förmår förklara det för andra. Förklara införda beteckningar och ekvationer, och redovisa eventuella beräkningar. Rita figurer där det gör svaret tydligare. Glöm inte heller bort att förklara dina figurer i ord eller i ekvationer. För uppgifter som ger många poäng vill jag se rimligt utförliga svar för full poäng, men för uppgifter med enstaka poäng räcker det med korta svar. Även korta svar skall vara tydliga. Jag kommer att befinna mig i närheten av tentamenslokalen och besöka den flera gånger under tentamenstiden för att svara på eventuella frågor. Kontakta tentamensvakten om du behöver få tag i mig mellan dessa tillfällen. Lycka till! Stefan Gustavson
Uppgift 1 (9 p). Phongs klassiska lokala reflexionsmodell med tre termer för allmänljus, diffus reflexion och spekulär reflexion brukar traditionellt presenteras med följande förenklade ekvation: L)+ I s k s ( R V )n I =I a k a+ I d k d ( N a) Förklara med en tydlig figur vad var och en av de ingånde vektorerna N, L, R, V representerar. (2 p) b) Vi struntar i I a, k a och sätter I s=i d, vilket man ofta gör. Förklara tydligt vad var och en av de ingående parametrarna I d, k d, k s, n representerar. (2 p) c) Om man verkligen ska implementera modellen i programkod i en shader måste man tänka på flera saker som inte framgår av den förenklade ekvationen. Vinkelberoendet mellan vektorerna N och L beräknas t ex med en skalärprodukt. Vad händer om vinkeln mellan vektorerna är större än 90 grader? Hur hanterar man det? Hur väl motsvarar det vad som händer i verkligheten? (2 p) d) Nästan samtliga ingående parametrar beror på olika sätt av vilken punkt p=(p x, p y, pz ) på ytan av ett visst objekt som man räknar på, men det framgår inte av ekvationen. För normalriktningen N är det ganska självklart att den beror på p, men förklara varför var och en av I d, k d och L i den diffusa termen också bör kunna bero av p för att få god realism! (3 p) Uppgift 2 (4 p). Bilden till höger visar ett mönsterlagt marmorgolv i er examinators trappuppgång. Om ytan skulle efterliknas i en syntetisk scen skulle man behöva modellera mönstret på något sätt. Beskriv såväl fördelar som nackdelar med var och en av nedanstående två metoder för att göra detta specifika mönster! a) Golvet görs som ett enda plan med en bildbaserad textur. b) Golvet modelleras med separata objekt för de svarta och vita stenarna. Uppgift 3 (4 p). Ett sätt att skapa texturer för datorgrafik är med så kalllade procedurella texturer, mönster som beräknas utifrån matematiska uttryck i stället för att man läser pixels från en förlagrad digital bild. Beskriv minst två potentiella fördelar och minst två potentiella nackdelar med metoden.
Uppgift 4 (6 p). Bilden nedan visar en verklig scen som skulle vara lämplig att efterlikna med raytracing. Förklara rimligt ingående hur följande pixels i bilden skulle beräknas med raytracing! a) En pixel på den speglande sfären som reflekterar en punkt på det matta rutiga underlaget. (2 p) b) En pixel på den blanka tekannan som inte ligger i skugga. (2 p) c) En pixel någonstans på det matta rutiga underlaget som skuggas av den speglande sfären. (2 p) Uppgift 5 (4 p). Bilden till höger visar ett foto på en kristallkrona i gustaviansk stil. Två tydliga och förhållandevis viktiga ljuseffekter från en kristallkrona är svåra att modellera i datorgrafik. Förklara varför klassisk raytracing inte kan modellera effekterna i a) och b) nedan. (Det går att utöka och modifiera metoden till att klara det, men det ignorerar vi här.) a) Det ojämna ljusmönstret i taket som kommer sig av brytningen i prismorna. (2 p) b) Skimret i regnbågens alla färger från prismorna som kommer sig av att kristallglasets brytningsindex varierar med ljusets våglängd. (Effekten syns tyvärr inte särskilt bra på fotot. Det är svårt att fotografera ljuskällor.) (2 p) Uppgift 6 (6 p). En kubisk Béziérkurva definieras av ekvationen: p(t)=(1 t)3 p0 +3t (1 t)2 p 1+3t 2( 1 t) p2 +t 3 p3, 0 t 1 där pi är kurvans kontrollpunkter, i=0, 1,2, 3. Om alla kontrollpunkter ligger på en sträcka mellan punkterna pa och pb så kommer alla kurvans punkter också att ligga på den sträckan. Visa detta!
Uppgift 7 (8 p). Spelet Quake från 1996 var en så kallad first person shooter, och ett av de allra första spelen för PC som genomgående använde riktig 3D-grafik. Såväl omgivningen som de animerade fienderna renderades som texturerade och ljussatta polygonmodeller. En bild från spelet i upplösningen 320x240 pixels (vilket var en vanlig skärmupplösning i dataspel för PC för 20 år sedan) visas här ovan. Quake skrevs från början för att renderas helt på en (långsam) CPU, men det var ett av de första spelen som skrevs om till att använda OpenGL när de första rimligt billiga 3D-grafikkorten till PC började dyka upp. Eftersom allt redan var polygoner så var det ganska lätt att göra om det. Tekniken för rendering i moderna datorspel är fortfarande i princip densamma som för det nästan 20 år gamla Quake, men bildkvaliteten är naturligtvis mycket bättre i dag. Förklara utifrån bilden vad som skulle behöva förbättras med Quake för att ge ett visuellt intryck som bättre motsvarar dagens krav på kvalitet. Ge minst fyra exempel på vad som kunde förbättras, hur det kunde förbättras, och vilken visuell skillnad den förbättringen skulle medföra. (2 p per relevant och väl beskrivet exempel, upp till max 8 p)
Uppgift 8 (9 p). Man vill rita en animerad teddybjörn med OpenGL och C++ på ett strukturerat sätt. Teddybjörnen har rörliga armar, ben och huvud. En verklig teddybjörn med de rörelsemöjligheterna finns i tentamenslokalen om du vill testa. (Det är helt OK att klappa honom också.) a) Scengrafen här bredvid är ett misslyckat försök att beskriva teddybjörnen. Hierarkin är felaktig, eller åtminstone väldigt olämplig. Rita om grafen så att problemet åtgärdas. (3 p) b) Skriv programkod i C++ som renderar teddybjörnen enligt strukturen i den scengraf du angav ovan. (Om du inte har svarat på a) kan du i stället skriva kod som renderar teddybjörnen enligt den givna, något felaktiga grafen. Detta ger inget poängavdrag, men tala om vilken graf du skriver kod för.) (6 p) För att rita objekt har du en enkel klass Mesh som renderas med metoden: Mesh.render(Matrix M); Matrisen högst upp på matrisstacken M används för att transformera objektet vid renderingen. Teddybjörnens kroppsdelar finns som objekt av typen Mesh med namnen TeddyHead, TeddyRightArm, TeddyLeftArm, TeddyBody, TeddyRightLeg och TeddyLeftLeg. Gör själv lämpliga antaganden om hur deras koordinatsystem är orienterade. Till din hjälp har du även klassen Matrix som implementerar en matrisstack enligt följande: Matrix.pop() Tag bort den översta matrisen från stacken. Matrix.push() Skapa en kopia av den översta matrisen och lägg den överst på stacken. Matrix.init() Tag bort alla matriser från stacken och lägg en enhetsmatris överst. Matrix.rotateX(phi) Multiplicera den översta matrisen med en rotationsmatris som roterar vinkeln phi runt x-axeln. Matrix.rotateY(phi) Multiplicera den översta matrisen med en rotationsmatris som roterar vinkeln phi runt y-axeln. Matrix.rotateZ(phi) Multiplicera den översta matrisen med en rotationsmatris som roterar vinkeln phi runt z-axeln. Matrix.translate(tx, ty, tz) Mutliplicera den översta matrisen med en translationsmatris.