Raytracing. Codeboekje. Didier Collard Simon Koolstra

Maat: px
Weergave met pagina beginnen:

Download "Raytracing. Codeboekje. Didier Collard Simon Koolstra"

Transcriptie

1 Raytracing Codeboekje Didier Collard Simon Koolstra

2

3 Stedelijk Gymnasium Johan van Oldenbarnevelt Profielwerkstuk Raytracing Door: Didier Collard Simon Koolstra Begeleider: Drs. R.M. Boers December 2009

4 Inhoudsopgave Voorwoord 3 Inleiding 4 1 Basis wiskunde Vectoren Matrices Verzamelingenleer Eenheidsobjecten Orthonormale basissen Alternatieve coördinatensystemen Steradiaal Kleuren in de raytracer Bronnen en code Objecten en rays Objecten Rays En de raytracer? Bronnen en code Rayintersectie Intersectie met impliciete oppervlakken Intersectie met begrensde vlakken En de raytracer? Bronnen en code Camera en perspectief Perspectief Camera En de raytracer? Bronnen en code Sampling Aliasing Sampling Gebruik van de samples En de raytracer? Bronnen en code

5 INHOUDSOPGAVE 2 6 Licht Rendervergelijking Lichtbronnen Shading Renderen En de raytracer? Bronnen en code Transformatie Verschillende transformaties Transformaties in 2D Transformaties in 3D Rayintersectie met getransformeerde objecten En de raytracer? Bronnen en code Geavanceerde Objecten en Intersecties Cilinders Polygon Meshes En de raytracer? Bronnen en code Textuur Het proces Texturen op verschillende objecten Objecten met textuur op andere plekken in de wereld En de raytracer? Bronnen en code Spiegelreflectie Het principe Het model En de raytacer? Bronnen en code Breking Het principe Het model En de raytracer? Bronnen en code Conclusie Samenvatting Wat had nog meer gekund? Onze raytracer Werking Gebruik Bibliografie 88

6 Voorwoord Sinds het begin van ons vijfde schooljaar op het Johan van Oldenbarneveltgymnasium zijn we bezig geweest met het oriënteren op een vervolgopleiding. Al gauw bleek dat wij beiden interesse hebben in zowel wiskunde als informatica. Geen onlogische keuze dus om voor een profielwerkstuk een onderwerp te zoeken dat met deze beide onderwerpen te maken heeft. Al snel hadden we zo n onderwerp gevonden. We werden getipt over een masterclass van de Technische Universiteit Eindhoven over het onderwerp raytracing. Dit onderwerp bleek uitdagend en interessant en naar aanleiding van deze masterclass zijn we de weg vrij gaan maken voor het profielwerkstuk. Raytracing, zoals u waarschijnlijk niet zult weten, is een techniek voor het genereren van 2D beelden op een computer. De computer leest een beschrijving van een 3D wereld en zet dit door middel van uitgestuurde stralen, de zogenaamde rays, om in een, meestal erg realistisch, 2D plaatje. Dit klinkt op dit moment misschien nog allemaal erg abstract en onduidelijk, maar gaandeweg zullen we u uitleggen hoe dit nu precies werkt en hoe men een computer zover kan krijgen om dit uit te voeren. Als u het op dit moment nog niet hebt opgegeven, wensen we u veel plezier met het lezen van ons profielwerkstuk. Met vriendelijke groeten, Didier Collard & Simon Koolstra 3

7 Inleiding Al jaren is men in de moderne computerwetenschappen op zoek naar manieren om plaatjes met de computer zo realistisch mogelijk te maken. De filmindustrie, met al haar films vol special effects en onbestaande wezens, en de game-industrie, bijvoorbeeld, hebben veel baat bij de (redelijk) recent populair geworden methode van het raytracen. Door jarenlang onderzoek en steeds betere raytracing programma s, zien we raytracing opkomen als de belangrijkste methode om plaatjes te renderen. 1 Zoals gezegd is raytracing een manier om erg realistische plaatjes in 2D te maken. Het maken van tweedimensionale plaatjes is belangrijk omdat een scherm alleen afbeeldingen in tweedimensies kan laten zien. Een scherm heeft namelijk alleen een breedte en een hoogte! Raytracing is dan ook ontwikkeld uit de vraag hoe je zo goed en realistich mogelijk een driedimensionale scène naar een tweedimensionale afbeelding kunt omzetten. In ons profielwerkstuk zullen we de basis van het raytracen uitleggen. Het belangrijkste principe van raytracing is dat het gebaseerd is op wat er in de echte wereld gebeurt. Het werkt met een model van de werkelijkheid, maar dan nét iets anders. In het echt zien wij dingen, doordat er licht door deze objecten wordt weerkaatst. Dit licht bereikt ons netvlies en onze hersenen kunnen van deze impulsen een beeld maken: het beeld dat wij zien. Om een erg realistisch plaatje te renderen, zouden we dit kunnen nabootsen. We zouden vanuit elke lichtbron in een scène in alle richtingen lichtstralen kunnen sturen en vervolgens kijken welke lichtstralen ons oog bereiken en hiermee een plaatje renderen. We zouden de stralen volgen, oftewel: we would trace the rays. Dit zou echter een hels karwei zijn. Om namelijk vanuit één lichtbron al in álle richtingen stralen af te sturen zijn oneindig veel stralen nodig. Om dit te benaderen zouden we dus al duizenden, misschien wel miljoenen stralen nodig hebben. En dat is nog maar voor één punt, op één lichtbron. Daarbij bereikt meer dan 99% van deze stralen ons oog helemaal niet! Het zou Figuur 1: Het principe van raytracing [2] dus een gekkenwerk zijn om deze stralen toch allemaal te bekijken en zelfs met meerdere computers zou het tijden duren om een plaatje te renderen. In raytracing wordt het dus anders aangepakt. Bij het raytracen doen we precies het omgekeerde van wat er in de natuur gebeurt. In plaats van dat we gaan kijken waar alle lichtstralen van elke lichtbron terechtkomen, gaan we vanuit het oog kijken welke lichtstralen het oog bereiken. In plaats van het uitsturen van lichtstralen vanaf elke lichtbron, sturen we zogenaamde rays uit vanuit het oog en kijken we wat er met deze rays in de scène gebeurt. We volgen dus de stralen die we vanuit het oog uitsturen: we trace the rays! Deze stralen gaan dus precies in de tegenovergestelde richting van de lichtstralen in het echt. We bekijken vervolgens of een ray vanuit het oog een object raakt. Is dit het geval dan kunnen we op het punt waar de straal het object raakt weer kijken hoeveel licht er op dit punt valt, of er weerkaatsing optreedt en meer van dat soort aspecten. Vervolgens 1 Met renderen bedoelen we het genereren van plaatjes door de computer. 4

8 INHOUDSOPGAVE 5 zullen we van al deze aspecten berekenen hoeveel effect ze hebben op de kleur van een bepaald punt en hiermee kunnen we voor elke pixel uiteindelijk een kleur berekenen. Doordat we zo dicht mogelijk bij de werkelijkheid blijven, zullen we uiteindelijk met al deze kleuren een erg realistisch plaatje kunnen bouwen. In figuur 1 zien we het principe van raytracing. Vanuit het oog sturen we rays uit, we zien er hier één afgebeeld. Deze ray raakt de groene bol. Vanaf het raakpunt met de groene bol worden weer rays uitgeschoten om te kijken of het punt licht ontvangt van lichtbronnen, of via reflectie van andere objecten. Het proces van het afschieten van rays en kijken wat er met deze rays gebeurt, is een proces, dat zich steeds herhaalt. Hierdoor is raytracen een rekenintensief en langdurig proces. Vaak gebeurt dit dus ook nog niet real-time 2, omdat de hedendaagse computers dit nog niet snel genoeg kunnen doen. Ondanks dit alles zijn er tegenwoordig al veel projecten gaande om raytracing toch real-time te kunnen laten voltrekken. Hoe het proces van raytracing precies werkt zullen we gaandeweg steeds verder uitleggen, waarbij we dieper ingaan op onderwerpen als licht, reflectie, breking, het plaatsen en raytracen van objecten en aliasing. Om alvast een voorproefje te krijgen van wat een volgroeid raytracer voor plaatjes zou kunnen creëren, kunt u een blik werpen op figuur 2. Onze raytracer Aansluitend op dit werkstuk hebben we onze eigen raytracer gebouwd, waarin alle theorie die in dit werk beschreven staat, wordt toegepast. Meer informatie over onze raytracer en het gebruik daarvan is terug te vinden in het laatste hoofdstuk op bladzijde 81. Op kunt u de raytracer, de broncode en dit profielwerkstuk downloaden. Opmerking over figuren Tot slot hebben we nog een opmerking over de afbeeldingen die we in dit profielwerkstuk hebben gebruikt. Wij hebben bij elke afbeelding die we niet zelf hebben geproduceerd (dan wel met de raytracer, dan wel op andere wijze) een bronvermelding gegeven. Ieder figuur zonder verwijzing is dus een door onszelf gemaakte afbeelding. Figuur 2: Een plaatje gerenderd door een raytracer. [3] 2 Real-time betekent dat het plaatje pas gerenderd wordt als het nodig is. Real-time zien we vooral bij interactieve zaken, zoals computerspellen en dergelijke.

9 Hoofdstuk 1 Basis wiskunde Voor het begrijpen van het proces van raytracing is een zeker basisniveau op het gebied van wiskunde nodig. Omdat niet alles als bekend mag worden verondersteld, hebben we dit hoofdstuk ingericht om een aantal wiskundige onderwerpen die veel voorkomen uit te leggen en begrijpelijk te maken. Een aantal onderwerpen die we wél als bekend veronderstellen zijn: goniometrische functies (het werken met sinus, cosinus en tangens en al de bijbehorende rompslomp), integratie, differentiatie, basis meetkunde en werken in 3D ruimtes. De onderwerpen die wel aan de orde worden gesteld zijn: vectoren, matrices, eenheidsobjecten, een basis voor verzamelingenleer, orthonormale basissen en assenstelsels, alternatieve coördinatensystemen en de steradiaal. Tenslotte zullen we nog aangeven hoe kleuren gedefinieerd worden in onze raytracer. 1.1 Vectoren Wat zijn vectoren? Vectoren zijn grootheden die een lengte en een richting hebben. De richting van een vector wordt vaak aangegeven door de vector als een pijl te tekenen. De lengte van de pijl geeft hierin de grootte aan. Een vector in een 2D stelsel met (bijvoorbeeld) een x en een y-as wordt gedefinieerd door twee ( waarden: de x-waarde en de y-waarde. Dit wordt dan als x volgt genoteerd:. Een voorbeeld van zo n vector zie je in figuur 1.1. Deze y) vector begint in de oorsprong en heeft de kentallen (x, y). Deze eindigt dus in punt (x, y). Een vector hoeft niet altijd in de oorsprong te beginnen en eindigt dus lang niet altijd op zijn kentallen (x, y). Een vector wordt door ons weergegeven als een letter met een pijltje erboven, bijvoorbeeld: a. De lengte van een vector kunnen we berekenen met de stelling van Pythagoras: a = x 2 + y 2. a betekent: de lengte van vector a. In een 3D stelsel wordt een vector gedefinieerd door drie kentallen: de x-waarde, x de y-waarde en de z-waarde. Deze zien er als volgt uit: y. De lengte van zo n z vector kan worden berekend door de stelling van Pythagoras in 3D toe te passen. Dit gaat als volgt: a = x 2 + y 2 + z 2. Figuur 1.1: Een vector vanaf de oorsprong met richting x, y. 6

10 HOOFDSTUK 1. BASIS WISKUNDE Operaties met vectoren Vectoren kunnen gewoon bij elkaar worden opgeteld en van elkaar worden afgetrokken. Er ontstaan dan nieuwe vectoren. Hieronder staat hoe dat gaat: a + a x b x a x + b x b = a y + b y = a y + b y a z bz a z + b z a a x b x a x b x b = a y b y = a y b y a z bz a z b z Ook ontstaan er vectoren als punten van elkaar worden afgetrokken. Als we bijvoorbeeld het punt p hebben met coördinaten (p x, p y, p z ) en punt c met coördinaten (c x, c y, c z ) en we trekken c van p af, krijgen we de vector met een richting van c naar p: p x c x cp = p c = p y c y p z c z Verder kunnen vectoren niet door elkaar worden gedeeld. Wel kunnen vectoren met elkaar worden vermenigvuldigd. Dit kan op twee manieren: met het inwendig product (het inproduct) en met het uitwendig product (het uitproduct). Het inwendig product geeft één waarde, een getal. We geven het inproduct van twee vectoren als volgt aan: a b en we kunnen dit op twee manieren berekenen: a b = a b cos θ a b = a x b x + a y b y + a z b z Hierin is θ de hoek tussen de twee vectoren. Beide manieren komen op hetzelfde uit en het hangt van de situatie af welke wordt gebruikt. Het uitproduct geeft als uitkomst een vector die loodrecht op het vlak van de twee andere vectoren staat. Het uitproduct van twee vectoren geven we zo aan: a b en berekenen we op de volgende manier: a a y b z a z b y b = a z b x a x b z a x b y a y b x Ook kan een vector worden vermenigvuldigd met of gedeeld worden door een gewoon getal. We krijgen dan: va x v a = va y va z a x a v v = a y v Ook kunnen we een negatieve vector nemen. Hierin is - a dezelfde vector als a maar dan in tegengestelde richting Normaalvectoren Een normaalvector is een vector die loodrecht op iets staat. We kunnen bijvoorbeeld een normaalvector van een vlak, een bol of een lijn nemen. Normaalvectoren zijn uitermate belangrijk bij het raytracen. We zullen een normaalvector op twee manieren bepalen. Twee vectoren die loodrecht op elkaar staan (dus die elkaars normaalvectoren zijn) maken een hoek van 90 met elkaar. Hieruit volgt dat het inproduct van deze twee vectoren nul is, want de cosinus van een hoek van 90 graden is nul. Hieruit volgt de volgende vergelijking voor de normaal van a: n a = 0 a z v

11 HOOFDSTUK 1. BASIS WISKUNDE 8 Als we een normaalvector van een vlak willen hebben, kunnen we het uitproduct van twee vectoren binnen dit vlak gebruiken. Het uitproduct van a en b geeft immers een vector die loodrecht op beide vectoren staat. We krijgen dan dus: n = a b Vaak zal de normaalvector een eenheidsvector moeten zijn (een vector met lengte één, zie 1.4). Om van een vector een eenheidsvector te maken, moeten we de vector delen door zijn eigen lengte. 1.2 Matrices Wat zijn matrices? Matrices zijn verzamelingen van getallen. Een matrix bestaat uit een aantal rijen en een aantal kolommen waarin getallen worden gezet. Een voorbeeld van een matrix kan er zo uitzien: [ 1 3 ] Deze matrix heeft 2 rijen en 3 kolommen. Dit is dus een 2 3-matrix. Een vierkante matrix is een matrix met evenveel rijen als kolommen Operaties met matrices Matrices kunnen bij elkaar worden opgeteld of van elkaar worden afgetrokken als ze allebei dezelfde afmetingen hebben. Dit gaat dan als volgt: ( ) ( ) ( ) a b e f a + e b + f + = c d g h c + g d + h ( ) ( ) ( ) a b e f a e b f = c d g h c g d h Matrix A en matrix B kunnen met elkaar vermenigvuldigd worden, als A evenveel kolommen heeft als B rijen. Dit gaat dan als volgt: a b c x ax + by + cz d e f y = dx + ey + fz g h i z gx + hy + iz = = Let op: de uitkomst is hier een 3 1-matrix en A B is niet hetzelfde B A! En matrices kunnen niet door elkaar gedeeld worden. We kunnen een matrix transponeren door van de rijen van de matrix de kolommen te maken, en van de kolommen de rijen. Dit gaat als volgt: ( ) A = A T = B = B T =

12 HOOFDSTUK 1. BASIS WISKUNDE 9 Van vierkante matrices kan ook een inverse matrix genomen worden. Voor de inverse matrix van een matrix A geldt dat we een eenheidsmatrix krijgen als we de operatie A A 1 uitvoeren, maar dat we ook een eenheidsmatrix krijgen als we de operatie A 1 A uitvoeren. Een voorbeeld staat hieronder. Algemeen geldt dat we van een matrix een inverse matrix kunnen nemen als de determinant (zie de alinea hieronder) niet gelijk is aan nul A = A 1 = A A 1 = = A 1 A = = De laatste belangrijke operatie die met een matrix kan worden uitgevoerd, is het bepalen van de determinant. We kunnen determinanten alleen nemen van vierkante matrices. Het berekenen van een determinant kunnen we het best uitleggen met twee voorbeelden: één van een 2 2-matrix en één van een 3 3-matrix: ( ) a b A = c d Regel van Cramer det(a) = ad bc B = a b c d e f g h i det(b) = aei + bfg + cdh ceg bdi afh De regel van Cramer is een formule voor het oplossen van een stelsel van lineaire vergelijkingen (vergelijkingen waarin de onbekenden alleen maar eerstegraads zijn) waarbij er evenveel vergelijkingen als onbekenden zijn. In deze formule wordt gebruikt gemaakt van matrices. Volgens de regel van Cramer schrijven we eerst alle formules in matrixvorm. Hierbij staan de coëfficienten van de onbekenden in de coëfficientenmatrix, de onbekenden in een matrix (met dus maar één kolom), die met de coëfficientenmatrix vermenigvuldigd wordt en achter het =-teken staan de uitkomsten van de vergelijkingen ook in een matrix (met ook maar één kolom). Hierna kunnen we de onbekenden op de volgende manier berekenen: voor de n-de onbekende vervangen we in de coëfficientenmatrix de n-de kolom door de uitkomstenmatrix. Hierna delen we de determinant van deze nieuwe matrix door de determinant van de originele coëfficientenmatrix en het antwoord op deze operatie is de n-de onbekende. Zo kunnen we alle onbekenden bepalen. Dit klinkt waarschijnlijk nog een beetje vaag, daarom hebben we hier een voorbeeld van de regel van Cramer toegepast op een stelsel met twee vergelijkingen en twee onbekenden: De matrix voor x wordt dan: ( x + 12y = 45 2x + 5y = 23 ( x = y) ) ( ( ) En voor y krijgen we: 23 5 ) ( ) Hiermee krijgen we de volgende 2 23

13 HOOFDSTUK 1. BASIS WISKUNDE 10 oplossingen: x = = y = = 8 Met deze methode kunnen we relatief eenvoudig stelsels oplossen met een n aantal onbekenden en deze methode komt ook voor in het raytracen (zie 3.2.3). 1.3 Verzamelingenleer Met verzamelingenleer willen we in dit werk eigenlijk alleen maar dat de lezer het kan volgen als wij zaken als verzamelingen opschrijven. Daarom zullen we ons hier beperken tot een lijst met verklarende tekens, die, indien nodig, kan worden nagelezen als er verzamelingen worden gebruikt. Al de volgende tabellen komen uit een onuitgegeven hoofdstuk over verzamelingenleer geschreven door onze wiskundeleraar, meneer Boers. [4] {} geven aan dat hierbinnen een verzameling staat : betekent letterlijk waarvoor geldt betekent zit in betekent of betekent en [a, b] geven een interval aan van alle getallen van a tot en met b, waarbij a en b bij het interval horen (a, b) geven een interval aan van alle getallen tussen a en b, waarbij a en b niet bij het interval horen betekent oneindig betekent is rechtevenredig met Belangrijke verzamelingen om te onthouden zijn: de belangrijkste getallenverzamelingen N de natuurlijke getallen N = {0, 1, 2, 3, 4,...} Z de gehele getallen Z = {..., 2, 1, 0, 1, 2, 3,...} R de reële getallen, zoals π, 1 2 7, 2, 431, 5 log (3), et cetera. 1.4 Eenheidsobjecten Eenheidsobjecten zijn bijzondere vormen van objecten. Er zijn een aantal belangrijke eenheidsobjecten die veel worden gebruikt bij het raytracen, namelijk: Het eenheidsvierkant - een vierkant van afmetingen 1 1 De eenheidsvector - een vector met lengte 1 De eenheidscirkel - een cirkel met straal 1 De eenheidsbol - een bol met straal 1 De eenheidsmatrix - een vierkante matrix waarvan de waarden op de diagonaal van linksboven tot rechtsonder allemaal 1 zijn en de rest van de matrix waarde 0 heeft. 1.5 Orthonormale basissen Wat zijn orthonormale basissen? Een orthonormale basis is een stelsel gevormd door drie vectoren, waarvan elk loodrecht op het vlak gevormd door de andere twee staat, en die allemaal eenheidsvectoren zijn. Voor een orthonormale basis, gevormd door

14 HOOFDSTUK 1. BASIS WISKUNDE 11 a, b en c geldt dus: a = b c b = a c c = a b a = b = c = 1 Omdat het drie vectoren zijn, die niet parallel zijn en niet alledrie in hetzelfde vlak liggen, kan elke andere 3D vector uitgedrukt worden in een combinatie van deze drie vectoren. Orthonormale basissen worden vaak gebruikt in raytracing, omdat je met deze systemen op een willekeurige plek in de 3D-wereld een plaatselijk coördinatensysteem op kunnen zetten. Dit wordt bijvoorbeeld gebruikt voor camera s (zie hoofdstuk 4) Het opzetten van een orthonormale basis Het opzetten van een orthonormale basis uit twee vectoren die niet evenwijdig zijn werkt als volgt. Stel we hebben vector a en vector b en we willen een orthonormale basis opstellen met als vectoren w, u en v, dan gaan we als volgt te werk. Eerst maken we w door een eenheidsvector van a te maken. We delen dus a door zijn eigen lengte, zodat we een vector krijgen die dezelfde richting heeft als a maar een lengte heeft van één: w = a a Vervolgens kunnen we met het uitproduct u bepalen als een vector die loodrecht staat op het vlak dat gedefinieerd wordt door b en w. u = b w b w En tenslotte kunnen we de laatste vector voor de orthonormale basis berekenen met het uitproduct van w en u. Omdat w en u eenheidsvectoren zijn, is de uitkomst van het uitproduct automatisch ook een eenheidsvector. We hoeven deze dus niet meer te normaliseren Orthonormale assenstelsels v = w u Een orthonormale basis met een punt O waar de vectoren elkaar ontmoeten is een orthonormaal assenstelsel. Met een orthonormaal assenstelsel kan we een plaatselijk coördinatenstelsel worden opgesteld en dit is waar orthonormale basissen het meest voor worden gebruikt. Het opstellen van een orthonormaal assenstelsel gaat hetzelfde als het opstellen van een orthonormale basis, alleen is hier de oorsprong O bekend. Orthonormale assenstelsels kunnen we gebruiken om gemakkelijk nieuwe vectoren te bepalen vanuit het punt O van dit assenstelsel. In het nieuwe stelsel kunnen we dan makkelijk de richting van deze vector bepalen. Ook kunnen we deze vectoren makkelijk terugrekenen naar het echte (x, y, z)-assenstelsel. Dit zorgt meestal voor minder rekenwerk en daarom wordt deze methode meestal verkozen boven het direct berekenen van de richting van de nieuwe vectoren in het (x, y, z)-stelsel, zonder gebruik te maken van orthonormale assenstelsels. Stel we hebben een nieuwe vector d = we deze richting omrekenen naar het (x, y, z)-stelsel met de volgende formule: d u d v d w bepaald in het orthonormale (u, v, w)-stelsel, dan kunnen d = d u u + d v v + d w w (1.1) Omdat u, v en w in (x, y, z)-coördinaten zijn uitgedrukt, krijgt d de goede (x, y, z)-coördinaten als je de componenten van d vermenigvuldigt met respectievelijk u, v en w en die bij elkaar optelt. 1 het normaliseren van een vector betekent dat je van deze vector een eenheidsvector maakt

15 HOOFDSTUK 1. BASIS WISKUNDE Alternatieve coördinatensystemen Behalve het bekende (x, y, z) coördinatensysteem zijn er nog andere manieren om punten in een 3D-wereld aan te geven. Een tweetal van deze coördinatensystemen gebruiken wij naast het (x, y, z)-systeem ook bij het raytracen en deze zullen we hier behandelen Cylindrische coördinaten Het systeem van cylindrische coördinaten werkt met een afstand r, een hoek φ en de y-coördinaat. Een punt, beschreven met cylindrische coördinaten ziet er dus zo uit: p(r, φ, y). De r is de afstand van het punt tot de y-as, loodrecht gemeten op de y-as. De hoek φ is een hoek in het (x, z)-vlak en wordt gemeten door p te projecteren op het vlak en de hoek te meten die de lijn Op maakt met de positieve z-as. Tenslotte is y het bekende y-coördinaat uit het (x, y, z)-stelsel (zie figuur 1.2). We kunnen de cilindrische coördinaten als volgt omrekenen naar (x, y, z)- coördinaten: Bolcoördinaten x = r sin φ (1.2) y = y (1.3) z = r cos φ (1.4) Figuur 1.2: Cylindrische coördinaten [1] Bij bolcoördinaten wordt een punt gedefinieerd door de afstand r tussen het punt en de oorsprong van het stelsel, en door de twee hoeken θ en φ. φ is hierin dezelfde hoek als bij de cilindrische coördinaten. Het is dus de hoek die het geprojecteerde punt in het (x, z)-vlak maakt met de positieve z-as. θ is de hoek tussen de y-as en Op. Hierin is O de oorsprong van het stelsel en p het punt dat we willen aanduiden. θ wordt gemeten vanaf de y-as en in het vlak, gedefinieerd door de hoek tussen de vector Op en de y-as (zie figuur 1.3). We kunnen de bolcoördinaten als volgt omrekenen naar (x, y, z)-coördinaten: 1.7 Steradiaal x = r sin(φ) cos(θ) y = r sin(φ) sin(θ) (1.5) z = r cos φ De steradiaal is een eenheid voor de grootheid ruimtehoek. Waar een gewone radiaal een eendimensionale hoek is, die meestal gebruikt wordt in een tweedimensionale omgeving, is een steradiaal een tweedimensionale hoek, die gebruikt wordt in een driedimensionale omgeving (zie figuur 1.4 (links)). De radiaal kan worden berekend uit een booglengte (een ééndimensionale variabele) en de straal (ook een ééndimensionale variabele) op de volgende manier: Figuur 1.3: Bolcoördinaten [1] θ = l r De steradiaal vertoont eenzelfde verband met de tweedimensionale variant van de lengte: het oppervlak op een bol. Deze moet dan ook worden gedeeld door de straal van de bol in het kwadraat, omdat de straal een ééndimensionale variabele is, terwijl de steradiaal tweedimensionaal is. De steradiaal is dus als volgt te berekenen: Ω = A r 2 De omtrek van een cirkel met straal 1 is 2π. Zo is ook de radiaal van een volledige eenheidscirkel (hoek van 360 graden) 2π. Het oppervlak van een bol met straal 1 is 4π. Zo is ook de steradiaal van een volledige eenheidsbol 4π.

16 HOOFDSTUK 1. BASIS WISKUNDE 13 Figuur 1.4: Links: De ruimtehoek als rechthoekige vorm op een eenheidsbol. [5] Rechtsmidden: een ééndimensionale hoek in een tweedimensionaal stelsel: de radiaal. [6] Rechts: een tweedimensionale hoek in een driedimensionaal stelsel: de steradiaal. [6] Als we op een eenheidsbol een rechthoekige vorm nemen, kunnen we deze aangeven in steradialen. We kunnen deze echter ook nog op een andere manier aangeven, namelijk met bolcoördinaten. We hebben de hoek θ in het (x, y)-vlak, de hoek φ in het (x, z)-vlak en de straal r = 1. De lengte van de rechthoek zou in dit geval gelijk zijn aan de verandering in hoek θ ( θ) en, mits de rechthoek op de x-as ligt, zou de breedte gelijk zijn aan de verandering in hoek φ ( φ). Nemen we deze oneindig klein, dan krijgen we dθ en dφ. We mogen hier niet van het bijzondere geval uitgaan dat de rechthoek op de x-as ligt, dus zullen we het verband moeten vinden tussen dφ en de hoek onder welke de rechthoek ten opzichte van de x-as staat. Dit verband wordt gevormd door een factor sin θ. De breedte van de rechthoek wordt dus: sin θ dφ (zie figuur 1.4 (rechts)). De oppervlakte van de rechthoek kunnen we dus alsvolgt berekenen: A = lengte breedte = dθ sin θdφ = sin θdθdφ Maar deze oppervlakte is ook te berekenen met de verandering in steradiaal ω. Deze nemen we ook oneindig klein, waardoor we dω krijgen. We bepalen de oppervlakte dan op de volgende manier: A = dωr 2 = dω Hieruit kunnen we het verband tussen de bolcoördinaten θ en φ en de steradiaal ω afleiden: Dit zullen we nodig hebben bij het belichtingsmodel. dω = sin θdθdφ (1.6) 1.8 Kleuren in de raytracer Hoewel dit onderwerp eigenlijk vrijwel niets met wiskunde te maken heeft, hoort het wel bij de basis van de raytracer. Daarom hebben we toch besloten dit in hoofdstuk 1 in te voegen. Een kleur wordt in onze raytracer bepaald als een combinatie van de basiskleuren rood, groen en blauw. Een kleur moet gedefinieerd worden door een getal r, een getal g en een getal b, in die volgorde. rgb geeft de verhouding aan waarin rood, groen en blauw worden gemengd. Zo zorgt rgb = (1, 0, 0) voor rood, want rood wordt met niets gemengd. rgb = (1, 0, 1) zorgt voor een paarstint, want rood en blauw worden in gelijke verhouding gemengd. Voor r, g en b geldt verder nog het volgende: 0 r 1 0 g 1 0 b 1 Het getal één geeft namelijk een volledige hoeveelheid van die kleur aan en er kan nooit meer dan dat van één kleur worden toegevoegd aan het mengsel van kleuren. Op deze manieren zullen alle kleuren in de raytracer worden bepaald.

17 HOOFDSTUK 1. BASIS WISKUNDE Bronnen en code Bronnen Na elk hoofdstuk zullen we een lijst geven van nummers van bronnen die we gebruikt hebben voor het hoofdstuk. De lijst van bronnen is terug te vinden in onze bibliografie op pagina 88. De bronnen die we voor dit hoofdstuk gebruikt hebben zijn: [1], [5], [6], [4], [7], [8], [9], [10] en [11] Code Naast een verwijzing naar de bronnen, zullen we hier een verwijzing naar de broncode van de raytracer toevoegen. In de broncode waarnaar wordt verwezen, staan de onderwerpen die we in het hoofdstuk hebben behandeld geprogrammeerd. De code voor de vectoren en punten is terug te vinden in: point2d.h, point3d.h, vector3d.h 2. In rgbcolor.h staat de code voor de kleuren. Voor het rekenen met matrices hebben we de eigen library gebruikt, die te vinden is op 2 Bij de.h bestanden horen natuurlijk ook de.cpp bestanden

18 Hoofdstuk 2 Objecten en rays De twee belangrijkste elementen van het raytracen zijn de objecten en de rays. De objecten worden geraytracet en zorgen voor de scène die moet worden afgebeeld. De rays gebruiken we om de scène daadwerkelijk te raytracen. In dit hoofdstuk zullen we uitleggen hoe we een aantal objecten zo kunnen beschrijven dat we ze kunnen neerzetten in een wereld. Ook zullen we uitleggen wat rays zijn, en hoe we ze beschrijven. 2.1 Objecten Om te kunnen raytracen, moeten we eerst een 3D-wereld bouwen, waarmee de computer kan werken. Om objecten in deze wereld te kunnen plaatsen en te kunnen kijken of rays ze raken, moeten we deze wiskundig kunnen beschrijven. Er zijn twee makkelijke manieren om objecten en oppervlakken te beschrijven. De ene manier is met impliciete vergelijkingen (die leiden tot impliciete oppervlakken) en de andere manier is met parametrische vergelijkingen (die leiden tot parametrische oppervlakten). Impliciete vergelijkingen zijn het tegenovergestelde van expliciete vergelijkingen. Een voorbeeld van een expliciete vergelijking is y = 5x. Hierbij is de y direct (expliciet) uitgedrukt in x. Een impliciete vergelijking zou de volgende kunnen zijn: y 5x = 0. Hierin is y indirect (impliciet) uitgedrukt in x. Een impliciete vergelijking is dus een vergelijking in de vorm van R(x, y) = 0. Een parametrische vergelijking is een vergelijking waarin twee waarden, bijvoorbeeld de x- waarde en de y-waarde afhankelijk zijn van een parameter, bijvoorbeeld t. De x en y zijn hierbij onafhankelijk van elkaar. Wat belangrijk is om te onthouden van impliciete oppervlakken, is dat ze in een 3D wereld met een x-as, een y-as en een z-as gedefinieerd worden door een vergelijking in de vorm van: f(x, y, z) = 0 (2.1) Hierbij geldt dat f(x, y, z) < 0 het gebied aan de ene kant van de grens aanduidt, en f(x, y, z) > 0 het gebied aan de andere kant van de grens. Ook is het belangrijk om te onthouden dat impliciete oppervlakken open of gesloten kunnen zijn. De open oppervlakken strekken tot in het oneindige, zoals bijvoorbeeld een onbegrensd vlak, terwijl de gesloten oppervlakken een eindig oppervlak hebben, zoals bijvoorbeeld een bol. De makkelijkste objecten om te raytracen zijn objecten die beschreven zijn met een impliciete vergelijking Onbegrensde vlakken Figuur 2.1: Impliciet vlak [1] Een vlak is een oneindig lang, plat oppervlak in een 3D wereld. Voorbeelden van vlakken zijn het (x, y)-vlak, het (x, z)-vlak en het (y, z)-vlak. Een vlak kan op verschillende manieren worden gedefinieerd. Één manier om een vlak te definiëren, is om een punt in het vlak te nemen, en een normaalvector op het vlak. Dit is de manier die voor raytracen het handigst is, en die wij dus zullen gebruiken. Aangezien een vlak plat is, zijn de normaalvectoren op alle punten in het vlak aan elkaar gelijk. Het maakt dus niet uit op welk punt in het vlak de normaalvector wordt genomen. Om het vlak te definiëren zijn dus een normaalvector n en een in 15

19 HOOFDSTUK 2. OBJECTEN EN RAYS 16 het vlak gelegen punt a nodig. Er bestaat maar één vlak dat door punt a gaat met de richting aangegeven door n. Met deze twee waarden is het vlak dus vastgelegd. Om een impliciete vergelijking van een vlak op te stellen gebruiken we ook nog een punt p dat ergens in het vlak ligt. Hiermee kunnen we dan de vector p a bepalen die ook in het vlak ligt. Aangezien we weten dat de normaalvector loodrecht op het vlak staat, staat deze ook loodrecht op elke vector in het vlak. Dus n p a. Dus het inproduct van n en a p is gelijk aan nul. Hiermee kunnen we de vergelijking van het vlak opstellen: (p a) n = 0 (2.2) We kunnen deze vergelijking verder uitschrijven door de kentallen van de vectoren waarmee we werken in te vullen. Neem voor het punt p de coördinaten (x, y, z), voor het punt a de coördinaten (a x, a y, a z ) en voor n n x de kentallen n y en vul dit in. Dit geeft het volgende: n z x a x n x y a y n y = 0 z a z n z Dit is makkelijker te schrijven als: n x (x a x ) + n y (y a y ) + n z (z a z ) = 0 n x x + n y y + n z z a x n x a y n y a z n z = 0 Hierin is A = n x, B = n y, C = n z en D = a x n x a y n y a z n z Begrensde vlakken Ax + By + Cz + D = 0 (2.3) Om een begrensd vlak te definiëren gaan we uit van een oneindig vlak, en controleren we vervolgens of de punten in het oneindige vlak aan bepaalde voorwaarden voldoen. Voldoet een punt aan de voorwaarden, dan valt het dus binnen het begrensde vlak. Cirkels Voor begrensde vlakken in het algemeen bepalen we eerst de vlakvergelijking van het oneindige vlak waar het object in ligt, en nemen we vervolgens alleen de punten die er toe doen. Voor een cirkel zijn dit dus alle punten op een afstand r of minder van het middelpunt c afliggen. Hierin is r natuurlijk de straal van de cirkel. Een cirkel wordt dus uiteindelijk door drie zaken gedefinieerd: het middelpunt c, de straal r, en de normaalvector n. Deze normaalvector en c samen definiëren namelijk samen het onbegrensde vlak waar de cirkel in ligt, en de straal r en c samen bepalen welke punten van het onbegrensde vlak ook binnen de cirkel liggen. Hier hoeven we geen impliciete vergelijking van te maken, om dat deze gegevens al voldoende zijn om een cirkel te kunnen raytracen.(zie 3.2.1). Rechthoeken Voor de definitie van een rechthoek zullen we een punt en twee vectoren gaan gebruiken. Het punt p 0 is het hoekpunt waar de twee vectoren a en b hun oorsprong hebben. Deze twee vectoren vormen twee zijden van de rechthoek en moeten dus loodrecht op elkaar staan. Uit de twee zijden kunnen we met het uitproduct een normaalvector berekenen. Deze volgt dus uit de andere gegevens. Een rechthoek wordt dus al gedefinieerd met één hoekpunt en twee zijden. Hiervoor geldt ook dat we geen impliciete vergelijking nodig hebben, omdat we met een aantal vergelijkingen kunnen bepalen of een punt op het onbegrensde vlak binnen de rechthoek ligt.

20 HOOFDSTUK 2. OBJECTEN EN RAYS 17 We noemen het punt in het onbegrensde vlak voor het gemak weer p. Dan kunnnen we met de volgende ongelijkheden bepalen of het punt p binnen de rechthoek ligt: 0 ( p p 0 ) a a 2 0 ( p p 0 ) b b 2 (2.4) Dit behoeft waarschijnlijk nog enige uitleg. De ongelijkheden zijn erop gebaseerd dat het inproduct van twee vectoren k en m te schrijven is als k m = kx m x + k y m y + k z m z. Doen we dit voor het inproduct van p p 0 en a, waarbij we p p 0 voor het gemak even P zullen noemen, dan krijgen we: Figuur 2.2: Rechthoek met p o, a, b en p [1] P a = P x a x + P y a y + P z a z Dit geldt voor een 3D-stelsel. We weten echter al van het punt p dat het in het vlak ligt (dat wordt namelijk gecontroleerd voordat we gaan kijken of het pun p ook binnen de rechthoek ligt), dus kunnen we uitgaan van een 2D-stelsel, gedefinieerd door de oorsprong p 0 en de vectoren a en b. Dan geldt dus: P a = P a a a + P b a b Hierbij is a b altijd nul omdat a en b de assen van het 2D-stelsel zijn waar we in werken (net zoals de y-coördinaat van de x-as altijd nul is). Dus geldt: P a = P a a a Omdat a b altijd nul is, is de lengte van a te beschrijven als a = a a. Als P a a a dan gelijk is aan a 2, dan is P a = a a en valt de a-coördinaat van punt p dus op de zijde van het vierkant van afmetingen a a met a als één van de zijden. Als P a a a a 2, dan ligt de a coördinaat van p op deze zijde, óf binnen dit vierkant, behalve als P a < 0, want dan ligt het punt er alsnog naast, maar aan de andere kant. Op dezelfde manier is dit geheel voor b te beredeneren. Als een punt p dus aan beide vergelijkingen in vergelijking 2.4 voldoet, dan ligt de a coördinaat dus ergens op de breedte van a en ligt de b coördinaat ergens op de lengte van b. Zodra dit voor een punt het geval is, ligt het punt binnen de rechthoek met de twee zijden a en b. Tot slot hebben we nog de normaal van de rechthoek. De normaal van de rechthoek is te berekenen met het uitproduct van a en b. Deze moet dan echter nog wel genormaliseerd worden. We krijgen dus voor de normaal de formule: n = a b a (2.5) b Driehoeken Een driehoek is te definiëren als drie punten die niet op één lijn liggen. Als we een driehoek hebben met de punten a, b, en c, dan zijn de zijden van de driehoek de vectoren b a, c a en c b. Deze drie punten definiëren ook een onbegrensd vlak. Een driehoek ligt dan ook in een onbegrensd vlak en is altijd plat. De normaal is dus ook overal constant. Aangezien de normaal van de driehoek recht staat op het vlak dat door de twee zijden van de driehoek wordt gedefinieerd, kunnen we de eenheidsnormaal beschrijven als: n = (b a) (c a) (b a) (c a) Om te kijken of een bepaald punt p in de driehoek ligt, kijken we weer eerst of het in het vlak ligt. Zodra dit het geval is, moeten we kijken of het ook binnen de driehoek in dit vlak ligt. Hiervoor gebruiken we barycentrische coördinaten. Als een driehoek de hoekpunten a, b, en c heeft, kunnen we de barycentrische coördinaten van een punt op het vlak gedefinieerd door deze driehoek als volgt weergeven (zie figuur 2.3): (2.6) p(α, β, γ) = αa + βb + γc (2.7)

21 HOOFDSTUK 2. OBJECTEN EN RAYS 18 Om dan binnen te driehoek te zitten, is het logisch dat geen enkel punt verder dan een lengte van één van de zijden, in de richting van die zijde, weg mag zitten van de oorsprong. Dus gelden de volgende voorwaarden: α + β + γ = 1 (2.8) 0 <α < 1 0 <β < 1 (2.9) 0 <γ < 1 Met deze ongelijkheden kunnen we bepalen of een punt op het vlak binnen de driehoek ligt. We hebben echter drie onbekenden, namelijk α, β en γ. Gelukkig kunnen we met vergelijking 2.8 een onbekende wegwerken. We kunnen namelijk α in de andere twee uitdrukkingen: α = 1 β γ. Dit invullen in vergelijking 2.7 geeft: p(α, β, γ) = (1 β γ)a + βb + γc p(α, β, γ) = a + βb βa + γc γa p(α, β, γ) = a + β(b a) + γ(c a) (2.10) De ongelijkheden in 2.9 kunnen we dan ook herschrijven. Hierbij verandert alleen de eerste: Het drietal wordt dus: 0 <α < 1 0 < 1 β γ < 1 1 < β γ < 0 1 > β + γ > 0 0 <β < 1 0 <γ < 1 (2.11) 0 < β + γ < 1 Als β = 0, dan hebben we een oneindige lijn door de hoekpunten a en c van de driehoek gedefinieerd (zie figuur 2.3). Dit is de γ-as. β = 0 invullen in vergelijking 2.10 geeft: p = a + γ(c a) (2.12) Als we hierbij de ongelijkheid uit 2.11 erbij nemen, kunnen we stellen dat we de zijde 0 < γ < 1 en vergelijking Op dezelfde manier kunnen we met γ = 0 en 0 < β < 1 de zijde p = a + β(b a) c a definiëren met b a definiëren. Deze wordt dan: Hiermee is de vergelijking uit 2.10 verklaard: dit is een combinatie van de vergelijkingen die de zijden γ en β aangeven. Zo kunnen we dus een driehoek en de zijden van een driehoek in barycentrische coördinaten aangeven. Ook kunnen we hiermee bepalen of een bepaald punt binnen de driehoek valt, maar omdat dit nauw samenhangt met het snijden van rays met objecten, zullen we dit behandelen in (zie pagina 23) Bollen Een bol is een... bol. Wiskundig gezien is een bol de verzameling van alle punten binnen een straal r van het middelpunt c. Oftewel B = {p : p c r}. Bij het raytracen maken we alleen gebruik van het oppervlak van de bol. Oftewel de punten die precies op een afstand r van c liggen: O = {p : p c = r}. Punt c wordt gedefinieerd door zijn drie coördinaten, dus c = (c x, c y, c z ). Een willekeurig punt p op het oppervlak van de bol heeft de coördinaten (x, y, z). Door de stelling van Pythagoras in 3D te gebruiken, kunnen we de lengte

22 HOOFDSTUK 2. OBJECTEN EN RAYS 19 van vector p c bepalen. Namelijk p c = (x c x ) 2 + (y c y ) 2 + (z c z ) 2. Deze lengte is natuurlijk weer gelijk aan de straal en dit vormt de definitie van een bol. Om het leesbaar te houden, is het handig om het wortelen weg te werken. We kwadrateren dus zowel de straal r als de afstand p c. Dan krijgen we dus (x c x ) 2 + (y c y ) 2 + (z c z ) 2 = r 2 oftewel de impliciete vergelijking: (x c x ) 2 + (y c y ) 2 + (z c z ) 2 r 2 = 0 (2.13) Met deze vergelijking kunnen we een bol definiëren en dit is de definitie van een bol die wij zullen gebruiken. De normaal van een bol is tamelijk eenvoudig te bepalen. Deze is echter wel voor elk willekeurig punt op het oppervlak van de bol anders. Voor een punt op het oppervlak van de bol geldt namelijk dat de normaalvector gelijk is aan de vector van het middelpunt, naar het punt op de oppervlak van de bol. Omdat het voor raytracen handig is om een eenheidsnormaal te hebben, kunnen we deze vector nog delen door de straal, en we hebben een eenheidsnormaal. In formulevorm is dit: 2.2 Rays n = p c r (2.14) Een ray bij raytracing is een oneindig lange rechte lijn, gedefinieerd door het punt o, de oorsprong en de richting in de vorm van een eenheidsvector d, Figuur 2.3: Driehoek met hoekpunten a, b, en c en een barycentrisch coördinatenstelsel. [1] van het engelse direction. De parameter van een ray is t, waarbij t [, + ] en bij t = 0 zitten we in de oorsprong van de ray. Een willekeurig punt op de ray kunnen we dus definiëren als: p = o + t d (2.15) In raytracing hebben we vier verschillende typen rays. We onderscheiden de primaire rays, de secundaire rays, de schaduwrays en de lichtrays. Primaire rays worden vanuit de camera afgeschoten. Secundaire rays zijn de rays die zijn weerkaatst vanaf een object of iets dergelijks. Schaduwrays worden gebruikt om schaduwen aan te brengen en beginnen per definitie vanaf het oppervlak van een object. De lichtrays, tenslotte, beginnen in de lichtbronnen en zijn nodig voor sommige aspecten van verlichting. Hiermee hebben we de basis voor het gebruik van rays gelegd. In hoofdstuk 3 zullen we nog iets dieper ingaan op rays om te kunnen bepalen of ze objecten snijden. 2.3 En de raytracer? Hoewel we met de informatie besproken in dit hoofdstuk nog helemaal niets kunnen raytracen, is het wel essentiële stof voor het bouwen van een raytracer. In dit hoofdstuk hebben we geleerd hoe we een aantal simpele objecten wiskundig kunnen beschrijven en daarmee kunnen we eenvoudige scènes bouwen. We weten nu immers welke waarden we nodig hebben om de objecten, die in dit hoofdstuk zijn beschreven, aan te geven. Zonder scène kunnen we natuurlijk niets raytracen, dus ondanks dat we nu een raytracer kunnen bouwen die niet kan raytracen (een waardeloze raytracer dus), was de informatie uit dit hoofdstuk toch een essentieel onderdeel van elke raytracer. 2.4 Bronnen en code Bronnen Voor dit hoofdstuk hebben we de volgende bronnen gebruikt: [1], [12], [13] en [14].

23 HOOFDSTUK 2. OBJECTEN EN RAYS 20 Code De code voor een ray is terug te vinden ray.h. De code voor de objecten komt pas bij het volgende hoofdstuk.

24 Hoofdstuk 3 Rayintersectie Hét essentiële onderdeel van raytracen is het bepalen of een ray een object raakt. Hoe dit kan worden bepaald, wordt in dit hoofdstuk uitgelegd. De eerste operatie die met een ray wordt uitgevoerd is om voor elk object in de 3D scène te kijken of het object wordt geraakt door de ray. We zoeken vervolgens naar het raakpunt met de kleinste waarde van t 1, waarbij t niet nul mag zijn. Waarom mag t geen nul zijn? Als t nul zou mogen zijn, zou de ray een raakpunt kunnen hebben in zijn oorsprong. Dit geeft problemen bij bijvoorbeeld de een schaduwray, die per definitie zijn oorsprong heeft op een objectoppervlak. Deze zou dan als eerste raakpunt het object raken, waarvandaan het wordt afgeschoten, en dat is niet de bedoeling. Om dit te verkomen nemen we t in het interval t [ɛ, + ), waarbij ɛ een klein, positief getal is, bijvoorbeeld ɛ = Intersectie met impliciete oppervlakken Om te kijken of een ray een impliciet oppervlak snijdt, kunnen we vergelijking 2.1 herschrijven. De x, y en z in de functie f(x, y, z) duiden een punt aan in een 3D wereld. Als we dit punt p noemen, geldt voor de coördinaten van p dat p = (x, y, z). We kunnen dus schrijven: f(p) = 0 (3.1) Als een ray een impliciet oppervlak raakt, moet voor het bewuste punt gelden dat de coördinaten van dit punt zowel aan de vergelijking van de ray, als aan de vergelijking van het vlak voldoen. Daarom kunnen we de vergelijking van de ray (2.15) substitueren in vergelijking 3.1. We krijgen dan: Dit is de basis voor elke intersectie met impliciete oppervlakken Onbegrensde vlakken f(o + t d) = 0 (3.2) Een impliciete vergelijking van een vlak was gegeven in vergelijking 2.2. Als we hierin de rayvergelijking substitueren krijgen we het volgende: (o + t d a) n = 0 Hierin is o een punt, t een parameter, d een vector, a een punt en tenslotte n de normaalvector van het vlak. We kunnen de vergelijking herschrijven tot: (o a) n + t d n = 0 t d n = (o a) n t = (a o) n d n (3.3) 1 t uit de rayvergelijking in

25 HOOFDSTUK 3. RAYINTERSECTIE 22 In vergelijking 3.3 zijn o, a, n en d bekend. De onbekende t is dus al te berekenen. Als t is berekend, kunnen we deze invullen in 2.15 en hieruit het punt p berekenen. Het enige wat we nu nog moeten doen is kijken of t [ɛ, + ). Als dit het geval is, hebben we een raakpunt voor het onbegrensde vlak. Wat nog wel even belangrijk is om op te merken is dat we een situatie krijgen waarin we gaan proberen te delen door nul. Namelijk als d n = 0. Dit is als de ray loodrecht op de normaal van het vlak staat, dus als de ray evenwijdig loopt aan het vlak. In C++, de programmeertaal waarin we de raytracer schrijven, geeft delen door nul echter geen foutmelding, maar de uitkomst infinity, oftewel oneindig. Dit zorgt dus voor een raakpunt op een oneindige afstand, en dit wordt nooit gerenderd. Er treden dus geen problemen op bij het delen door nul in dit geval Bollen Zoals we in hoofdstuk 2 hebben gezien, is de impliciete vergelijking voor een bol de volgende: (x c x ) 2 + (y c y ) 2 + (z c z ) 2 r 2 = 0 (2.13). Deze kan ook worden geschreven als: (p c) (p c) r 2 = 0 (3.4) Want: x c x x c x (p c) (p c) = y c y y c y = (x c x )(x c x ) + (y c y )(y c y ) + (z c z )(z c z ) z c z z c z Als we in vergelijking 3.4 de p weer vervangen door vergelijking 2.15 te substitueren, krijgen we het volgende: Dit uitschrijven geeft: (o + t d c) (o + t d c) r 2 = 0 (3.5) (t d + (o c)) (t d + (o c)) r 2 = 0 ( d d)t 2 + (2(o c) d)t + (o c) (o c) r 2 = 0 (3.6) Dit is een tweedegraadsvergelijking die op te lossen is met de ABC-formule: D = b 2 4ac t = b + D 2a b D 2a Hierin is a de coëfficient van t 2, b de coëfficient van t en c de term zonder t in vergelijking 3.6. Aangezien deze vergelijking behalve t weer alleen maar bekenden bevat, kunnen we t berekenen. Het enige wat dan nog rest is kijken of t [ɛ, + ). Als dit ook waar is, hebben we de raakpunten met een bol. 3.2 Intersectie met begrensde vlakken Om snijpunten met begrensde vlakken te bepalen, kijken we eerst of de ray een snijpunt heeft met het onbegrensde vlak waar het begrensde vlak in ligt. Vervolgens kijken we of het snijpunt binnen de grenzen van het begrensde vlak ligt. We zullen dit hier demonstreren voor de begrensde vlakken genoemd in hoofdstuk Cirkels Als een cirkel gedefinieerd is met de normaalvector n, de straal r en het middelpunt c kunnen we al bepalen of een afgeschoten ray de cirkel raakt. Eerst bepalen we met de manier beschreven in of de ray het vlak raakt waar de cirkel in ligt. Als hij dit vlak raakt, noemen we het punt waar de ray het vlak raakt p. Om te kijken of dit punt ook in de cirkel ligt, nemen we de vector van c naar p en bepalen we daar de lengte van.

26 HOOFDSTUK 3. RAYINTERSECTIE 23 Als deze lengte groter is dan de straal weten we dat het punt p buiten de cirkel ligt, maar is de lengte kleiner dan of gelijk aan de straal, dan ligt hij binnen de cirkel. Oftewel, om in de cirkel te liggen moet p aan de volgende voorwaarden voldoen: p c = p c r (p x c x ) 2 + (p y c y ) 2 + (p z c z ) 2 Alle waarden in deze vergelijkingen zijn al bekend. Punt p is met de rayvergelijking bepaald toen we keken of de ray het vlak raakte, middelpunt c staat in de definitie van de cirkel en de straal r ook. Hiermee kunnen we dus kijken of een ray de cirkel raakt Rechthoeken Eerder is al gezegd dat alle punten in een rechthoek voldoen aan twee ongelijkheden, namelijk de ongelijkheden in 2.4. Met deze ongelijkheden kunnen we voor elk punt p op het vlak kijken of dit binnen de rechthoek ligt. Eerst kijken we met de methode beschreven in of de ray een snijpunt heeft met het onbegrensde vlak dat gedefinieerd is door de rechthoek. Als dit het geval is, betekent dit dat punt p aan vergelijking 2.15 voldoet. We kunnen dus p substitueren in 2.4. We krijgen dan: 0 (o + t d p 0 ) a a 2 0 (o + t d p 0 ) b b 2 (3.7) Omdat t al is berekend toen we keken of de ray een snijpunt met het onbegrensde vlak had, zitten er in 3.7 geen onbekenden meer. Ook weten we al dat t [ɛ, + ). De ongelijkheden kunnen we dus gewoon controleren. Als aan allebei deze ongelijkheden is voldaan, weten we dat de ray een snijpunt heeft met de rechthoek Driehoeken In waren we al begonnen met de barycentrische coördinaten. Om een snijpunt met een driehoek te berekenen zullen we daarmee verder werken. Om te kijken of een ray het vlak raakt waar de driehoek in ligt, gebruiken we de vergelijking die we hebben opgeschreven in Om een snijpunt te hebben moet het punt p uit deze vergelijking ook weer voldoen aan het punt p uit de rayvergelijking. Dus kunnen we een substitutie uitvoeren waardoor we het volgende krijgen: o + t d = a + β(b a) + γ(c a) (3.8) Dit verschilt van de vergelijkingen die we voor cirkels en rechthoeken moesten oplossen omdat er hier drie onbekenden zijn, namelijk t, β en γ. Als we dit anders schrijven kunnen we dit als een vergelijking schrijven met alleen vectoren en onbekende parameters erin, namelijk op de volgende manier. t d β(b a) + γ(c a) = a o t d + β(a b) + γ(a c) = a o (3.9) Omdat we een vector krijgen als we twee punten van elkaar aftrekken, zijn (a b), (a c) en (a o) vectoren. Dus kunnen we de vergelijkingen voor de x, y en z-waarden in drie verschillende vergelijkingen opschrijven. We krijgen dan het volgende: td x + β(a x b x ) + γ(a x c x ) = a x o x td y + β(a y b y ) + γ(a y c y ) = a y o y (3.10) td z + β(a z b z ) + γ(a z c z ) = a z o z Omdat dit een lineair stelsel is (alle onbekenden zijn eerstegraads), en er evenveel vergelijkingen als onbekenden zijn, kunnen we dit geheel oplossen met de regel van Cramer. Hiervoor schrijven we de drie vergelijkingen

27 HOOFDSTUK 3. RAYINTERSECTIE 24 op in matrices. Dit ziet er dan op de volgende manier uit: a x b x a x c x d x a y b y a y c y d y β γ = a x o x a y o y (3.11) a z b z a z c z d z t a z o z Volgens de regel van Cramer kunnen we nu de eerste onbekende bepalen op de volgende manier. In de a x o x matrix vervangen we de coëfficienten in de eerste kolom door de vector a y o y. Vervolgens delen we a z o z de determinant van deze matrix door de determinant van de originele coëfficientenmatrix. Hiervan is de uitkomst dan, in dit geval, β. Zo kunnen we voor de tweede onbekende de coëfficienten in de tweede kolom vervangen, en voor de derde onbekende de coëfficienten in de derde kolom. De matrices met de vervangen kolommen zien er als volgt uit: B = a x o x a x c x d x a y o y a y c y d y a z o z a z c z d z a x b x a x o x d x C = a y b y a y o y d y a z b z a z o z d z a x b x a x c x a x o x T = a y b y a y c y a y o y a z b z a z c z a z o z Als we de originele coëfficentenmatrix dan O noemen, kunnen we β, γ en t als volgt bepalen met de regel van Cramer: β = det(b) det(o) γ = det(c) det(o) t = det(t ) det(o) (3.12) Omdat de determinanten van B, C, T en O erg lang worden om op te schrijven met de originele variabelen, vervangen we deze even door handiger variabelen, zodat de matrixvergelijking (3.11) er zo uit ziet: a b c e f g β γ = d h (3.13) i j k t l Hierin zijn de variabelen dus: a = a x b x, b = a x c x, c = d x, d = a x o x, e = a y b y, f = a y c y, g = d y, h = a y o y, i = a z b z, j = a z c z, k = d z, l = a z o z.

28 HOOFDSTUK 3. RAYINTERSECTIE 25 Dan worden de verschillende matrices en hun determinanten dus: O = a b c e f g i j k det(o) = afk + bgi + cej cfi bek agj = a(fk gj) + b(gi ek) + c(ej fi) B = d b c h f g l j k det(b) = dfk + bgl + chj cfl bhk dgj = d(fk gj) + b(gl hk) + c(hj fl) C = a d c e h g i l k det(c) = ahk + dgi + cel chi dek agl = a(hk gl) + d(gi ek) + c(el hi) T = a b d e f h i j l det(t ) = afl + bhi + dej dfi bel ahj = a(fl hj) + b(hi el) + d(ej fi) Zo kunnen we dus de onbekenden uitrekenen: d(fk gj) + b(gl hk) + c(hj fl) β = a(fk gj) + b(gi ek) + c(ej fi) a(hk gl) + d(gi ek) + c(el hi) γ = a(fk gj) + b(gi ek) + c(ej fi) a(fl hj) + b(hi el) + d(ej fi) t = a(fk gj) + b(gi ek) + c(ej fi) (3.14) Vervolgens hoeven we alleen nog maar te checken of β en γ wel aan de ongelijkheden in 2.11 voldoen en of t [ɛ, + ) en als dit waar is, hebnen we het punt gevonden waar de ray de driehoek raakt. 3.3 En de raytracer? Na dit hoofdstuk kunnen we in principe nog steeds niets raytracen, maar we hebben een stevige basis gelegd. We kunnen op dit moment een scène bouwen, bestaande uit bollen, cirkels, rechthoeken, vlakken en driehoeken en we kunnen controleren of uitgestuurde rays objecten raken. Hoewel we nog geen rays kunnen uitzenden en dus nog geen plaatje kunnen renderen, is dat wel het enige wat nog ontbreekt om een volledig werkende, zeer eenvoudige raytracer te bouwen. 3.4 Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk hebben gebruikt zijn: [1] en [15]. Code De code voor de objecten is terug te vinden in: plane.h, rectangle.h, circle.h en sphere.h. In geometricobject.h staat de algemene interface voor een object.

29 Hoofdstuk 4 Camera en perspectief Om een realistische afbeelding te renderen, is het logisch dat we de 3D-wereld in perspectief willen zien. In dit hoofdstuk zullen we eerst uitleggen hoe perspectief werkt bij raytracen en daarna hoe we een virtuele camera maken, die we door de scène kunt bewegen om de wereld vanuit verschillende punten te bekijken. 4.1 Perspectief Perspectief is het weergeven van diepte. Dit gaat met raytracen net zoals in de echte wereld. Normaal kijken we vanuit ons oog (een punt) de wereld in. De stralen bereiken onze ogen allemaal onder een verschillende hoek. Dit gebeurt ook met raytracing. We schieten de stralen onder een hoek af vanuit het eyepoint (het oog ) richting de pixel, die we aan het raytracen zijn. De stralen beginnen dus in het eyepoint en gaan door het scherm heen (zie figuur 4.1). De afstand d is de afstand tussen het scherm en het eyepoint. Punt e is het Figuur 4.1: Afschieten van stralen vanuit het eyepoint door het scherm [1] eyepoint. Door d en e te variëren kunnen we verschillende soorten afbeeldingen krijgen. We kunnen: d groter maken. Door d groter te maken, wordt het gebied dat we zien kleiner, het scherm staat immers verder weg. Hierdoor zoomen we in. d kleiner maken. Door d kleiner te maken, wordt het gebied dat we zien groter. Hierdoor zoomen we uit. e veranderen. Door e te veranderen, wordt d ook groter of kleiner. Hierdoor kunnen we dus ook in- of 26

30 HOOFDSTUK 4. CAMERA EN PERSPECTIEF 27 Figuur 4.2: Orthonormaal assenstelsel met e als oorsprong, u, v, w als assen. Rechtsonder het assenstelsel van de wereld. up is dit geval gelijk aan v omdat die recht omhoog staat. [1] uitzoomen. Doordat het eyepoint verandert, verandert echter ook het perspectief. De stralen worden nu immers vanaf een ander punt afgeschoten. Daarom kunnen we het best e constant houden. De grootte van de pixels te veranderen. Door de pixels groter of kleiner te maken, veranderen we de grootte van het scherm. Ook hiermee kunnen we dus in- of uitzoomen. Om in en uit te zoomen kunnen we dus het best de d veranderen of de pixelgrootte veranderen. 4.2 Camera Om van uit verschillende oogpunten de scène te kunnen bekijken, moeten we een virtuele camera maken. Deze camera moeten we vrij kunnen bewegen. Vervolgens schiet de camera de rays de wereld in. De plek van de camera wordt bepaald door: e Het eyepoint. De plek vanaf waar de rays worden afgeschoten. l Het look-at-point. Het punt waar de camera naartoe kijkt. up De upvector, die de bovenkant van de camera aangeeft. d De afstand tussen het scherm en de camera. De camera zorgt vervolgens voor het renderen van een pixel Orthonormale basis Orthonormale basis berekenen We moeten eerst een orthonormale (u, v, w)-basis berekenen met het punt e als oorsprong. Het scherm is vervolgens parallel aan het vlak van u en v. Hiermee kunnen we vervolgens de richting van de ray binnen de orthonormale basis berekenen en deze vervolgens omrekenen naar wereld coördinaten (zie figuur 4.2). De camera kijkt richting l, de kijkrichting is dus l e. Voor de orthonormale basis nemen we de omgekeerde kijkrichting, zodat de w as ook hier naar ons toe komt. Dus geldt: w = e l e l (4.1)

31 HOOFDSTUK 4. CAMERA EN PERSPECTIEF 28 Vervolgens kunnen we met uitproducten de andere twee assen u en v berekenen: 1 u = up w up w (4.2) v = w u (4.3) Als de kijkrichting gelijk of tegengesteld is aan de upvector, moet er handmatig een orthonormale basis worden gekozen. De camera kan immers niet in de dezelfde richting kijken als de upvector. Als de camera in de richting van de upvector (dus recht omhoog, als de camera niet gerold heeft) kijkt wordt de basis u = 0, v = 0, w = 1 gekozen, als de camera tegengesteld aan de richting van de upvector kijkt wordt de basis u = 0, v = 0, w = 1 gekozen Camera draaien We kunnen de camera van richting veranderen door e en l aan te passen. Daarnaast kunnen we de camera nog rollen (zie roll in figuur 4.2). Dit doen we door de upvector aan te passen. De upvector is een eenheidsvector 0 die de bovenkant van de camera aangeeft. Als de camera recht staat is die 1. Door de x en y aan te 0 passen kunnen we de camera laten rollen. Omdat het een eenheidsvector is, is de lengte 1. We kunnen de waarden voor x en y voor hoek α in radialen dus bereken met de eenheidscirkel (de hoek α wordt gemeten vanaf de bovenkant van de eenheidscirkel en niet vanaf de rechterkant, daarom nemen we voor de x de sinus en de y de cosinus): up = sin α cos α (4.4) Richting van de ray berekenen Met behulp van de orthonormale basis kunnen we vervolgens de ray berekenen. Het startpunt van de ray is het eyepoint dus: o = e. Vervolgens moeten we de richting van de ray berekenen. Daarvoor moeten we de u v, de v v en de w v coördinaten van de pixel op de orthonormale basis uvw berekenen. Het scherm ligt op afstand d in de diepte dus w = d ( w is immers tegengesteld gericht aan de kijkrichting). u v en v v berekenen De u v en v v coördinaten hangen af van: De resolutie h res bij v res De pixelgroote s De coördinaten van het samplepunt p x en p y (zie hoofdstuk 5.1, pagina 31) 2 De rij r en kolom c van de pixel waarvoor we de coördinaten aan het berekenen zijn. 1 Omdat w en u al eenheidsvectoren zijn, wordt v dat ook en hoeven we deze niet meer te normaliseren. 2 Het samplepunt geeft een plaats binnen een pixel aan. Zo kunnen we later meerdere verschillende samples nemen. Zonder samples wordt de ray door het midden van de pixel afgeschoten, dan geldt p x = 1 2 en py = 1 2.

32 HOOFDSTUK 4. CAMERA EN PERSPECTIEF 29 In figuur 4.3 staat een voorbeeld van een scherm van 8 bij 6 pixels. Het scherm ligt gecentreerd met de w as in het midden (de blauwe punt). We gaan vervolgens alle pixels af. Bij de pixel linksonder is c = 0 en r = 0. Het midden ligt aan de linkerkant van het vak waarvoor geldt c = 1 2 h res en r = 1 2 v res. Om de pixel om te rekenen naar coördinaten moeten we er dus respectievelijk 1 2 h res en 1 2 v res van aftrekken. Vervolgens tellen we daar nog het samplpunt bij op. Tenslotte moeten we het nog vermenigvuldigen met de pixelgrootte s, één vakje is immers s groot. Voor u v en v v geldt dus: u v = s(c 1 2 h res + p x ) (4.5) v v = s(r 1 2 v res + p y ) (4.6) Figuur 4.3: Een scherm van 8x6 pixels [1] De vector v die de richting van de ray aangeeft wordt dan vervolgens v vv d Omrekenen naar wereldcoördinaten Vervolgens moeten we de coördinaten nog omrekenen naar wereldcoördinaten, zodat ze we ze als richting voor de ray kunnen gebruiken. Omdat uvw een orthonormale basis aangeeft, kunnen we de vector als volgt omrekenen ( d is de vector voor de kijkrichting in wereldcoördinaten): We hebben nu het beginpunt o en de richting d van de vector berekend. Scène renderen d = u v u + v v v d w (4.7) De camera is tenslotte verantwoordelijk voor het afschieten van de rays en dus het feitelijk renderen van de scène. De camera wordt steeds gevraagd om een pixel te renderen. Hij schiet vervolgens een ray af voor elke pixel. Als de ray een object raakt krijgt de pixel de desbetreffende kleur. Later zullen we die kleur door middel van lichtberekeningen bepalen. 4.3 En de raytracer? Op dit moment kunnen we onze eerste echte raytracer bouwen. Nu we een camera kunnen neerzetten, rays kunnen uitsturen en perspectief in ons plaatje kunnen krijgen, kunnen we een raytracer bouwen die plaatjes kan renderen. Dit zijn echter nog lang niet de plaatjes die we willen renderen met een raytracer, omdat het echtheidsgehalte nog vrij laag is. Een voorbeeld van een plaatje, gerenderd met het programma dat we nu kunnen schrijven, is te zien in 4.4. Het is duidelijk dat deze raytracer nog stukken beter kan. u v Figuur 4.4: Een plaatje gerenderd met een zeer simpele raytracer

33 HOOFDSTUK 4. CAMERA EN PERSPECTIEF Bronnen en code Bronnen De bron die we voor dit hoofdstuk hebben gebruikt is: [1]. Code De code voor de camera is terug te vinden in camera.h. De camera gebruikt vervolgens de tracer, die in tracer.h en raycast.h staat om de rays af te schieten.

34 Hoofdstuk 5 Sampling Als we een bol gaan raytracen, zien we al direct het eerste probleem. Er treedt kartelvorming (aliasing) op. De lijnen die eigenlijk rond hadden moeten zijn, worden kartelig. In dit hoofdstuk zullen we uitleggen hoe dit komt en hoe we dit op kunnen lossen. 5.1 Aliasing Aliasing ontstaat doordat een scherm bestaat uit een rooster van vierkantjes: pixels. Als we op dat rooster een schuin vlak willen aangeven, dan valt het schuine stuk tussen twee pixels in. De pixels zouden eigenlijk half geel, half grijs moeten zijn (zie figuur 5.2). Hetzelfde gebeurde bij de bol. Doordat de lijnen tussen twee pixels in vallen, ontstaan er kartels. Wat natuurlijk een oplossing is, is om de afbeelding op zo n hoge resolutie te renderen, dat we de kartels niet meer zien. We kunnen de resolutie Figuur 5.1: Aliasing bij een bol echter niet onbeperkt groter maken: het computerscherm heeft bijvoorbeeld maar een beperkte resolutie. We kunnen het probleem ook oplossen door meerdere monsters voor één pixel te nemen. We sturen niet één ray uit voor een pixel, maar meerdere. We nemen dus meerdere samples voor één pixel. Uiteindelijk hebben we meerdere kleuren berekend voor een pixel, waar we vervolgens het gemiddelde van nemen. Hierdoor krijgen de pixels een kleur die tussen de kleuren van de twee grenzende vlakken in zit en wordt de aliasing minder. Om de verschillende rays uit te sturen, moeten we eerst weten hoe we de samples nemen. 5.2 Sampling Figuur 5.2: Twee schuinen vlakken, afgebeeld op 7x5 pixels [1] Er zijn verschillende methodes om te samplen. In deze paragraaf zullen we ze beschrijven en uitleggen hoe we ze in onze raytracer gebruiken. We hebben de samples nu alleen nodig voor het anti-aliasen 1, maar we zullen ze later ook voor andere processen binnen het raytracen gebruiken. Omdat het genereren van samplepunten tijd kost, berekenen we voor het raytracen al een aantal verzamelingen van een s aantal samples. Als er vervolgens ergens samples nodig zijn in onze raytracer, zorgt de samplecode ervoor dat er een samplepunt op een eenheidsvierkant wordt teruggegeven, die dus al eerder berekend is. Hiermee besparen we tijd op het raytracen. 1 Anti-aliasing is het tegenwerken van de kartelvorming. 31

35 HOOFDSTUK 5. SAMPLING 32 Figuur 5.4: Moiré patterns die ontstaan (bijv. in de rode cirkels). Links geen sampling, midden regular sampling, rechts random sampling. [1] Regular sampling Figuur 5.3: Regular sampling. In dit voorbeeld: p = 3 en q = 1 [1] De makkelijkste manier om te samplen is regular sampling. De verschillende samples worden regelmatig verdeeld over een vierkant. We nemen dus op een regelmatige manier verschillende samples voor een pixel (zie figuur 5.3). Door de meerdere samples, wordt de aliasing minder. Dit werkt als volgt. We nemen een s aantal samples (het aantal samples moet een vierkantsgetal zijn 2 ). n is dan n = s. We kunnen het eenheidsvierkant dus verdelen in n bij n hokjes. We gaan vervolgens alle hokjes af. We zijn dan steeds bij hokje (p, q) (zie figuur 5.3). Aangezien de hokjes op een eenheidsvierkant liggen, zijn ze 1 n bij 1 n groot. We willen steeds een ray schieten door het midden van het hokje, dus de coördinaten zijn x = (p ) 1 n en y = (q+ 1 2 ) 1 p+0.5 n, of te wel x = n en y = q+0.5 n. De coördinaten worden vervolgens opgeslagen, zodat ze later gebruikt kunnen worden. Hoewel de kartels verdwijnen, verdwijnen niet al onze problemen. De zogenaamde moiré patterns blijven bestaan (zie figuur 5.4). Moiré patterns ontstaan doordat de samples op een regelmatige manier worden genomen. We nemen dan wel meerdere samples, maar doordat we ze op een regelmatige manier nemen, ontstaan er onbedoelde patronen op de afbeelding. Een oplossing hiervoor is om de samples willekeurig te nemen. In plaats van de patronen ontstaat er ruis, wat minder opvalt in een afbeelding Random sampling In plaats van de samples regelmatig te verdelen, kunnen we dat ook willekeurig doen. De computer berekent twee willekeurig getallen a en b tussen de 0 en de 1. Deze kunnen direct gebruikt worden als coördinaten op het eenheidsvierkant. De coördinaten zijn dus x = a en y = b. Doordat de samples willekeurig genomen worden, verdwijnen de moiré patterns en komt er ruis voor in de plaats (zie figuur 5.4). Het nadeel hieraan is dat de punten volstrekt willekeurig verdeeld zijn, hierdoor kan het gebeuren dat er voor bepaalde stukjes van het eenheidsvierkant helemaal geen sample wordt genomen, terwijl er voor andere stukken van het eenheidsvierkant juist ontzettend veel samples worden genomen. Daardoor ontstaat er te veel ruis en kunnen we nog maar een deel van de afbeelding goed zien. 2 Een vierkantsgetal S is een nummer waarvoor geldt: S = n 2 en n N

36 HOOFDSTUK 5. SAMPLING Jittered sampling Het beste is om de eerste twee methodes te combineren. We verdelen de eenheidsvierkant weer in hokjes, maar in plaats van een sample midden in het hokje te nemen, plaatsen we ze op een willekeurige plek in het hokje. Hierdoor zorgen we ervoor, dat er wel samples voor alle delen van de eenheidsvierkant zijn, maar ook dat ze niet volstrekt regelmatig verdeeld zijn. Ook dit is simpel te implementeren. In plaats van de p en q + 0.5, nemen we p + a en q + b waarbij a en b weer willekeurige getallen tussen de 0 en de 1 zijn. Voor de coördinaten van het samplepunt geldt dus: 5.3 Gebruik van de samples x = (p + a) 1 n y = (q + b) 1 n De samplers kunnen we vervolgens gebruiken bij het afschieten van de rays. Voor één pixel worden er met behulp van de samplers verschillende rays afgeschoten. De camera zal steeds om nieuwe samples vragen, die hij gebruikt om de rays af te schieten. Hij berekent voor elke sample de kleur en daar neemt hij vervolgens het gemiddelde van. We maken gebruik van jittered sampling bij het renderen van de uiteindelijke afbeeldingen, omdat dit de mooiste plaatjes oplevert. Voor de testafbeeldingen maken we gebruik van regular sampling met maar één sample per pixel, zodat we altijd een sample in het midden hebben. Dit doen we, omdat het renderen met minder samples veel sneller gaat en bij testafbeeldingen de kwaliteit nog niet van belang is. Daarnaast zouden we de samples nog kunnen gebruiken bij andere zaken binnen het raytracen. Deze technieken hebben we echter niet geïmplementeerd in onze raytracer. We gebruiken sampling onder anderen bij: belichtingsmodellen (, depth of field en het renderen van halfschaduwen. 5.4 En de raytracer? In dit hoofdstuk hebben we geleerd hoe we kartelrandjes kunnen voorkomen door samples te gebruiken. Op dit moment is het raytracen nog zo eenvoudig dat het nemen van samples nauwelijks uitmaakt voor het eindresultaat. Later, echter, als we belichting (hoofdstuk 6) en reflectie (hoofdstuk 10) en dergelijke gaan toevoegen aan onze raytracer, is sampling wel degelijk van belang. In figuur 5.5 zien we 10.3 aan de ene kant gerenderd zonder samples en aan de andere kant gerenderd met 25 samples. Het verschil is duidelijk te zien. 5.5 Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk hebben gebruikt zijn: [1] en [16]. Code De code voor de samplers is terug te vinden in: jitteredsampler.h, randomsampler.h en regularsampler.h In sampler.h staat de algemene interface voor een sampler.

37 HOOFDSTUK 5. SAMPLING 34 Figuur 5.5: Links: figuur 10.3, geraytracet zonder samples. Rechts: dezelfde scène geraytracet met 25 samples

38 Hoofdstuk 6 Licht Tot nu toe hebben we alleen gekeken of de ray een object raakte en als dat zo was de pixel de kleur van het desbetreffende object gegeven. Hier houdt het proces natuurlijk niet op. Vanaf het snijpunt van het object van de ray gaan we de kleur van de pixel berekenen, die afhankelijk is van het licht wat hierop valt. Eerst zullen we kijken hoe licht (natuurkundig) in elkaar zit en hiermee de rendervergelijking opstellen. De rendervergelijking beschrijft hoe het licht dat een object reflecteert (naar de camera) afhankelijk is van de lichtbronnen in de scène. Vervolgens zullen we een model gebruiken om dit te benaderen in onze raytracer. 6.1 Rendervergelijking The rendering equation, of te wel de rendervergelijking is bedacht door David Immel en James Kajiya in De vergelijking beschrijft hoeveel licht er in de richting van een bepaald punt wordt weerkaatst. Als we hiermee bekijken hoeveel licht er in de richting van de camera wordt weerkaatst, kunnen we de kleur van een punt bereken. Raytracing probeert deze net als andere renderingsmethodes doen te benaderen. De vergelijking vormt daarom de basis voor alle computer graphics. De vergelijking luidt als volgt: L o (p, ω o ) = L e (p, ω o ) + f r (p, ω i, ω o )L i (p, ω i )cosθ i dω i (6.1) 2π Hierbij is L o de hoeveelheid weerkaatste licht (radiance). L e is het licht wat het object zelf uitzendt. De integraal geeft aan hoeveel licht een object weerkaatst. De f r geeft aan hoe een object licht weerkaatst en tenslotte geeft L i het inkomende licht aan. In deze paragraaf zullen we de vergelijking nader toelichten afleiden. We zullen vervolgens deze vergelijking gebruiken als uitgangspunt bij het modelleren van lichtverschijnselen Grootheden Licht bestaat uit fotonen die door een lichtbron worden uitgezonden. De formule voor de energie van een foton is: Q = hc (6.2) λ Waarbij λ de golflengte, h de constante van Planck (h = 6, Js) en c de lichtsnelheid is (c = 2, m s 1 ). De flux (bij fotonen) is de hoeveelheid energie die per seconde door een oppervlak heen gaat en wordt gemeten in J s 1 oftewel in Watt. Φ = Q (6.3) t De volgende logische vraag is dan hoeveel licht er op iets valt. We meten de hoeveelheid licht die op een oppervlak valt. Je drukt dus de hoeveelheid licht E die op een oppervlak valt uit in W m 2. Dit noem je de irradiance. E = Φ A (6.4) 35

39 HOOFDSTUK 6. LICHT 36 De irradiance vertelt ons hoeveel licht er op een oppervlak valt, maar niets over waar het licht vandaan komt. We willen de hoeveelheid licht weten die op een oppervlak valt, uit een bepaalde richting. Dit heet de radiance L. We meten deze richting als een ruimtehoek in steradialen (symbool ω). We kunnen bedenken hoe we dit berekenen door ons voor te stellen hoe een radiancemeter zou werken. We plaatsen een irradiance meter op het oppervlak (deze meet dus hoeveel flux er in totaal op het oppervlak valt). Over de meter plaatsen we een kegel, zodat de meter alleen de stralen die uit een bepaalde ruimtehoek komen meet. (zie figuur 6.1). De meter meet maar een deel van de irradiance, dit noemen we E. De kegel staat in de richting van de ruimtehoek, terwijl de meter op het oppervlak staat. We moeten daarom het geprojecteerde oppervlak van A op het oppervlak hebben (zie figuur 6.1). Figuur 6.1: Radiancemeter staat op het oppervlak, kegel onder een hoek [16] De A is getekend in figuur 6.2, samen met de normaal en het geprojecteerde oppervlak AB. B + C + A 2 = 180 (hoekensom driehoek). Verder is C = 90 dus B + A 2 = 90 Aangezien n de normaal is geldt: A 1 + A 2 = 90, dus B = A 2, oftewel B = θ. Vervolgens volgt uit de cosinus dat AB = BC cosθ oppervlak is dus A cosθ. Voor de radiance geldt dus:. Het geprojecteerde Figuur 6.2: Geprojecteerde oppervlak [1] L = E ω cos θ (6.5) Deze wordt uitgedrukt in W m 2 sr 1. Bij het raytracing slaan we de radiance op als een RGB kleur. In de natuurkunde zijn de formules ook nog afhankelijk van de golflengte λ. Dit doen we bij het raytracen eigenlijk ook; we berekenen de radiance afzonderlijk voor drie golflengtes: rood, groen en blauw. De berekende radiance kunnen we dan direct als kleur gebruiken. Integralen met ruimtehoeken Met de ruimtehoek kun je verschillende integraalberekeningen uitvoeren. Je schrijft een integraal over een ruimtehoek als volgt op: I = f(θ, φ) cos θdω Ω De integraal is hier geschreven als een enkele integraal over de ruimtehoek. Dit is een korte notatie voor de dubbele integraal over θ en φ, omdat er voor een differentiële ruimtehoek geldt dat: dω = sin θdθdφ (vergelijking 1.6 op pagina 13). De cosθ is voor het geprojecteerde oppervlak (zie figuur 6.2). Bij licht nemen we vaak de integraal over een halve bol, om zo bijvoorbeeld al het licht te berekenen dat op een oppervlak valt. Als de functie f(θ, φ) = cos n 1 θ is, dan kunnen we deze integraal exact oplossen. De oppervlakte van

40 HOOFDSTUK 6. LICHT 37 een halve bol is 2π, dus ω = 2π. De integraal wordt dan: I = cos n 1 θ cos θdω 2π = cos n θdω = = 2π 2π 0 2π π π 0 cos n θ sin θdθdφ cos n θd cos θdφ Bij de laatste regel hebben we sin θ achter de d gebracht voor de substitutiemethode. We nemen nu cos θ = u, dan worden de grenzen cos( 1 2π) = 0 en cos 0 = 1. = 2π 0 0 = 2π 0 = 2π 0 = 2π 0 = 2π 0 1 u n dudφ [ 1 n + 1 un+1 [ un+1 n + 1 ] 0 dφ 1 ] 0 dφ 1 0n+1 n + 1 1n+1 n + 1 dφ 1 n + 1 dφ [ = φ n + 1 Berekeningen met radiance en irradiance ] 2π 0 = 2π n + 1 Met de radiance kun je vervolgens weer berekeningen uitvoeren. Uit 6.5 volgt dat: E = L ω cos θ Om nu de irradiance te berekenen, dus de hoeveelheid licht die uit alle richtingen op het oppervlak valt kunnen we een integraal gebruiken. We meten de hoeveelheid licht uit een kleine ruimtehoek dω. We hebben nu een differentiaalvergelijking: de = L dω cos θ Om de irradiance, de totale hoeveelheid te berekenen, moeten we dit dus integreren over alle richtingen waar licht vandaan komt (Ω i ). E = L i cos θ i dω i (6.6) Ω i

41 HOOFDSTUK 6. LICHT Weerkaatsing We zien dingen doordat licht dat op een voorwerp valt gereflecteerd wordt naar onze ogen. Daarom moeten we voor het raytracen weten hoeveel licht een voorwerp weerkaatst in de richting van de camera. Dit is een deel van de totale hoeveelheid licht (irradiance) die op het voorwerp valt. Deze wordt in een bepaalde richting (radiance) naar onze ogen weerkaatst. Als er twee keer zo veel licht op een voorwerp valt, wordt er ook twee keer zo veel licht weerkaatst. Dit verband is dus recht evenredig. Voor een hoeveelheid irradiance de i die op een voorwerp valt, geldt derhalve voor de hoeveelheid radiance dl o die het voorwerp weerkaatst: dl o de i De BRDF (bidirectional reflectance distribution function) geeft de verhouding aan tussen de hoeveelheid radiance die in een bepaalde richting wordt weerkaatst en de totale hoeveelheid irradiance die op het oppervlak valt. Daarmee kunnen we dus berekenen hoeveel radiance er wordt weerkaatst. Hiervoor geldt: f r = dl o de i De BRDF is afhankelijk van het punt waar het licht op valt (de BRDF kan verschillen per plek op het oppervlak), de richting van de radiance die op het voorwerp valt, ω i, en de richting van de radiance die het voorwerp weerkaatst, ω o. De irradiance de i kunnen we uitdrukken in L i volgens de formule 6.5. De L i en L o zijn vervolgens afhankelijk van het punt p waar het licht op valt en natuurlijk de richtingen ω i en ω o. Dit invullen geeft dan: f r (p, ω i, ω o ) = dl o (p, ω o ) L i (p, ω i )cosθ i dω i (6.7) De BRDF blijft hetzelfde voor licht dat in de richting ω i op het oppervlak valt en in de richting ω o wordt weerkaatst en voor het licht dat in de richting ω o invalt en in de richting ω i wordt weerkaatst. Als je dus ω i en ω o omdraait, blijft de BRDF hetzelfde. f r (p, ω i, ω o ) = f r (p, ω o, ω i ) Dit betekent ook dat je je als je BRDF bedenkt, je er voor moet zorgen dat het bovenstaande geldt. De BRDF geeft aan hoe een oppervlak eruit ziet; bijvoorbeeld of het spiegelend of mat is. Een materiaal gebruikt vaak verschillende BRDF s om de uiteindelijke radiance en daarmee de kleur te berekenen. Je kunt de verschillende BRDF s bij elkaar optellen om de totale radiance te berekenen. Reflectievergelijking Met behulp van de vergelijking 6.7 en een integraal kunnen we de hoeveelheid weerkaatst licht berekenen. Voor een differentiële hoeveelheid radiance geldt: dl o (p, ω o ) = f r (p, ω i, ω o )L i (p, ω i )cosθ i dω i Door deze vergelijking te integreren over de ruimtehoek Ω i waarop het licht invalt kunnen we het vervolgens berekenen. L o (p, ω o ) = f r (p, ω i, ω o )L i (p, ω i )cosθ i dω i Ω i Om dan de totale hoeveelheid gereflecteerde radiance te berekenen moeten we voor de inkomende richting een halve bol nemen. Licht kan immers vanuit een halve bol op een punt vallen. We nemen dus Ω i = 2π. L o (p, ω o ) = f r (p, ω i, ω o )L i (p, ω i )cosθ i dω i (6.8) 2π Deze vergelijking heet de reflectievergelijking en beschrijft hoeveel licht er in een bepaalde richting wordt gereflecteerd (bij raytracing hoeveel licht er vanuit een voorwerp naar de camera wordt gereflecteerd).

42 HOOFDSTUK 6. LICHT 39 Voor het licht, afkomstig van één lichtbron s kunnen we de integraal weghalen. We kijken immers nu maar naar één hoeveelheid radiance die op het punt valt, afkomstig van één lichtbron s. Voor de weerkaatste radiance geldt dan: L o,s (p, ω o ) = f r (p, ω i,s, ω o )L i,s (p, ω i,s )cosθ i,s (6.9) We kunnen dus de totale hoeveelheid geflecteerde licht, afkomstig van n lichtbronnen als volgt berekenen: Reflectance L o (p, ω o ) = n f r (p, ω i,j, ω o )L i,j (p, ω i,j ) cos θ i,j (6.10) j=1 De reflectance ρ geeft de verhouding tussen de inkomende flux en de weerkaatste flux weer. Voor de reflectance geldt derhalve: ρ = Φ o Φ i (6.11) Uit de vergelijking voor de rradiance 6.6 volgt dat voor een differentiële hoeveelheid flux geldt: E = L o cosθ i dω i Ω i dφ i = da L i cosθ i dω i Ω i Ditzelfde geldt natuurlijk ook voor de weerkaatste flux. Hierin kunnen we vervolgens de reflectievergelijking invullen. dφ o = da L o cosθ o dω o Ω o = da f r (p, ω i, ω o )L i (p, ω i )cosθ i cosθ o dω i dω o Ω o Ω i Dit kan vervolgens in de vergelijking voor de reflectance worden ingevuld. ρ(p, Ω i, Ω o ) = dφ o (6.12) dφ i da f r (p, ω i, ω o )L i (p, ω i )cosθ i cosθ o dω i dω o Ω = o Ω i da L i cosθ i dω i Ω i f r (p, ω i, ω o )L i (p, ω i )cosθ i cosθ o dω i dω o Ω = o Ω i L i cosθ i dω i Ω i Echte materialen reflecteren niet alle energie, een deel ervan wordt geabsorbeerd. Uit de wet van behoud van energie volgt dat een object nooit meer energie kan uitstralen dat dat er op valt. Daarom moet altijd het volgende gelden (voor de totale hoeveelheid gereflecteerde flux, dus van de halve bol om het punt heen Ω i = Ω o = 2π) ρ(p, 2π, 2π) < 1

43 HOOFDSTUK 6. LICHT Rendervergelijking Een object kan naast licht reflecteren, natuurlijk ook zelf licht uitzenden. Die hoeveelheid noemen we L e (p, ω o ) (de e van emitted). Nu kunnen we met behulp van de reflectievergelijking (6.8) de vergelijking voor de totale hoeveelheid radiance opstellen. Deze noemt men de rendervergelijking: L o (p, ω o ) = L e (p, ω o ) + f r (p, ω i, ω o )L i (p, ω i )cosθ i dω i (6.13) 2π We kunnen de inkomende L i berekenen door een ray uit te sturen in de richting ω i en te kijken wat daar de radiance L o is. We schrijven het eerste snijpunt van een ray met een object als volgt op r c (p, ω i ). (het eerste snijpunt van een ray die vanaf punt p wordt uitgestuurd in de richting ω i ). Voor de inkomende radiance geldt dus: L i (p, ω i ) = L o (r c (p, ω i ), ω i ) Als de ray niks raakt, wordt een zwarte kleur, oftewel een radiance van 0 teruggegeven. 1 Dit invullen geeft: L o (p, ω o ) = L e (p, ω o ) + f r (p, ω i, ω o )L o (r c (p, ω i ), ω i )cosθ i dω i (6.14) Deze vergelijking is een recursieve functie (L o komt zowel links als rechts van het = teken voor). Deze vergelijking is dan ook niet exact op te lossen, maar wel op verschillende manieren te benaderen. Een simpel model hiervoor is het phong belichtingsmodel, welke we aan het eind van dit hoofdstuk beschrijven. 6.2 Lichtbronnen 2π Om te berekenen hoeveel licht er weerkaatst wordt, moeten we natuurlijk eerst definiëren waar licht vandaan komt. We definiëren de lichten met een kleur c l en een schaalfacor l s die aangeeft hoe sterk licht is (hoeveel radiance de lichtbron uitzendt). De lichtbronnen die we hier allemaal beschrijven zijn allemaal geïdealiseerd en zouden niet werkelijk kunnen bestaan. Figuur 6.3: Scène gerenderd met ambient licht Ambient licht In de echte wereld krijgt bijna alles wel via diverse weerkaatsingen licht, hoewel deze niet rechtstreeks van een lichtbron vandaan komt. Bij het raytracen berekenen we in eerste instantie alleen maar de directe verlichting; licht dat rechtstreeks vanaf een lichtbron op een oppervlak valt en niet de indirecte verlichting die via weerkaatsingen op het oppervlak valt. Later zullen we wel de indirecte verlichting gaan berekenen. Voor nu moet we zorgen dat alle objecten toch een beetje licht krijgen. Dit noemen we een een ambient lichtbron. De hoeveelheid licht die objecten hiervan ondervinden is overal hetzelfde. Voor de hoeveelheid inkomende radiance voor ambient licht geldt dus: Voor de gereflecteerde radiance geldt dan: 2 L i = l s c l (6.15) L o (p) = f hh l s c l 1 Eventueel kan in plaats van zwart een andere achtergrondkleur worden teruggegeven. 2 De functie f hh is hierbij geen BRDF functie, maar de hemispeherical-hemispherical reflectance. Deze wordt later in dit hoofdstuk bij shading besproken.

44 HOOFDSTUK 6. LICHT 41 Er is altijd maar één ambient licht bron in de scène aangezien deze overal hetzelfde is (en je dus twee ambient lichtbronnen ook tot één kunt samenvoegen). Voor de rest is L o en f r alleen maar van het punt p afhankelijk (het ene materiaal kan ambient licht anders reflecteren dan een andere), maar niet van van de richting ω i en ω o omdat ieder object evenveel omgevingslicht ondervindt. Hier zit dus ook niet de cosinus factor in. In figuur 6.3 zie je hoe een scène eruit ziet die alleen maar met ambient licht is gerenderd Directional licht Lichstralen bij een directional licht lopen evenwijdig aan elkaar en komen daarom uit één richting. Hun lichtsterkte hangt niet af van de positie. Een directional light is bijvoorbeeld een goede benadering van de zon. Het wordt naast c l en l s gedefinieerd met een richting l. Deze richting l is tegengesteld aan de richting van de lichtstralen. De hoek die l met de normaal op het object maakt is de hoek θ uit de reflectievergelijking (zie figuur 6.4). Voor de gereflecteerde radiance van één licht d geldt dan: L o,d (p, ω o ) = f r (p, l d, ω o ) l s,d c l,d cos θ l,d (6.16) Voor een n aantal directional lichten kan de gereflecteerde radiance worden berekend met een som: n L o (p, ω o ) = f r (p, l j, ω o ) l s,j c l,j cos θ l,j j=1 In figuur (6.5) is een voorbeeld te zien van een scène die met directional licht is gerenderd Puntlicht De derde lichtbron is een puntlichtbron. Licht wordt vanaf één punt gelijk verspreid in alle richtingen. We geven de sterkte van het licht aan met de intensiteit I in flux per ruimtehoek (W sr 1 ). We kunnen de totale hoeveelheid flux berekenen met een integraal over de hele bol (4π) om het punt heen. Deze is exact op te lossen (zie paragraaf 6.1.1). Φ = Idω = 2 cos 0 Idω = 2 4π 2π Figuur 6.4: De gedefinieerde richting en de richting van de lichtstralen (boven), de hoek θ met de normaal (onder) [1] 2π I = 4πI Hiermee kunnen we vervolgens de irradiance berekenen. Voor de oppervlakte van een bol geldt A bol = 4πr 2, dus: E = Φ A = 4πI 4πr 2 = I r 2 = I 1 r 2 De irradiance neemt dus kwadratisch af als de afstand (r) tot de lichtbron toeneemt. Dit is de kwadratenwet uit de natuurkunde. We definiëren het licht voor de rest weer met een kleur c l en een schaalfacor l s. Voor de intensiteit geldt dan I = c l l s. Dit kunnen we invullen in de vergelijking voor de BRDF (6.7), waarbij we nu de irradiance weten. Er geldt dan voor de gereflecteerde radiance van één lichtbron d: L o,d (p, ω o ) = f r (p, l d (p), ω o ) l s,d c l,d 1 rd 2 cos θ l,d (6.17) De totale hoeveelheid gereflecteerd licht van n lichtbronnen kunnen we weer berekenen met een som: L o (p, ω o ) = n j=1 f r (p, l j (p), ω o ) l s,j c l,j 1 r 2 j cos θ l,j

45 HOOFDSTUK 6. LICHT 42 Figuur 6.5: Scène gerenderd met directional licht (links), puntlicht met kwadratenwet (midden) en puntlicht zonder kwadratenwet(rechts) Merk op dat de richting van het inkomende licht l nu in tegenstelling tot bij directional light ook afhankelijk is van het punt waar het ligt op valt. De 1 r bepaalt de afname van de lichtsterkte door de afstand. In de 2 praktijk blijkt de kwadratenwet hiervoor niet zo goed te werken. Het oppervlak dicht bij het de bron wordt snel overbelicht (zie het einde van dit hoofdstuk) en de lichtsterkte neem snel af. Daarom kan je in onze 1 raytracer aangeven of je de kwadratenwet wel wilt gebruiken. r staat dan ook los in de vergelijking, om aan 2 te geven dat deze weggelaten kan worden. Bij figuur (6.5) is een voorbeeld te zien van een scène die met een puntlicht is gerenderd, met en zonder de kwadratenwet. 6.3 Shading Figuur 6.6: Perfecte diffuse weerkaatsing [1] We kunnen nu met behulp van de lichten en de vergelijkingen die we net hebben besproken de objecten in de scène gaan shaden. Shading is het bepalen van de kleur van een object aan de hand van de verschillende lichtbronnen. We gebruiken hiervoor phong shading. Dit is een (simpel) model om de kleur van de objecten te bepalen en daarmee de rendervergelijking te benaderen. Het model is bedacht in 1973 door Bui Tuong Phong. Het bestaat uit drie componenten: het ambient deel, het diffuse deel en het specular deel (zie figuur 6.7). Als we een object alleen met het ambient deel en het diffuse deel renderen, krijgen we een mat oppervlak. Je zou hiermee bijvoorbeeld het licht dat op papier of mat hout valt kunnen renderen. Dit noemen we het diffuse materiaal. We kunnen ook een object renderen met alle drie de dingen, dit noemt men het phong materiaal. Tenslotte zullen we bekijken of een object wel licht van een lichtbron kan krijgen of dat het in de schaduw staat. Figuur 6.7: Het phong model [17]

46 HOOFDSTUK 6. LICHT Diffuse We beginnen met het diffuse deel, omdat we hieruit later ook het ambient deel kunnen afleiden. Het diffuse deel zorgt voor perfecte diffuse weerkaatsing; het inkomende licht wordt gelijkmatig in alle richtingen weerkaatst (zie figuur 6.6). We definiëren het diffuse oppervlak met de reflectance ρ d. Om vervolgens de hoeveelheid weerkaatste radiance te kunnen berekenen, moeten we de BRDF weten. Omdat het licht in alle richtingen gelijkmatig wordt weerkaatst, is de BRDF niet afhankelijk van de richting van het licht. Daarom kunnen we voor de radiance die gereflecteerd wordt door een diffuse oppervlak L o,d, de BRDF functie f d uit de integraal in de reflectievergelijking halen (6.9). In de BRDF functie zitten immers geen variabelen meer waarover geïntegreerd wordt. Vervolgens kunnen we vergelijking 6.6 hierin substitueren: L o,d (p) = f r,d (p, ω i, ω o )L i (p, ω i )cosθ i dω i Ω i = f r,d (p) L i (p, ω i )cosθ i dω i Ω i = f r,d (p)e i (p) f r,d (p) = L o,d(p) E i (p) De hoeveelheid weerkaatste flux is te berekenen met een integraal (zie paragraaf 6.1.2). Hier kunnen we L r,d (p) uit de integraal halen, omdat deze niet afhankelijk is van de richting van het licht. De integraal die overblijft is vervolgens exact op te lossen. Ω o = 2π aangezien het licht in de halve bol om het punt heen weerkaatst wordt (zie figuur 6.6). dφ o = da L o,d (p, ω o )cosθ o dω o Ω o = dal o,d (p) cosθ o dω o = dal o,d (p) = dal o,d (p)π 2π 2π Voor de inkomende flux geldt: dφ i = dae i (p) We kunnen dit invullen in de vergelijking voor de reflectance (6.11). Hier komt nu de vergelijking voor de BRDF f r,d (p) in voor. ρ d (p) = Φ o Φ i = dal o,d(p)π dae i (p) = π Lo,d(p) E i (p) = πf r,d (p) f r,d (p) = ρ d(p) π Hiermee hebben we de BRDF voor het diffuse deel van het model berekend en kunnen we de hoeveelheid weerkaatst licht berekenen. Aangezien een object alleen zijn eigen kleur c p weerkaatst, moeten we deze kleur

47 HOOFDSTUK 6. LICHT 44 als een factor in de vergelijking opnemen, anders zou het object niet de goede kleur krijgen. De uiteindelijke BRDF voor het diffuse deel wordt dus als volgt: Ambient f r,d (p) = ρ d(p) π Het ambient deel zorgt voor de weerkaatsing van het ambient licht in de scéne. Omdat ambient licht van alle kanten komt, kunnen we hier geen BRDF voor gebruiken. In plaats daarvan gebruiken we de hemisphericalhemisperical reflactance, wat de verhouding aangeeft tussen het licht dat op de gehele halve bol binnenkomt en over de gehele halve bol wordt weerkaatst. Deze kunnen we berekenen met de formule voor de reflectance. We mogen hierbij L i uit de integraal halen, omdat deze constant is. Ook f r kunnen we uit de integraal halen omdat deze niet afhankelijk is van ω i en ω o. Ω o = Ω i = 2π, het gaat om de halve bol. We kunnen de integralen vervolgens weer exact oplossen. c p f r,d (p, ω i, ω o )L i (p, ω i ) cos θ i cos θ o dω i dω o Ω f hh (p) = o Ω i L i cos θ i dω i Ω i f r,d L i cos θ i cos θ o dω i dω o 2π 2π = L i cos θ i dω i 2π = f r,d cos θ i cos θ o dω i dω o L i = f r,d L i 2π 2π 2π = f r,d L i 2π 2 2π 2 cos θ odω o cos θ o dω o 2π = f r,d 2π 2π 2 2π 2 2 = πf r,d = ρ d (p) Hiermee kunnen we nu het ambient deel van het model berekenen, uitgaande van gedefinieerde ρ d voor het oppervlak. Ook hier geldt weer dat we het nog keer de kleur van het oppervlak c p moeten doen Specular De specular reflection laat de weerkaatsing van de lichtbron op het oppervlak zien. Hiervoor moeten we eerst de richting van de weerkaatsing berekenen. Uit de terugkaatsingswet van de natuurkunde weten we dat i = t. Hierdoor is de hoek wel bekend, maar nog niet de richtingsvector. Deze gaan we hier berekenen. De vector l geeft de richting van het invallende licht aan, n is de normaal en r is de richting van het teruggekaatste licht. Verder is θ de hoek met de normaal (zie figuur 6.8). Het zijn allemaal eenheidsvectoren. Omdat l, n en r allemaal in hetzelfde vlak liggen, moet r een lineaire combinatie van l en n zijn. Vervolgens nemen we aan beide kanten het inproduct met de normaal: r = a l + b n r n = a l n + b n n Omdat het allemaal eenheidsvectoren zijn, levert het inproduct direct de cosinus op. Omdat de hoek van inval gelijk is aan de hoek van terugkaatsing leveren r n en l n allebei cos θ op. De normaal maakt

48 HOOFDSTUK 6. LICHT 45 Figuur 6.8: l, n, r en het vlak (links), n (midden), de hoek α met de kijkrichting ω o (rechts) [1] natuurlijk een hoek van 0 graden met zichzelf en de cosinus hiervan levert 1 op. Dit kunnen we vervolgens verder gaan herleiden. cos θ = a cos θ + b cos 0 b = cos θ a cos θ b = l n a l n b = (1 a) l n Vervolgens kunnen we een eenheidsvector n loodrecht op n opstellen. Nu nemen we het inproduct met n. r n = a l n + b n n cos(90 + θ) = a cos(90 θ) + b cos(90) cos(90 + θ) = a cos(90 θ) Deze hoeken schrijven we vervolgens in radialen op: cos(π + θ) = a cos(π θ) Zoals we weten is cos(π + θ) = cos(π θ) en hieruit volgt dat a = 1. Dit kunnen we vervolgens invullen in de eerste vergelijking: Specular licht r = a l + b n r = 1 l + ((1 1)( l n)) n r = l + 2( n l) n (6.18) Het specular licht is de weerkaatsting van de lichtbron op het oppervlak. Het licht valt in in de richting l en wordt weerkaatst in de richting r. Met de camera zien we het licht dat in de richting ω o van de camera wordt weerkaast (zie rechterplaatje bij figuur 6.8). De hoeveelheid licht (van de specular reflectie) die we kunnen zien met de camera is dus afhankelijk van de hoek α tussen r en ω o. Hoe groter α, hoe kleiner de hoeveelehid. Phong modelleerde deze afname als volgt: (cos α) e, waarbij e de Phong exponent is die aangeeft hoe groot de specular weerkaatsing is. Voor e geldt tevens e o. Hiermee kunnen we de BRDF voor de specular weerkaatsing opstellen. 3 f r,d (p, ω i, ω o ) = k s (r ω o ) e (6.19) 3 De BRDF voor specular geeft een reflectie van de lichtbron op het oppervlak aan. We hoeven dit dus niet keer de kleur van het oppervlak te doen

49 HOOFDSTUK 6. LICHT 46 Hier hebben we de hoek α met het inproduct tussen r en ω o berekent. r hebben we hierboven berekent. Daarnaast hebben we een factor k s toegevoegd die aangeeft hoeveel de specular reflectie bijdraagt aan de totale reflectie. Het samenvoegen van ambient, diffuse en specular licht geeft ons, zoals gezegd, het Phongmateriaal. Figuur 6.9 is een voorbeeld van een scéne gerenderd met drie bollen en een vlak, die alle het Phongmateriaal hebben Schaduw Een object krijgt alleen licht van een lichtbron, als er ook daadwerkelijk licht van die lichtbron op het object kan vallen. Er moeten dus geen andere objecten tussen de lichtbron en het desbetreffende object staan. We kunnen dit uitvinden, door vanaf het object een ray richting de lichtbron te sturen, en te kijken of deze ray nog een ander object raakt voor het de lichtbron bereikt. Als het licht zich echter achter het oppervlak van het object bevindt, kan het überhaupt geen licht ontvangen. Voor de hoek α tussen de de normaal n en de richting van het licht l moet dus gelden dat π < α < π, anders staat de lichtbron achter het oppervlak. Hierin is de hoek α in radialen. Dit betekent dat er voor inproduct moet gelden: 4 n l > 0 De normaal moet dan wel in de richting van de camera staan, zodat we naar de goede kant van het oppervlak kijken. Als dat niet zo is, moeten we de normaal omdraaien. Dit gebeurt bijvoorbeeld als we de binnenkant van een cilinder renderen. De normaal van een cilinder wijst naar buiten (van de cilinder af), maar als we de binnenkant van een cilinder renderen Figuur 6.9: Scène met een puntlichtbron, een ambient lichtbron en een directional lichtbron, vier objecten met het Phongmateriaal en schaduwen. moet hij juist naar binnen wijzen. Om dit te voorkomen controleren of het inproduct tussen de normaal n en de richting van het weerkaastse licht naar de camera ω o groter dan 0 is. Als dat niet zo is, draaien we de normaal om. Als het bovenstaande geldt gaan we vervolgens met behulp van rays kijken of er geen objecten in de weg staan. We schieten vanaf het punt p op het oppervlak een ray naar elk licht. Als die ray een object raakt moeten bedenken of het object tussen het oppervlak en het licht staat of pas achter het licht komt. Hiervoor moeten we dus kijken wat er dichterbij is, het object of de lichtbron. We kunnen dit controleren door te kijken of de t van de ray kleiner is dan de afstand tot de lichtbron. Bij directional licht hoeft dit natuurlijk niet, aangezien zo n lichtbron oneindig ver weg staat. Met deze methode kunnen we dus bekijken of een oppervlak in de schaduw staat of niet. Doordat we geïdealiseerde lichten gebruiken, ontstaan er alleen harde schaduwen. Een punt of een oppervlak krijgt of wel, of geen licht en er zit niets tussenin. In figuur 6.9 staat een voorbeeld van een scène gerenderd met schaduwen Renderen Alle in dit hoofdstuk beschreven aspecten hebben we nodig om het licht te kunnen renderen. Het hele proces gaat dus als volgt: 1. De camera schiet een ray af. Als de ray een object raakt gaan we op dat punt de kleur berekenen. 2. De hoeveelheid ambient licht wordt berekend. 3. Er worden schaduwrays naar elke lichtbron uitgestuurd. 4 n en l zijn immers eenheidsvectoren, dus als het inproduct kleiner is dan nul, geldt dat de hoek tussen n en l groter is dan 90 graden, want de inverse cosinus van een negatief getal is groter dan negentig graden. 5 Om wel halfschaduwen te krijgen, zouden we gebruik kunnen maken van area lights. Hierbij geeft niet een punt, maar een heel oppervlak licht. Hier zijn wij echter niet meer aan toegekomen.

50 HOOFDSTUK 6. LICHT Voor elke lichtbron waarvan het licht het punt kan berekenen wordt de invallende radiance berekent. 5. Met behulp van de BRDF voor diffuse deel (in het geval van het duffse materiaal) of de BRDF voor het diffuse deel en het specular deel wordt de hoeveelheid weerkaatste radiance berekent. 6. De gereflecteerde radiance van alle lichtbronnen wordt bij elkaar opgeteld. Hieruit volgt dan direct de kleur die de camera ziet, dus de kleur van de pixel. Een oppervlak kan zoveel licht weerkaatsen, dat een of meer van de r, g, b waarden groter dan 1 wordt. Aangezien de waarden r, g en b tussen de 0 en de 1 moeten vallen, kunnen we zo geen kleur laten zien. Het punt is dan overbelicht. We kunnen dit op twee manieren oplossen. Ten eerste kunnen we alle punten die overbelicht zijn in een bepaalde kleur (rood of wit) veranderen, zodat je kunt zien welke punten overbelicht zijn. Dit is handig bij het bouwen van een afbeelding, maar geeft natuurlijk geen mooi plaatje. Daarom kun je ook instellen dat de raytracer de waarde van r, g en b aanpast. De r, g, b waarden worden allemaal gedeeld door de grootse waarde(r, g of b) zodat de kleur weer binnen het bereik valt. 6.5 En de raytracer? In dit hoofdstuk hebben we de werking van licht in onze raytracer besproken. We hebben drie verschillende lichtbronnen besproken, en uitgelegd hoe schaduwen werken. In 6.10 zien we hoe de toegevoegde stof de raytrace uit figuur 4.4 beïnvloedt. Deze scène is nu gerenderd met op alle objecten phongmateriaal, een ambient lichtbron, een directional lichtbron, een puntlichtbron en 25 samples (jittered sampling). 6.6 Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk hebben gebruikt zijn: [1], [16], [6], [17], [18] en [5]. Figuur 6.10: De simpele scène Code uit figuur 4.4 gerenderd met licht. De code voor de lichten is terug te vinden in ambient.h, directional.h en pointlight. De interface voor een licht staat in licht.h. De materiaal klassen zijn verantwoordelijk voor het shaden. De code hiervoor is terug te vinden in matte.h, phong.h en material.h waar de interface te vinden is. Daarnaast wordt de ShadeRec klasse, te vinden in shaderec.h gebruikt voor het uitwisselen van informatie tussen licht, materiaal en oppervlak.

51 Hoofdstuk 7 Transformatie Het uitvoeren van transformaties op objecten kan een handige manier zijn om objecten te verplaatsen, te draaien of te vervormen. Vooral voor het verplaatsen van lastigere objecten, zoals voorkomen in hoofdstuk 8 is het handiger om deze objecten te verplaatsen door middel van transformaties. In dit hoofdstuk zullen we uitleggen hoe we transformaties uit kunnen voeren op objecten en hoe we deze vervolgens kunnen raytracen. 7.1 Verschillende transformaties Er zijn verschillende soorten transformaties. Zo hebben we onder andere translatie, verschalen, rotatie, spiegeling en glijspiegeling. Wij zullen alleen translatie, verschalen, rotatie en spiegeling behandelen. Laten we beginnen met het uitleggen van wat deze verschillende transformaties eigenlijk allemaal inhouden. Verschalen: Verschalen is het vergroten of verkleinen van een object. Spiegeling: Spiegeling is het spiegelen van een object in een bepaalde lijn of een bepaald punt. Wij zullen alleen spiegeling in de x-as, de y-as of de z-as behandelen. Rotatie: Rotatie is het draaien van een punt rond een bepaald punt of een bepaalde lijn. Wij zullen alleen rotatie rond de x, de y en de z-as behandelen. Translatie: Translatie is het verplaatsen van een punt (of object) in de wereld, in een gegeven x-richting, een gegeven y-richting en een gegeven z-richting. In de volgende paragrafen zullen we eerst translaties in 2D behandelen, omdat dit het begrijpen van 3D translaties erg zal vereenvoudigen. Vervolgens zullen we de translaties verder tillen naar 3D. 7.2 Transformaties in 2D Als we punt p gaan transleren in een 2D wereld (O xy ), dan kunnen we de getransleerde coördinaten als volgt opschrijven: x = ax + by y = cx + dy (7.1) Hierin zijn x en y allebei een combinatie van de x en de y en twee bepaalde factoren voor deze waarden. De enige uitzondering hierop is translatie, waarbij x en y kunnen worden beschreven als een constante opgeteld bij de originele x en y-waarden. Maar hier komen we later op terug. We kunnen 7.1 in een vergelijking van matrices opschrijven. We krijgen dan: [ ] [ [ ] x a b x y = (7.2) c d] y De matrix met a, b, c en d is de transformatiematrix. We zullen al onze transformaties door middel van transformatiematrices uitvoeren. 48

52 HOOFDSTUK 7. TRANSFORMATIE Verschalen Verschalen is het vergroten of het verkleinen van een object. Dit betekent dus dat we van het object voor elk punt de x en de y een factor groter of kleiner maken. We kunnen dit doen door voor de transformatiematrix bij een verschaling van V (a, b), dus x verschalen met een factor a en y verschalen met een factor b, de volgende matrix te nemen: [ ] a 0 V (a, b) = 0 b Want als we dit invullen in 7.2 krijgen we het volgende: [ ] [ ] [ ] x a 0 x y = = 0 b y Spiegeling [ ] ax by Bij spiegeling in de x-as, verandert het teken (+ of -) van de y-coördinaat van een punt. Zo wordt een negatieve y-coördinaat positief en een positieve y-coördinaat wordt negatief. Dit geldt natuurlijk ook bij spiegeling in de y-as, maar dan voor de x-coördinaat (zie figuur 7.1). Zo kunnen we de spiegelingen in respectievelijk de x en de y-as met de volgende transformatiematrices uitvoeren: [ ] 1 0 S x = 0 1 [ ] 1 0 S y = Rotatie Rotatie is een van de moeilijkere translaties. We zullen de transformatiematrix voor rotatie uitleggen met behulp van een feit dat we elke vector als volgt kunnen schrijven: ( ) ( ( a 1 0 = a + b b 0) 1) Figuur 7.1: De blauwe cirkel wordt gespiegeld in de y-as. p(x, y) wordt p( x, y). Als we een vector v met kentallen (1, 0) roteren over een hoek θ, worden de kentallen van v (cos θ, sin θ) (zie figuur 7.2). Voor de geroteerde vector v R geldt dus: ( ) ( ( ) cos θ cos θ 0 1 v R = = sin θ sin θ 0) 0 Als we een vector w met kentallen (0, 1) roteren over een hoek θ, worden de kentallen van w ( sin θ, cos θ) (zie figuur 7.2). We krijgen dus: ( ) ( ) ( sin θ 0 sin θ 0 w R = = cos θ 0 cos θ 1) Deze allebei invullen in vergelijking 7.3 geeft voor een vector a met ( ) ( ) ( ) ( ) 1 cos θ sin θ a R = a + b 0 sin θ cos θ ( ) ( ) ( ) ( ) a cos θ sin θ = + 0 sin θ 0 b 0 cos θ ( ) ( cos θ sin θ a = sin θ cos θ b) ( ) a geroteerd over hoek θ: b (7.3)

53 HOOFDSTUK 7. TRANSFORMATIE 50 Om iets over een hoek θ te laten roteren, gebruiken we de volgende transformatiematrix: [ ] cos θ sin θ R(θ) = sin θ cos θ We zien dat zowel x als y afhankelijk zijn van zowel de originele x-coördinaat als de originele y-coördinaat. Figuur 7.2: Links: Het roteren van een vector met kentallen (1, 0). Rechts: Het roteren van een vector met kentallen (0, 1) Translatie Tot slot hebben we translatie. Translatie ( ) is in theorie de makkelijkste translatie om uit te voeren. De dx vergelijkingen voor een translatie van punt p met (x, y) zien er namelijk als volgt uit: d y x = x + d x y = y + d y In matrixvorm wordt dit: [ ] x = y [ dx d y ] + [ ] x y Hoewel dit misschien de makkelijkste transformatie is, zorgt hij toch voor een probleem. We willen namelijk vaak een aantal translaties achter elkaar uitvoeren. Dit gaat het makkelijkst als de translaties allemaal een standaard patroon volgen. Daarbij willen we ook graag dat we de inverse matrix kunnen nemen van een transformatiematrix, om redenen die later duidelijk zullen worden. Dit kan alleen met een vierkante matrix. We willen dus voor de transformatiematrix een vierkante matrix hebben, die wel, als we hem steeds met andere getallen invullen, voor elke transformatie kunnen gebruiken. Dit probleem wordt opgelost door een transformatiematrix in 3D te nemen voor 2D transformaties. We nemen hiervoor aan dat het (x, y)-vlak in een imaginair 3D-stelsel ligt met een W -as erbij. Ook nemen we aan dat voor alle punten in het (x, y)-vlak geldt dat W = De projectieve wereld Zoals gezegd gaan we voor translaties in 2D een 3D-wereld gebruiken. Deze 3D-wereld noemen we een projectieve wereld. De drie assen in deze wereld noemen we X, Y en W. Coördinaten uitgedrukt in (X, Y, W ) zijn homogene coördinaten. Ons 2D-vlak (x, y) heeft in deze projectieve wereld zijn oorsprong in het punt

54 HOOFDSTUK 7. TRANSFORMATIE 51 (uitgedrukt in homogene coördinaten) (0, 0, 1). Hierbij zijn de x en de X-as parallel aan elkaar en de y en de Y -as ook, zodat zowel de x en X-coördinaten als de y en de Y -coördinaten altijd aan elkaar gelijk zijn. We behandelen nu elk punt in het (x, y)-vlak alsof het bestaat in de projectieve wereld. Voor elk punt in (x, y) geldt dus nu dat we het uitdrukken als (X, Y, 1). Met deze gegevens kunnen we alle transformaties in het (x, y) vlak uitvoeren met een vermenigvuldiging van een 3 3-matrix en een 3 1 matrix: de coëfficientenmatrix en de matrix met de coördinaten van het punt dat we transformeren. Ook kunnen we zo een punt transleren in het vlak met een vierkante matrix en een matrixvermenigvuldiging. Zo kunnen we voor translatie, verschalen, rotatie en spiegeling de volgende transformatiematrices nemen: 1 0 d x T (d x, d y ) = 0 1 d y V (a, b) = a b cos θ sin θ 0 R(θ) = sin θ cos θ S x = S y = Dit kan allemaal worden gecontroleerd door deze transformatiematrices in te vullen in de algemeen geldende transformatieformule: p = T p (7.4) Hierin is p het originele punt, uitgedrukt in (X, Y, W ), p het getransformeerde punt, uitgedruk in (X, Y, W ) en T de transformatiematrix. In al deze transformaties blijf de W -coördinaat van het resultaat 1. p houdt dus altijd de coördinaten (x, y, 1), wat het makkelijk maakt om dit punt in het (x, y) stelsel aan te duiden. 7.3 Transformaties in 3D De methodes die we hebben gebruikt om 2D-transformaties uit te voeren, zijn eenvoudig om te zetten naar 3D-transformaties. Hier zullen we ook met transformatiematrices gaan werken die één dimensie meer hebben dan de originele punten. We zullen dus gaan werken met 4 4 en 4 1 matrices. Ook hier geldt vergelijking 7.4. Het enige wat we nog hoeven te doen is de transformatiematrices van de verschillende transformaties om te zetten naar 4 4-matrices Translatie Hoewel we in 2D zijn geëindigd met translaties, zullen we er hier mee beginnen. De vier dimensionale transformatiematrix voor translaties is namelijk heel eenvoudig te bedenken. Deze ziet er namelijk zo uit: d x T (d x, d y, d z ) = d y d z

55 HOOFDSTUK 7. TRANSFORMATIE 52 Dit invullen in vergelijking 7.4 geeft: p = T p d x x x + d x = d y y d z z = y + d y z + d z x y z 1 Figuur 7.3: Links: Een ongetransformeerde driehoek. Rechts: De driehoek getransleerd met d x = 150, d y = 50 en d z = Verschalen Figuur 7.4: Links: Een ongetransformeerde bol. Midden: Een bol verschaald met a = 2, b = 1 en c = 1. Rechts: een bol verschaald met a = 1.5, b = 2.5 en c = 1. Ook de transformatiematrix voor het verschalen van een object is eenvoudig af te leiden uit de drie dimensionale matrix die we in hebben gebruikt. De transformatiematrix voor het verschalen van een

56 HOOFDSTUK 7. TRANSFORMATIE 53 object in 3D ziet er als volgt uit: a V (a, b, c) = 0 b c Als we dit invullen in vergelijking 7.4 zien we dat het goede geprojecteerde punt eruit komt Rotatie Figuur 7.5: Links: Een ongetransformeerde driehoek. Rechts: De driehoek geroteerd over de z-as met 90 ( 1 2 π radialen) In 2D hebben we alleen geroteerd om de oorsprong van het 2D-stelsel. In 3D hebben we echter drie verschillende assen waar we alledrie om kunnen roteren. Als we om de x-as roteren, roteren we het object in het (y, z)-vlak. Hierbij blijft de x-coördinaat dus constant en kunnen we om y en z te berekenen dezelfde waarden gebruiken als in Dit leidt tot de volgende transformatiematrices om te roteren om respectievelijk de x, de y en de z-as: R x (θ) = 0 cos θ sin θ 0 0 sin θ cos θ cos θ 0 sin θ 0 R y (θ) = sin θ 0 cos θ cos θ sin θ 0 0 R z (θ) = sin θ cos θ Ter illustratie zullen we het punt p(1, 2, 3) roteren over de y-as over een hoek van 90 graden, oftewel 1 2 π

57 HOOFDSTUK 7. TRANSFORMATIE 54 radialen. x cos θ 0 sin θ 0 x y z = y sin θ 0 cos θ 0 z W cos 1 2 π 0 sin 1 2 π 0 1 = sin 1 2 π 0 cos 1 2 π = = In figuur 7.5 is een driehoek te zien die met negentig graden is geroteerd over de z-as Spiegeling Tot slot hebben we spiegeling. Spiegeling in 3D betekent dat we het teken van één van de coördinaten veranderen (dus van negatief naar positief of andersom). Dit doen we in 3D voor respectievelijk de x, y en de z-coördinaten op de volgende manier: S x = S y = S z = Figuur 7.6: Links: Een ongetransformeerde driehoek. Linksmidden: De driehoek gespiegeld in de x-as. Rechtsmidden: De driehoek gespiegeld in de y-as. Rechts: De driehoek gespiegeld in de z-as Opmerkingen over transformaties Belangrijk om op te merken is dat de volgorde waarin we transformaties uitvoeren van belang is voor de uiteindelijke uitkomst. Zo krijgen als we eerst transleren en vervolgens roteren het object op een andere plek

58 HOOFDSTUK 7. TRANSFORMATIE 55 in de wereld dan als we eerst roteren en daarna transleren. Over transformaties in de raytracer moet dus goed worden nagedacht. Een andere belangrijke opmerking is dat we zelfs bij meerdere transformaties eigenlijk maar één formule willen hebben, namelijk de formule in 7.2. Dit kan door al deze transformatiematrices samen te voegen tot één transformatiematrix. Dit doen we door ze met elkaar te vermenigvuldigen. Hier moeten we er wel weer aan denken dat matrix A met matrix B vermenigvuldigen iets anders oplever dan matrix B met matrix A vermenigvuldigen. Als we bijvoorbeeld de translatie (d x, d y ) en de verschaling S(a, b) willen uitvoeren, kan dat op twee manieren: 1 0 d x a 0 0 a 0 d x T (d x, d y ) S(a, b) = 0 1 d y 0 b 0 = 0 b d y S(a, b) T (d x, d y ) = a b d x 0 1 d y = a 0 ad x 0 b bd y We zien dat T S neerkomt op eerst een verschaling en dan een verplaatsing en dat S T neerkomt op eerst een verplaatsing en dan een verschaling. De transformatie die voor het -teken staat gebeurt dus als eerst en de transformatie die achter het -teken staat komt erna. We krijgen dus voor de uiteindelijke transformatiematrix bij n transformaties die op nummer uitgevoerd moeten worden (dus transformatie 1 eerst, dan transformatie 2 enzovoort tot transformatie n) de volgende formule: T = T n T n 1 T n 2...T 2 T 1 (7.5) 7.4 Rayintersectie met getransformeerde objecten Rayintersectie met getransformeerde objecten is een lastige opgave. We hebben namelijk geen vergelijking voor het getransformeerde object. We hebben alleen het ongetransformeerde object en de stappen die we met dit object ondernemen. Het is met deze informatie veel makkelijker om in plaats van het originele object te transformeren, een inverse transformatie op de ray uit te voeren. Vervolgens kunnen we met deze invers getransformeerde ray een snijpunt met het object berekenen. Dit punt kunnen we vervolgens weer transformeren om de plek te krijgen waar de ongetransformeerde ray het getransformeerde object zou raken. Als we dan ook de normaal op het punt meetransformeren, hebben we daarmee het snijpunt en de normaal en kunnen we daarmee verder renderen. We werken dus volgens de volgende stappen: 1. We voeren de inverse transformaties uit op de ray. 2. We zoeken het snijpunt van de invers getransformeerde ray met het ongetransformeerde object. 3. We berekenen de normaal op dit snijpunt. 4. We transformeren het snijpunt en de normaal van het snijpunt om het punt, en de normaal op dat punt, te krijgen waar de originele ray het getransformeerde object zou raken Inverse transformaties Om een inverse transformatie uit te voeren op een ray, moeten we zowel de oorsprong van de ray (o), als de richtingsvector ( d) invers transformeren. Het transformeren van punten en vectoren gaat niet precies hetzelfde. Dit is omdat een punt een vaste plaats aangeeft in de wereld, ( terwijl de vector een richting 2 aangeeft. Een vector heeft dus geen vaste plek. Zo kan een vector a = op de x-as liggen, maar zou hij 0) ook op y = 1 kunnen liggen. Zowel voor een punttransformatie als voor een vectortransformatie hebben we echter transformatiematrices nodig, en in dit geval dus inverse transformatiematrices.

59 HOOFDSTUK 7. TRANSFORMATIE 56 Inverse transformatiematrices Hoewel er formules bestaan om inverse matrices te bepalen, hebben we deze niet nodig. Het is voor de transformatiematrices die wij gebruiken namelijk heel makkelijk om inverse transformatiematrices te bedenken zonder dat er (veel) wiskunde aan te pas komt. We krijgen dan namelijk voor de inverse transformatiematrices de volgende matrices: d x T 1 (d x, d y, d z ) = d y d z a V 1 1 (a, b, c) = 0 b c R 1 x (θ) = R 1 y (θ) = R 1 z (θ) = 0 cos θ sin θ 0 0 sin θ cos θ cos θ 0 sin θ sin θ 0 cos θ cos θ sin θ 0 0 sin θ cos θ De inverse spiegelingstransformatiematrices staan hier niet bij, omdat de inverse matrices van deze matrices gelijk zijn aan de gewone matrices. Bij de inverse rotatiematrices maken we gebruik van het feit dat sin 2 θ + cos 2 θ = 1. Het invers transformeren van de ray Om een ray invers te transformeren, nemen we aan dat de originele ray die we uitschieten getransformeerd is. Van vergelijking 2.15 maken we dus: p = o + t d (7.6) Hierbij verhouden punten op de invers getransformeerde ray zich natuurlijk met punten op de echte ray op de volgende manier (hierin is p een punt op de echte ray en p een punt op de invers getransformeerde ray, en dus ook op het ongetransformeerde object): p = T p Hierin is T de transformatiematrix. Er geldt dus voor een punt op de invers getransformeerde ray: p = T 1 p Voor p gold vergelijking 7.6 dus geldt voor p op de invers getransformeerde ray: Oftewel: p = T 1 (o + t d) = T 1 o + tt 1 d p = o + t d o = T 1 o d = T 1 d

60 HOOFDSTUK 7. TRANSFORMATIE 57 Nu zijn we aangekomen op het punt waar we een punt en een vector invers moeten kunnen transformeren. Het verschil is, zoals al gezegd, dat een punt een vaste plaats aangeeft in een wereld, terwijl een vector een, niet-plaatsgebonden, richting aangeeft. Kortom: we kunnen punten wel transleren, maar vectoren niet. Bij de homogene coördinaten hoeven we een vector dus niet vast te zetten op W = 1. We krijgen dan voor o en d : m 00 m 01 m 02 m 03 o x o = m 10 m 11 m 12 m 13 o y m 20 m 21 m 22 m 23 o z m 00 m 01 m 02 m 03 d x d = m 10 m 11 m 12 m 13 d y m 20 m 21 m 22 m 23 d z Vervolgens kunnen we met de normale snijpuntsberekeningen uit hoofdstuk 3 of hoofdstuk 8 gebruiken om het snijpunt met de invers getransformeerde ray met het ongetransformeerde object en de normaal op dat punt te berekenen. Deze kunnen we vervolgens transformeren en voilà: we kunnen een getransformeerd object raytracen. Het transformeren van de normaal en het snijpunt In de praktijk zullen we in het raytraceprogramma de transformatiematrix niet berekenen: we nemen namelijk direct de inverse transformatiematrix. We gebruiken de inverse transformatiematrix om de ray te transformeren. Hiermee hebben we een t berekend. Deze t kunnen we invullen in de rayvergelijking van de ongetransformeerde ray om het snijpunt te krijgen met het object als het getransformeerd zou zijn. Hiervoor hebben we dus geen transformatiematrix nodig, want het snijpunt is zo te berekenen. Een normaal transformeren blijkt echter een lastiger project te zijn. Een normaal transformeren met de transformatiematrix geeft namelijk niet altijd de goede normaal voor het getransformeerde object (zie figuur 7.7). Maar een raaklijn blijft wél een raaklijn aan het getransformeerde object. We zullen gebruiken dat de normaal loodrecht op de raaklijn staat om te bepalen hoe we de normaal dan wel moeten transformeren. n r = 0 (7.7) Figuur 7.7: Een normaal transformeren met dezelfde transformatiematrix als het object geeft niet altijd de goede normaal voor het getransformeerde object. M n is hierin de normaal die met de transformatiematrix is getransformeerd. N n is de echte normaal van het getransformeerde object. M t is de getransformeerde raaklijn. [19] Hierin is n de normaal van het originele object en r de raaklijn van het originele object. We zullen vanaf nu de vectoren beschouwen als matrices. We kunnen matrices alleen met elkaar vermenigvuldigen als de ene matrix even veel rijen heeft als de andere kolommen heeft. We zullen dus één van de vectoren uit 7.7 moeten transponeren. In matrixvorm wordt 7.7 dus: n T r = 0 Hierin zijn n en r dus matrices. De raaklijn kunnen we met de transformatiematrix T vermenigvuldigen om de getransformeerde raaklijn te krijgen. We zullen de transformatiematrix waarmee we de normaal vermenigvuldigen N noemen. We noemen ook de getransformeerde raaklijn t T en de getransformeerde normaal n N We moeten een waarde van N vinden zodat: n T Nr T = Nn T T r = 0 We weten dat voor een willekeurige matrix geldt dat als we deze met een eenheidsmatrix vermenigvuldigen, we dezelfde matrix houden. Dus: n T Ir = 0

61 HOOFDSTUK 7. TRANSFORMATIE 58 Hierin is I een eenheidsmatrix. Een eenheidsmatrix kunnen we ook schrijven als een vermenigvuldiging van een matrix met zijn geïnverseerde matrix. Als we I vervangen door T 1 T krijgen we: Hieruit volgt: n T T 1 T r = 0 (T 1 n T )(T r) = 0 (T 1 n T )r T = 0 n T N = T 1 n T n N = (T 1 ) T n = T T n Kortom, we zullen de normaal moeten vermenigvuldigen met de getransponeerde inverse matrix. Het transponeren van een matrix is heel eenvoudig, dus het probleem van het bepalen van de normaal voor het getransformeerde object is hiermee opgelost. Opmerking over volgorde van inverse transformaties In vergelijking 7.5 zagen we dat we als we een uiteindelijke transformatiematrix maken, we de transformatie die als laatst moet worden gedaan voorop moeten zetten. Bij inverse transformatiematrices doen we precies het omgekeerde van wat we doen bij gewone transformaties. Om de uiteindelijke inverse transformatiematrix te krijgen, zetten we dan ook de inverse transformatie die het eerst moet gebeuren gewoon voorop. We krijgen dus voor de uiteindelijke inverse transformatiematrix: 7.5 En de raytracer? T 1 = T1 1 T2 1...Tn 1 1 T n 1 We hebben in dit hoofdstuk geleerd hoe we objecten kunnen draaien, spiegelen in één van de assen, vergroten of verkleinen, en verplaatsen. Voor de objecten die we nu kennen (de objecten die we in hoofdstuk 2) is eigenlijk alleen het verschalen van belang, maar bij de objecten die we in hoofdstuk 8 erbij zien komen, zijn ook de andere transformaties erg handig. Ook voor het gebruik textuur zijn transformaties erg belangrijk. In figuur 7.8 zien we wat er kan gebeuren als we gaan spelen met transformaties op de twee bollen uit figuur Hier hebben we de rode bol verschaald met S(3; 2, 5; 1, 5), vervolgens met 50 graden over de z-as geroteerd en hebben we tot slot de translatie T (0, 50, 0) uitgevoerd.de blauwe bol hebben we eerst in de z-as gespiegeld en getransleerd met T (150, 0, 100). Verder verschilt de scène niets van de scène uit Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk gebruikt hebben zijn [1], [20], [19], [10] en [21]. Figuur 7.8: De scène uit figuur 6.10 na een aantal transformaties. Code De code voor het transformeren is te vinden in geometricobject.h.

62 Hoofdstuk 8 Geavanceerde Objecten en Intersecties We hebben al eerder eenvoudige objecten, zoals vlakken en bollen, behandeld, maar om realistische plaatjes te maken hebben we natuurlijk meer nodig dan dat. In dit hoofdstuk zullen we ook uitleggen hoe we een cilinder in onze raytracer kunnen krijgen en hoe we buiten de raytracer gemaakte modellen kunnen laten inlezen door de raytracer. 8.1 Cilinders Het definiëren van een cilinder Een cilinder is een object met een as en loodrecht op deze as overal eenzelfde cirkel als doorsnede. Een voorbeeld is te zien in figuur 8.1. Laten we als voorbeeld eens een simpele cilinder nemen met de as op de y-as. De doorsnedecirkel ligt dan op of evenwijdig aan de x, z-as. De straal van deze cirkel noemen we r. De formule voor de cirkel is een 2D versie van de 3D bol. Dus: (x c x ) 2 + (z c z ) 2 = r 2. Aangezien het middelpunt op de y-as ligt, is c x = 0 en c z = 0. Dus de definitie van de cirkel wordt: x 2 + z 2 = r 2 (8.1) Als we een oneindig lange cilinder { willen, kunnen we de cilinder nu als volgt definiëren: (x, y, z) : x 2 + z 2 = r 2 y [, ] } Meestal gaat het echter niet om een oneindig lange cilinder, maar { om een eindige. Dus van y 0 tot y 1. Dan geldt de definitie (x, y, z) : x 2 + z 2 = r 2 y [y 0, y 1 ] }. Voor de cirkel die een deel van de cilinder bepaalt geldt de volgende vergelijking: Om een cilinder in de scène te plaatsen, moeten we dus van deze cilinder de straal geven en twee waarden van y waar de cilinder tussen Figuur 8.1: Een cilinder [1] zit. Daarbij mogen we opmerken dat we met de bovenstaande gegevens de cilinder automatisch met als as de y-as nemen. Om de cilinder op andere plekken in de wereld te plaatsen, zullen we een cilinder met zijn oorsprong op de y-as moeten transformeren (zie hoofdstuk 7) Rayintersectie met een cilinder De x-coördinaat en de z-coördinaat van een punt op een ray zijn te beschrijven met de volgende formules, afgeleid uit ergelijking 2.15: p x = o x + d x t p z = o z + d z t 59

63 HOOFDSTUK 8. GEAVANCEERDE OBJECTEN EN INTERSECTIES 60 Dit invullen in vergelijking 8.1 geeft: (o x + d x t) 2 + (o z + d z t) 2 r 2 = 0 o 2 x + d 2 xt 2 + 2o x d x t + o 2 z + d 2 zt 2 + 2o z d z t r 2 = 0 (d 2 x + d 2 z)t 2 + 2(o x d x + o z d z )t + o 2 x + o 2 z r 2 = 0 Hierin zijn alle waarden behalve t bekend en dus kunnen we t berekenen. Vervolgens hoeven we alleen nog maar te kijken of p y [y 0, y 1 ]. En dan hebben we een raakpunt met de cilinder. De normaal van een cilinder in een raakpunt is ook eenvoudig te bepalen. Deze wijst namelijk vanaf de as van de cilinder recht naar buiten. De vector van het middelpunt van de cilinder naar de rand is deze: a = p x 0. We normaliseren deze en nemen de genormaliseerde vector als normaalvector. We delen de p z vector hiervoor door zijn eigen lengte, welke gelijk is aan de straal r. De normaalvector ziet er dus als volgt uit: p x /r n = 0 p z /r (8.2) 8.2 Polygon Meshes Het is in theorie mogelijk om met de cilinder en de objecten in hoofdstuk 2 alle mogelijke vormen en objecten te maken. Het zou echter een hoop tijd kosten om ingewikkelde objecten, zoals auto s of schooltassen, telkens zelf in het raytracingprogramma te bouwen met dit soort objecten. Ook zou het een overbodig proces zijn, want er zijn veel betere programma s gebouwd om dit soort modellen te maken en er zijn ook vele gratis modellen te downloaden op internet die stukken beter zijn dan de modellen die we zelf zouden maken in ons programma. Om deze redenen willen we het programma ook modellen laten inlezen. Dit betekent dat we een model, gemaakt buiten het programma, kunnen invoeren en raytracen. Hiervoor zullen we eerst iets moeten uitleggen over modelleren. Dit zullen we echter zo beknopt mogelijk houden, omdat we niet zelf willen gaan modelleren, maar alleen bestaande modellen willen gebruiken Wat zijn polygon meshes? Figuur 8.2: Polygon meshes in schema [22] De modellen die we gaan gebruiken zullen worden weergegeven als zogenaamde polygon meshes. Dit betekent dat het model is opgebouwd uit polygons. Elk model begint met punten. Zo bestaat het model voor een driehoek uit drie punten. Een punt in een model noemen we een vertex. Een verbinding tussen twee vertices noemen we een edge, oftewel een rand. Dit is een rechte lijn. Een verzameling van edges is een face, een aangezicht. Zo is een driehoek een face bestaande uit drie vertices en drie edges. Een polygon

64 HOOFDSTUK 8. GEAVANCEERDE OBJECTEN EN INTERSECTIES 61 is een verzameling van faces. Een aantal polygons samen vormt tenslotte een surface, een oppvervlak. Het gebruik van surfaces is soms handig maar vaak niet noodzakelijk. Voor een overzicht, zie figuur 8.2. Wij zullen alleen werken met objecten die uit driehoekjes bestaan, dus alleen met faces. Dit is omdat wij in onze raytracer niet het raytracen van andervormige faces hebben opgenomen OBJ Om de polygon meshes te kunnen importeren in ons programma, moeten deze natuurlijk wel beschreven worden. Wij zullen modellen gaan gebruiken die beschreven staan in een bestandstype dat bekend staat als.obj. In een.obj bestand staat simpelweg een lijst van elementen die in het object voorkomt, te beginnen met de vertices. Na de vertices volgen de normalen op de vertices, eventueel de UV coördinaten (voor texturen) en tenslotte de faces. In Code 8.1 staat een mogelijk.obj bestand. Eerst komen alle vertices (v) en vervolgens de normalen (vn). Vervolgens volgen de faces, bestaande uit drie vertices, samen met hun bijbehorende normaal. In dit geval bestaat de eerste face uit vertex 1 met normaal 2, vertex 7 met normaal 2 en vertex 5 met normaal 2. 1 # cube. obj 2 v v v v v v v v vn vn vn vn vn vn f 1/2 7/2 5/2 19 f 1/2 3/2 7/2 20 f 1/6 4/6 3/6 21 f 1/6 2/6 4/6 22 f 3/3 8/3 7/3 23 f 3/3 4/3 8/3 24 f 5/5 7/5 8/5 25 f 5/5 8/5 6/5 26 f 1/4 5/4 6/4 27 f 1/4 6/4 2/4 28 f 2/1 6/1 8/1 29 f 2/1 8/1 4/1 Code 8.1: Een mogelijk.obj-bestand Omdat we alleen.obj bestanden gebruiken die volledig uit driehoekjes bestaan, kunnen we deze al raytracen. We hoeven ze alleen nog maar in te lezen in de raytracer. Er ontstaat echter een probleem als er licht en schaduw in het spel komt Vloeiende versus strakke belichting Figuur 8.3 geeft al aan met wat voor probleem we te maken krijgen. Voor het linker plaatje is de standaardtechniek voor rayintersectie gebruikt en zijn de afzonderlijke driehoeken uit het OBJ-bestand geraytracet alsof ze niets met elkaar te maken hebben. In het rechter plaatje is een techniek gebruikt waarbij wél reke-

65 HOOFDSTUK 8. GEAVANCEERDE OBJECTEN EN INTERSECTIES 62 Figuur 8.3: Strakke belichting tegenover vloeiende belichting [23] ning is gehouden met het feit dat deze mesh één object is, opgebouwd uit meerdere objecten. Logischerwijs raytracen we liever met de techniek van het rechter plaatje, omdat de resultaten duidelijk beter zijn. Wat gaat er namelijk mis met de linker techniek? Het belichtingsproces van een object bij het raytracen werkt met de normaal van het object. Een driehoek heeft op elk punt dezelfde normaal en er ontstaat dus een knik tussen de normalen van twee driehoeken die aan elkaar grenzen maar niet dezelfde normaal hebben. Hierdoor zien we ook in de belichting van de theepot knikken ontstaan in de kleur die de pot krijgt. Om dit te voorkomen kunnen we werken met een gemiddelde normaal, zoals is gedaan bij de rechter theepot. Het werken met een gemiddelde normaal gaat als volgt. In het OBJ bestand staat voor elk hoekpunt van een driehoek de normaal gegeven. Vervolgens kunnen we hiermee de gemiddelde normaal berekenen. Hiervoor grijpen we even terug naar de barycentrische coördinaten. De barycentrische coördinaten van het punt in de driehoek zijn namelijk bekend door de manier waarop we het raakpunt van de driehoek met de ray hebben berekend: β en γ zijn berekend, en aangezien α = 1 β γ (zie vergelijking 2.8), weten we ze alle drie. Wat we vervolgens doen om de normaal te bereken is het volgende: we nemen een gewogen gemiddelde van de normalen van de drie vertices, die de hoekpunten van de driehoek zijn. Dit doen we door de normaal op het hoekpunt waar β = 0 geldt te vermenigvuldigen met de β-coördinaat van het punt, de normaal op het hoekpunt waar γ = 0 geldt te vermenigvuldigen met de γ-coördinaat van het punt en de normaal op het hoekpunt waar 1 β γ = 0 geldt te vermenigvuldigen met 1 β γ. Vervolgens tellen we deze vectoren bij elkaar op en normaliseren we ze. Stel: we hebben een driehoek met de hoekpunten a, b, en c. Dan hebben we op deze punten de normaalvectoren n a, n b en n c. Om dan de normaal van een punt p binnen de driehoek te krijgen doen we wat we net hebben beschreven: n p = (1 p β p γ ) n a + p β n b + p γ n c (1 p β p γ ) n a + p β n b + p γ n c Dit geeft ons de eenheidsnormaal voor p en met deze normaal kunnen we het belichtingsproces uitvoeren. Dit geeft kleuren die zorgen voor realistischer lichteffecten voor het model Bounding boxes Hoewel we ingewikkelde modellen, bestaande uit een grote hoeveelheid driehoekjes, wel kunnen raytracen, kost het soms erg veel tijd om te kijken of een ray al deze driehoekjes raakt. We kunnen dit proces sneller maken door een zogenaamde bounding box om het object heen te zetten. Dit is een balk die we om het object heenzetten. We hoeven dan eerst alleen te kijken of de rays de balk raken, en pas als dit het geval is hoeven we de driehoekjes die zich binnen de balk bevinden te raytracen. Het plaatsen van een bounding box is tamelijk eenvoudig. Uit een OBJ-bestand kunnen we de hoogste en laagste waarden van x, y en z vinden die het object heeft. Laten we als voorbeeld de code uit 8.1 gebruiken. Hier zien we dat de hoogste x van een vertex in het bestand een waarde van 1 heeft. De laagste x-waarde is 1, de laagste en hoogste y-waarden zijn respectievelijk 1 en 1 en de laagste en hoogste z-waarden zijn respectievelijk 1 en 1. Nu weten we dat voor dit object geldt: (x, y, z) [ 1, +1] [ 1, +1] [ 1, +1]. Hieruit kunnen we twee coördinaten van hoekpunten van de bounding box halen: de twee uiterste coördinaten,

66 HOOFDSTUK 8. GEAVANCEERDE OBJECTEN EN INTERSECTIES 63 namelijk ( 1, 1, 1) en (1, 1, 1). Elk punt dat een combinatie is van deze x, y en z coördinaten is een hoekpunt van de bounding box. Dit geeft ons acht hoekpunten. Een balk bestaat uit zes rechthoeken. Als we een balk gaan raytracen, raytracen we dus ook eigenlijk zes rechthoeken. Om een rechthoek te kunnen raytracen moeten we eerst de waarden hebben die een rechthoek voor ons definiëren. Dit zijn twee zijden en het punt waar de zijden samenkomen (zie 2.1.2, pagina 16). Hiervoor hebben we maar zes zijden en twee hoekpunten van de bounding box nodig. De hoekpunten die we gebruiken zijn gewoon en A = (x 0, y 0, z 0 ) X = (x 1, y 1, z 1 ). Hierbij zijn x 1, y 1, en z 1 de maximale x, y en z waarden en x 0, y 0 en z 0 de minimale x, y en z waarden. De zijden zijn de zes zijden die in deze hoekpunten samenkomen (in elk hoekpunt drie). Dit zijn dus de volgende vectoren: x 1 x 0 a = b = y 1 y c = 0 z 1 z 0 u = x 0 x v = y 0 y 1 w = z 0 z 1 De vlakken met hun vectoren en het punt dat ze definieert zijn dan als volgt: Vlak A - a, b, punt A en normaal n = a b Vlak B - a, c, punt A en normaal n = a c Vlak C - b, c, punt A en normaal n = b c Vlak D - u, v, punt X en normaal n = u v Vlak E - u, w, punt X en normaal n = u w Vlak F - v, w, punt X en normaal n = v w Deze vlakken vormen samen de bounding box, die we vervolgens kunnen raytracen. 8.3 En de raytracer? Op dit moment hebben we alle objecten behandeld die we in onze raytracer willen gebruiken. We hebben de wiskundige figuren: de bollen, vlakken, rechthoeken, cirkels, driehoeken en nu de cilinders. Daarnaast kunnen we modellen, beschreven in.obj-files, inlezen en raytracen. Ook hebben we uitgelegd hoe we om ingewikkelde objecten een bounding box kunnen zetten om ze sneller te kunnen renderen. In figuur 8.4 hebben we drie cilinders toegevoegd aan de scène in 6.10.

67 HOOFDSTUK 8. GEAVANCEERDE OBJECTEN EN INTERSECTIES Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk hebben gebruikt zijn: [1], [23] en [22]. Code De code voor een cylinder is terug te vinden in cylinder.h, de code voor een.obj-files in mesh.h en objfactory.h. Figuur 8.4: De scène uit figuur 6.10 met drie extra cilinders.

68 Hoofdstuk 9 Textuur Tot nu toe hebben we het alleen over objecten gehad, die we één kleur gaven. We maakten de bol blauw bijvoorbeeld, of de cirkel geel. Het is echter natuurlijk veel leuker en mooier om een voorwerp ook anders te kunnen kleuren. Bijvoorbeeld paars met witte stippen en een goud randje. Hiervoor gebruiken we texturen. Texturen zijn plaatjes die we plaatsen op de objecten. Zo kunnen we bijvoorbeeld een kaart van de wereld op een bol plaatsen, waardoor de bol een wereldbol lijkt. Hoe dit gaat zullen we in dit hoofdstuk bespreken. 9.1 Het proces Zodra een textuur is aangebracht is hij heel gemakkelijk te gebruiken. De code van de textuur geeft namelijk simpelweg een kleurcode terug, waarmee de kleur van het punt, dat wordt geraytracet, bepaald wordt. De moeilijkheid met texturen zit hem dus in het aanbrengen ervan. Dit gaat als volgt in zijn werk. Voor het aanbrengen van de textuur gebruiken we zogenaamde textuurcoördinaten. Dit zijn genormaliseerde coördinaten van het originele plaatje. Het zijn dus coördinaten die binnen het interval [0, 1] vallen. Dus: (u, v) [0, 1] [0, 1]. Voor de coördinaten van een punt op het originele plaatje met een resolutie van (h res, v res ) geldt het volgende: (x p, y p ) [0, h res 1] [0, v res 1]. Voor de relatie tussen (u, v) en (x p, y p ) geldt dan: x p = (h res 1)u y p = (v res 1)v (9.1) Zo kunnen we x p en y p makkelijk bepalen voor elke u en v. De u en v zullen we moeten bepalen voor het object waar we textuur op aanbrengen, en zo kunnen we dus punten op het object koppelen aan een punt op de textuur, waarmee we het punt op het object de kleur van het textuur kunnen geven. Dit proces zullen we duidelijker maken met het voorbeeld van een rechthoek Rechthoekvoorbeeld In dit voorbeeld gaan we een textuur aanbrengen op een rechthoek in het (x, z)-vlak met (x, z) [ 1, +2] [ 1, +1]. Elk raakpunt met deze rechthoek heeft de coördinaten (x, 0, z), want hij staat evenwijdig met de y-as. Nu geldt voor u en v (hierin is x 0 weer de kleinst mogelijke x-waarde, z 0 de kleinst mogelijke z-waarde, en x 1 en z 1 respectievelijk de grootst mogelijke x en z-waarden): u = z z 0 z 1 z 0 v = x x 0 x 1 x 0 65

69 HOOFDSTUK 9. TEXTUUR 66 Oftewel: u = z v = x Met vergelijking 9.1 kunnen we nu de punten van het textuur binden aan hun respectievelijke punten op de rechthoek, waardoor we een plaatje tevoorschijn zien komen op de rechthoek. Bij het raytracen zullen we altijd uitgaan van een rechthoek van 1 bij 1, gelegen in het (x, z)-vlak met het punt p 0 op de oorsprong van het O xyz vlak. Zo krijgen we namelijk dat u = z en v = x. Hierdoor zijn textuurberekeningen heel makkelijk. 9.2 Texturen op verschillende objecten In is al uitgelegd hoe we texturen kunnen aanbrengen op rechthoeken; in dit stuk zullen we uitleggen hoe dit werkt voor andere objecten. Zolang een object wiskundig gezien plat is, geeft textuur aan brengen geen problemen. Als een voorwerp niet plat is, wordt het lastiger om het textuur te geven, omdat de textuur dan wordt vervormd als hij op het object wordt geplakt. De definitie van een wiskundig gezien plat voorwerp is vrij ingewikkeld, maar het komt op het volgende neer: als we een vel papier in een vorm kunnen krijgen zonder te scheuren of te vouwen dan is het een plat object, zo niet dan is het niet plat. Zo is een open cilinder een plat object en een bol niet. We kunnen namelijk niet met een vel papier een bol vouwen zonder dat het gaat kreukelen. We zien dan ook dat we een textuur makkelijker kunnen aanbrengen op een cilinder dan op een bol. Daarom zullen we nu eerst laten zien hoe je een textuur aanbrengt op een cilinder Textuur op een cilinder Als we een cilinder nemen met als straal 1, als as de y-as en y [ 1, +1] wordt deze cilinder bepaald door de cilindrische coördinaten φ [0, 2π] en y [ 1, +1] (zie 8.1.1). Hierin geldt: φ = tan 1 (x/z) Als we een cilinder uitrollen, krijgen we een rechthoek. Hierin is de hoogte y en de lengte is de omtrek van de cilinder. Om op een willekeurig punt de coördinaten uit te drukken gebruiken we dit. De lengte van de cilinder is de booglengte horende bij een hoek van 360 graden, oftewel een hoek van 2π radialen, wordt berekend in de volgende formule: l = r θ (9.2) Hierin is r de straal van de cirkel en θ de middelpuntshoek, die bij onze cilinder φ is. Aangezien bij onze cilinder de straal 1 was, is de u makkelijk te berekenen met de volgende formule: u = φ/2π Want φ is de booglengte (en r = 1, dus r φ = φ) en 2π is de totale lengte. Dus geldt nu u [0, 1]. Variabele v is ook heel makkelijk te bereken, omdat y net zo n waarde is als x en z waren voor de rechthoek in Dus geldt voor v: v = y y o 2 v = y Hiermee kunnen we voor alle punten op de cilinder een punt op het plaatje van de textuur vinden en kunnen we textuur aanbrengen op een cilinder.

70 HOOFDSTUK 9. TEXTUUR 67 Voor een cilinder met een andere straal is dit natuurlijk ook makkelijk te doen. Dan verandert alleen de formule voor u. Deze wordt dan: u = r φ 2πr Hoewel het in de bovenstaande vergelijking lijkt of u onafhankelijk is van r, zullen we toch bij texturen standaard uitgaan van een straal van 1. Bij bepaalde waarden van r kan het namelijk bij andere objecten zo uitkomen dat bepaalde functies geen goede uitkomst meer geven. Zo krijgen we bij textuur op een bol te maken met cos 1 y. Dit kan alleen voor y [ 1, 1], dus moet gelden: 1 r 1. Daarom zullen we bij texturen aanbrengen altijd uitgaan van de standaardobjecten Textuur op een bol Al is het moeilijker om een textuur mooi op een bol te krijgen, is het natuurlijk niet onmogelijk. Om op een bol de positie van een punt aan te geven zullen we hier gaan werken met bolcoördinaten. Aangezien de φ hetzelfde is als de φ bij de cilindrische coördinaten, hebben we ook dezelfde formule voor u. Als we kijken naar een cirkel met als middelpunt (0, 0, 0) en als straal r = 1 kunnen we u uitdrukken als: u = φ/2π We houden dus alleen θ over om te bespreken. Voor de y-coördinaat van een punt op de cirkel met middelpunt (0, 0, 0) en r = 1 geldt: Dus: y = cos θ θ = cos 1 y De inverse cosinus geeft altijd een waarde tussen 0 en π. De hoogste waarde die θ dus kan hebben is π. Om die te passen in [0, 1] zullen we θ dus moeten delen door π. We kunnen dit echter niet zonder meer doen en de uitkomst als v gebruiken, zoals dat bij φ wel kon, want θ wordt gemeten vanaf de positieve y-as. Dus hoe groter θ, hoe kleiner de y-waarde wordt. We moeten dus iets omkeren. Er geldt altijd: θ/π [0, 1]. Dus om de juiste y-waarden te krijgen, kunnen we de volgende formule gebruiken: v = 1 θ π Het aftrekken van θ π van 1 zorgt ervoor dat de v-waarde kleiner wordt als θ groter wordt, wat dus precies is wat we nodig hadden. Wat is nu het probleem met het aanbrengen van een textuur op een bol? We zien het probleem ontstaan als we een textuur op de bol hebben geplakt. Laten we bijvoorbeeld het baksteenmotief uit figuur 9.1 (boven) op een bol aanbrengen. Als we dit raytracen krijgen we het plaatje uit figuur 9.1 (onder). Hoewel het bij dit motief niet zo n heel groot probleem is, zien we dat het motief wordt vervormd. Ook zien we dat het motief erger wordt vervormd naarmate we dichter bij de polen van de bol komen. Gelukkig kan ook dit probleem worden opgeloast. We kunnen namelijk een textuur vervormen voordat we het op de bol plakken. Hoe we dit kunnen doen is al in de zestiende eeuw uitgevonden door de Vlaamse cartograaf Gerardus Mercator, die bezig was met kaarten en wereldbollen. Hoe dit precies in zijn werk gaat zullen we hier niet bespreken, aangezien wij zelf geen texturen zullen maken, maar slechts willen dat door anderen gemaakte texturen in onze raytracer kunnen worden geïmplementeerd. Figuur 9.1: Boven: We raden dan ook af om met deze raytracer een willekeurig plaatje als textuur voor Een baksteenmotief. een bol te gebruiken en raden aan om hiervoor een plaatje te gebruiken dat speciaal Onder: Het baksteenmotief rond een bol. is gemaakt als boltextuur. [24]

71 HOOFDSTUK 9. TEXTUUR Textuur op een cirkel Als we op een cirkel een volledig rechthoekig plaatje zouden willen krijgen, zou dit een ontzettend vervormd plaatje worden. Daarom hebben wij ervoor gekozen om een uitsnede van het plaatje te gebruiken als wij op een cirkel texturen gaan aanbrengen, zoals in figuur 9.2. Een deel van het plaatje blijft dus ongebruikt. Door deze methode te gebruiken wordt niet alleen het plaatje niet vervormd als we de textuur aanbrengen, maar wordt ook het bepalen van de (u, v)-coördinaten op een punt op de cirkel makkelijker. Als voorbeeld zullen we een cirkel nemen in het (x, z)-vlak met als middelpunt (0, 0, 0) en als straal 1. De laagste waarde x-waarde die nog op de cirkel ligt is dan 1, de hoogste x-waarde is 1, de laagste z-waarde is 1 en de hoogste z-waarde is 1. De (u, v) coördinaten kunnen we dan beschrijven alsof we met een vierkant te maken hebben: u = z z 0 = z + 1 z 1 z 0 2 v = x x 0 = x + 1 x 1 x 0 2 Een aantal (u, v)-coördinaten worden dus nooit gebruikt, want die liggen helemaal niet op de cirkel. Een punt met u = 1 en v = 1 is bijvoorbeeld niet op de cirkel te vinden (zie figuur 9.2). Zo krijgen we een cirkelvormige uitsnede van het plaatje op de cirkel Textuur op polygon meshes Hoewel het leuk en soms handig is om texturen aan te brengen op de wiskundige objecten die we hiervoor behandeld hebben, is het waarschijnlijk belangrijker om textuur aan te kunnen brengen op geïmporteerde modellen. In de praktijk zullen we namelijk meestal de 3D-scène opbouwen uit modellen die we in andere programma s hebben gemaakt of van internet hebben gedownload. Om een.obj-bestand Figuur 9.2: Links: Hoekjes worden afgesneden als we een plaatje als textuur voor een cirkel gebruiken. Rechts: Het punt (u, v) = (1, 1) ligt niet op de cirkel. van een textuur te voorzien, moeten in dit bestand de u en v-coördinaten voor elke vertex gegeven zijn. Hiermee zijn u en v voor elk hoekpunt van elke driehoek bekend. Om vervolgens (u, v) voor een bepaald raakpunt binnen een driehoek te bepalen, gebruiken we dezelfde methode als we voor de normaal van een punt hebben gebruikt in We weten β en γ, dus we kunnen het gewogen gemiddelde van de (u, v)-waarden van alle drie de hoekpunten nemen om de (u, v)-coördinaten op het raakpunt te berekenen. 9.3 Objecten met textuur op andere plekken in de wereld Zoals een oplettende lezer al zal hebben opgemerkt, hebben we hier alleen texturen besproken voor specifieke objecten die op bijzondere plaatsen in de wereld liggen. Het is namelijk erg lastig om op een willekeurige andere plek in de wereld de (x, y, z)-coördinaten om te rekenen naar (u, v)-coördinaten. Als we dus een object met textuur op een andere plek in de wereld willen krijgen, zullen we transformaties moeten toepassen op de standaardobjecten.

72 HOOFDSTUK 9. TEXTUUR 69 We hebben in dit hoofdstuk texturen op rechthoeken, bollen, cirkels, cilinders en polygon meshes besproken. De standaardobjecten waar we vanuit moeten gaan bij het aanbrengen van texturen staan hieronder. De standaardobjecten zijn: 1 Een rechthoek met a = 0, 0 b = 0 en p 0 = (0, 0, 0). 0 1 Een cilinder met r = 1 en de y tussen 1 en 1. Een bol met r = 1 en c = (0, 0, 0). 0 Een cirkel met normaal 1, r = 1 2 en c = ( 1 2, 0, 1 2 ). 0 Bij polygon meshes gaat het aanbrengen van textuur automatisch goed, omdat de textuurcoördinaten in het.obj-bestand gegeven zijn en we alleen de gemiddelden daarvan hoeven te berekenen. Meestal is het zo dat er bij een model een textuur hoort die wordt bijgeleverd. Andere texturen voor het model maken is een moeilijke en tijdrovende taak, die buiten de raytracer moet worden vervuld. Hier zullen wij dus verder niet op in gaan. 9.4 En de raytracer? In dit hoofdstuk hebben we geleerd hoe we texturen aan kunnen brengen op objecten. Dit zorgt voor een aantal interessante nieuwe mogelijkheden. Plaatjes kunnen we nu alweer een stuk realistischer maken dan ze eerst waren, door ze te versieren met een plaatje of een motief. Ook hebben we geleerd dat we om texturen aan te brengen op objecten die op een willekeurige plek in de wereld staan, we uit moeten gaan van de standaardobjecten en we deze moeten transformeren, omdat anders de texturen niet werken. In figuur 9.3 hebben we een wereldboltextuur op de voorste bol uit de bekende scène geplakt. 9.5 Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk gebruikt hebben zijn: [1], [25] en [24]. Code Figuur 9.3: De scène uit 7.8 met een wereldboltextuur op de voorste bol. De code voor een textuur is terug te vinden in texture.h, colortexture.h en imagetexture.h. De objecten zijn verantwoordelijk voor het berekenen van de uv-coördinaten, dit is te vinden in de bestanden rectangle.h, circle.h, cylinder.h en mesh.h. Tenslotte vragen de materialen de texturen om de kleur. Dit is te vinden in de bestanden voor materialen: material.h, diffuse.h en phong.h.

73 Hoofdstuk 10 Spiegelreflectie Het licht dat ons oog bereikt, komt niet altijd van een voorwerp dat het direct weerkaatst vanuit een lichtbron. Het komt vaak voor dat objecten indirect licht ontvangen: ze krijgen licht dat is weerkaatst door andere objecten. Zo zie je in een spiegel een weerspiegeling van jezelf, doordat de spiegel het licht, dat je lichaam richting de spiegel weerkaatst, terugkaatst naar je oog, waardoor je dit licht ziet. In dit hoofdstuk zullen we beschrijven hoe we in een raytracer rekening kunnen houden met spiegelreflectie Het principe Spiegelreflectie is een speciale vorm van reflectie: het licht wordt gereflecteerd zoals een spiegel licht reflecteert. Dit betekent dat een evenwijdige lichtbundel, als die gereflecteerd wordt, een evenwijdige lichtbundel blijft. Ook geldt hier dat de hoek van inval gelijk is aan hoek van terugkaatsing. We gaan bij spiegelreflectie als volgt te werk: zodra een primaire ray (dus afgeschoten vanuit de camera) een object raakt, kijken we of er vanuit Figuur 10.1: Spiegelreflectie bij twee bollen en een vlak. de reflectierichting licht komt. Dit doen we door middel van het uitsturen van een nieuwe ray in de richting waarvoor geldt dat de hoek tussen de normaal en de nieuwe ray gelijk is aan de hoek tussen de normaal en de primaire ray. Van deze ray volgen we vervolgens het verloop. Er zijn voor deze ray vier mogelijkheden: 1. De nieuwe ray raakt geen enkel object meer. We krijgen dus de achtergrondkleur. 2. De nieuwe ray raakt een lichtbron. Het uitgestuurde licht van de lichtbron in de richting van het punt op het object moet worden berekend. 3. De nieuwe ray raakt een object waarin niets wordt gereflecteerd (een niet-reflectief object). Het directe licht dat op dit punt van het niet-reflectieve object valt en in de richting van het punt op het originele object wordt teruggekaatst moet worden berekend. 4. De nieuwe ray raakt een reflectief object. Het directe licht dat op dit punt van het reflectieve object valt en in de richting van het punt op het originele object wordt teruggekaatst moet worden berekend. Ook moeten we een nieuwe ray uitzenden vanaf het reflectieve object en hetzelfde proces hiervoor uitvoeren. 1 De radiance die terug wordt gegeven door deze nieuwe ray moet worden opgeteld bij het andere, dierecte, teruggekaatste licht. Na deze stappen kan het indirecte licht op het object worden opgeteld bij het licht dat het object direct van de lichtbronnen ontvangt om een totale hoeveelheid licht te verkrijgen. 1 Omdat dit proces in theorie een oneindig aantal keren zou kunnen doorgaan, kun je in onze raytracer aangeven hoeveel keer je dit proces maximaal wil laten herhalen. 70

74 HOOFDSTUK 10. SPIEGELREFLECTIE 71 Omdat stap 4 het hele proces nog een keer uitvoert, kan dit proces in een scène met veel objecten erg vaak uitgevoerd moeten worden. Dit zorgt voor veel intensief rekenwerk waardoor het relatief lang duurt om een scène met reflectie te renderen. Hier moet worden opgemerkt dat wij in dit werkstuk alleen omgevingslicht, directional licht en puntlicht behandelen. De bronnen van deze soorten lichten kunnen geen van allen door een ray worden geraakt, dus optie twee komt in onze raytracer niet voor. Dit zou wel van toepassing zijn als we bijvoorbeeld een lamp willen raytracen: een lamp is namelijk een object dat zelf licht uitzendt Het model De rendervergelijking Zoals hierboven al is beschreven kunnen we de totale hoeveelheid licht die vanaf een punt in een bepaalde richting wordt weerkaatst als volgt beschrijven: L o (p, ω o ) = L direct (p, ω o ) + L indirect (p, ω o ) (10.1) Hierin is L direct (p, ω o ) te bereken met de stof behandeld in hoofdstuk 6. Voor reflectie geldt voor L indirect (p, ω o ) de algemene formule: L indirect (p, ω o ) = f r (p, ω i, ω o )L i (r c (p, ω i ), ω i ) cos θ i dω i (10.2) 2π Dit is een ingewikkelde formule, maar wij kunnen deze sterk vereenvoudigen, omdat we alleen spiegelreflectie bekijken. Dit zullen we hieronder doen Indirect licht bij spiegelreflectie Om het indirecte licht bij spiegelreflectie te berekenen, moeten we ten eerste de nieuwe ray opstellen in de richting waarvandaan indirect licht zou invallen. Omdat het gaat om een spiegelreflectie weten we dat θ i = θ o = θ r : de hoek van de inkomende ray met de normaal is even groot als de hoek van de uitgaande ray met de normaal. De uitgaande ray zullen we hier de reflected ray noemen, om verwarring met directe verlichting te voorkomen. Ook weten dat φ i = φ o ± π, want de uitgaande straal gaat precies aan de andere kant van de normaal van het object weg. Uit 6.18 kunnen we dan afleiden dat de nieuwe ray met de volgende vergelijking te beschrijven is: r i = r r + 2( n r r ) n Hierin zijn r i en r r allebei van het vlak af gericht. r i is de incoming ray. Het is dus de ray in de richting waar het indirecte licht vandaan komt. r r is de reflected ray. Het is de ray die in de richting van de camera gaat (dit is dus r, als r de ray is die uit de camera is afgeschoten). Ook weten we bij spiegelreflectie dat de indirecte radiance, die van een reflectief object komt, maar uit één richting komt, namelijk in de richting van het punt op het originele object. Hiervoor hoeven we dus geen integraal te gebruiken. We kunnen de gereflecteerde radiance in de richting ω o beschrijven als: L indirect (p, ω o ) = f r,s (p, ω i, ω o )L i (p, ω i ) cos θ i (10.3) Hierin is L i het inkomende licht op het reflecterende object. De f r,s is de perfect specular BRDF, de BRDF van perfect gespiegeld licht. Omdat we hier alleen het simpele model voor spiegelreflectie zullen uitleggen, nemen we aan dat deze BRDF een constante is, afhankelijk van de reflectiecoëfficient k r en de reflectiekleur c r. 2 Hierin is k r [0, 1].De perfect specular BRDF wordt dan: f r,s = k r c r Dit invullen in 10.3 geeft: L indirect (p, ω o ) = k r c r L i (p, ω i ) cos θ i (10.4) 2 Een ander model dat kan worden gebruikt bevat zogenaamde Fresnel vergelijkingen, waarin f r,s afhankelijk is van de hoek θ i. Dit zullen wij echter niet in dit verslag behandelen, bij gebrek aan tijd.

75 HOOFDSTUK 10. SPIEGELREFLECTIE 72 De BRDF moet echter voor alle hoeken nul zijn, behalve voor de hoeken waarvoor geldt dat hoek van inval gelijk is aan hoek van uitval. Dit zullen we echter niet in de formules aangeven. In de code houden we rekening met dit aspect door alleen de berekeningen uit te voeren voor de waarden waarbij geldt θ i = θ r en φ i = φ o ±π. Als we ook hieraan hebben gedacht (hoewel we dit alleen in de code zullen doen en niet in de formules) hebben we nog één probleem. In de rendervergelijking krijgen we namelijk te maken met een factor cos θ i. De hoeveelheid weerkaatste radiance richting de camera is echter niet afhankelijk van de hoek van inval bij spiegelreflectie. 3 Deze moeten we dus nog uit de vergelijking zien te halen. Dit kunnen we eenvoudigweg doen door vergelijking 10.4 te delen door cos θ i. We krijgen dan: L indirect (p, ω o ) = k r c r L i (p, ω i ) cos θ i cos θ i L indirect (p, ω o ) = k r c r L i (p, ω i ) (10.5) Met deze formules kunnen we spiegelreflectie implementeren in onze raytracer En de raytacer? In dit hoofdstuk hebben we besproken hoe we een eenvoudige vorm van reflectie in onze raytracer kunnen bouwen: spiegelreflectie. Hiermee kunnen we een stuk interessantere plaatjes renderen dan we hiervoor konden, zoals bijvoorbeeld figuur In figuur 10.3 zien we wat er met de Figuur 10.2: Scène met reflectie, getiteld: De drie voetballers. scène uit 8.4 gebeurt als we het groene vlak en de twee bollen reflectief maken. Het groene vlak heeft hier een reflectiecoëfficient van 0,5, de rode bol een reflectiecoëfficient van 0,4 en de blauwe bol een reflectiecoëfficient van Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk gebruikt hebben zijn: [1] en [26]. Code De code voor dit hoofdstuk is terug te vinden in reflective.h. Figuur 10.3: De scène uit figuur 8.4 gerenderd met reflectie. 3 Bij bepaalde andere vormen van reflectie is deze factor wel van belang. Deze zullen we echter niet in dit profielwerkstuk behandelen.

76 Hoofdstuk 11 Breking Breking is een veel voorkomend verschijnsel in de natuur. Het is een verschijnsel dat optreedt als licht overgaat van het ene materiaal in het andere. Als we bijvoorbeeld door glas kijken treedt er breking op. Een duidelijk voorbeeld is te zien als we een potlood in een glas water zetten, zie figuur Het potlood lijkt hier gebroken. Bij elke instantie waarbij we door een transparant voorwerp kijken, komt het licht gebroken in onze ogen. In dit hoofdstuk zullen we een relatief eenvoudig model uitleggen om breking in raytracing te benaderen. We zullen alleen zogenaamd perfect specular breking behandelen Het principe Breking komt voor bij het raytracen van transparante objecten. Hier gaat het begrip brekingsindex een rol spelen. De brekingsindex (η) is een eigenschap die per stof verschilt. Het is een verhoudingsgetal van de lichtsnelheid (c) in vacuüm en de lichtsnelheid in de stof (v stof ) en wordt gegeven door de volgende vergelijking: η stof = c v stof Figuur 11.1: Een voorbeeld van breking. [27] Wanneer een lichtbundel een doorzichtig medium binnentreedt is er een constante verhouding tussen de sinus van de hoek van inval en de sinus van de hoek van breking, de brekingshoek. Dit heet de Wet van Snellius. Deze verhouding is gelijk aan de brekingsindex, dus geldt: η stof = sin θ i sin θ t = Hierin staat de t in θ t voor transmitted. Ook geldt voor een overgang van de ene stof in de andere dat de brekingsindex ten opzichte van de ene stof tot de andere voldoet aan de volgende vergelijking: c v stof η A B = η A η B (11.1) Wij werken echter niet met de échte natuurkunde, want wij zijn aan het raytracen: wij bekijken waar lichtstralen vandaan zouden kunnen komen. Als wij dus rays gaan schieten, zullen we niet formule 11.1 voor η moeten gebruiken, maar het omgekeerde hiervan. Want de rays gaan tegen het licht in. Dus de brekingsindex waar wij mee zullen werken als we rays uitsturen zullen we als volgt berekenen: η A B,rays = η B η A (11.2) 73

77 HOOFDSTUK 11. BREKING 74 Figuur 11.2: Een scène gerenderd met ambient, directional en puntlicht, één transparante bol (links: η = 1, rechts: η = 1, 1), één bol met Phongmateriaal en een vlak (Phongmateriaal). Met deze vergelijking kunnen we berekenen hoe licht gebroken wordt als het van stof A in stof B overgaat, want hieruit kunnen we het volgende afleiden: η A B = η B η A = sin θ i sin θ t (11.3) In Realistic Ray Tracing, Second Edition van P. Shirley en R. Morley (2003) staat een afleiding, waaruit we een vergelijking voor de richting van een lichtstraal die gebroken wordt kunnen berekenen. [16] Deze zullen we gebruiken om deze richting te berekenen en deze luidt als volgt: t = 1 η r i (cos θ t 1 η cos θ i) n (11.4) Hierin is t de gebroken ( transmitted ) lichtstraal, η de brekingsindex van de stof waaruit de lichstraal komt naar de stof waar de lichstraal ingaat, r i is de invallende lichtstraal en n is de normaal, tot slot is θ t de hoek van breking en θ i de hoek van inval. Voor cos θ i geldt natuurlijk: cos θ i = n r i Voor cos θ t geldt (ook deze komt uit het boek van Shirley en Morley): cos θ t = 1 1 η 2 (1 cos2 θ i ) (11.5) Door deze constructie is t automatisch een eenheidsvector. Er zijn bij breking twee verschillende opties, namelijk dat de lichtstraal naar de normaal toe gebroken wordt, of dat de lichtstraal van de normaal af gebroken wordt. Uit 11.3 kunnen we afleiden dat het licht naar de normaal toe breekt als η B > η A, dus als het licht van een stof met een kleinere brekingsindex naar een stof met een grotere brekingsindex gaat. Zo kunnen we ook afleiden dat als η B < η A het licht van de normaal af wordt gebroken. In figuur 11.2 zien we links een scène waarin transparantie optreedt. We zien de groene bol met Phongmateriaal dwars door de rode, transparante bol heen. Hier is de brekingsindex van de transparante bol 1, dus kijken we er doorheen, zonder dat het licht van richting wordt veranderd. Rechts zien we in figuur 11.2 dezelfde twee bollen, maar dan met een brekingsindex 1,1 voor de transparante bol. Hier zien we duidelijk dat het beeld van de groene bol in de rode vervormd wordt. Dit is een voorbeeld van geraytracete breking Totale reflectie Als we eens een situatie bekijken waarbij er breking van de normaal af optreedt, dus θ r > θ i. Dan komt er een moment waar op θ i < 90 en θ t > 90. Bij θ t > 90 is er echter helemaal geen sprake meer van breking.

78 HOOFDSTUK 11. BREKING 75 De t gaat dan namelijk de andere stof helemaal niet binnen maar weerkaatst van het oppervlak. We noemen de hoek van inval waarbij θ t = 90 de grenshoek, oftewel θ g. Wat gebeurt er nu met t als θ i > θ g? Het antwoord is dat t dan niet bestaat. De reden hiervoor is dat de energie die met de invallende ray wordt meegenomen verdeeld wordt over t, de gebroken lichtstraal, en r het gedeelte van het licht dat gereflecteerd wordt. Bij θ i > θ g geldt dat alle energie in de gereflecteerde lichtstraal r gaat zitten. t heeft dan dus geen energie meer en bestaat dus niet. We hadden al kunnen verwachten dat er zo n limiet was voor θ t aangezien de vergelijking van de cosinus van deze hoek aan de vergelijking in 11.5 moet voldoen. Dit is een wortelfunctie en deze heeft dus een (verticale) asymptoot, wat namelijk moet gelden is dat dat, wat onder het wortelteken staat, groter moet zijn dan nul, want anders is de uitkomst een imaginair getal. Een voorwaarde voor breking is dus de volgende ongelijkheid: 1 1 η 2 (1 cos2 θ i ) > 0 (11.6) Gaat deze ongelijkheid niet op, dan hebben we te maken met totale reflectie Het model Uit hoofdstuk 10 hadden we voor de rendervergelijking het volgende gehaald (vergelijking 10.1: L o (p, ω o ) = L direct (p, ω o ) + L indirect (p, ω o ) Hier kunnen we nu L indirect opdelen in een gebroken en een gereflecteerde component: L indirect (p, ω o ) = L r (p, ω o ) + L t (p, ω o ) Hierin is L r (p, ω o ) het gereflecteerde licht en L t (p, ω o ) het gebroken ( transmitted ) licht. Net zoals bij L r, kunnen we voor L t een moeilijke formule geven, die we vervolgens kunnen vereenvoudigen. Deze formule luidt als volgt: 1 L t (p, ω o ) = f t,s(p, ω i, ω o )L o (r c (p, ω i ), ω i ) cos θ i dω i (11.7) 2π Bij breking hebben we de radiance aan de andere kant van het oppervlak nodig, hiervoor gebruiken we niet de BRDF, maar de BTDF. Waar de BRDF de verhouding aangeeft van de hoeveelheid radiance, die wordt weerkaatst naar een bepaalde richting, met de hele irradiance, geeft de BTDF de verhouding aan van de hoeveelheid radiance, die gebroken wordt naar een bepaalde richting, met de hele irradiance (zie figuur 11.3). In vergelijking 11.7 is f t,s (p, ω i, ω o ) de functie van de BTDF. De BTDF geeft dus de verhouding aan tussen de hoeveelheid licht die gebroken wordt en de hoeveelheid invallende irradiance. Deze verhouding is afhankelijk van de brekingsindices van de twee stoffen, waar we mee te maken hebben, en met een brekingscoëfficient. Zo kunnen we voor de BTDF de volgende formule opstellen: f t,s = k t η 2 t η 2 i (11.8) Hierin is η t de brekingsindex van de stof waar het licht ingaat en η i de brekingsindex van de stof waar het licht vandaan komt. Hoewel 11.8 een simpele vergelijking is, is het makkelijk om de verkeerde η t en η i te nemen. Laten we nou bijvoorbeeld eens een ray nemen die van stof A naar stof B gaat. Stof A heeft als brekingsindex η out en B η in. In figuur 11.4 gaat een Figuur 11.3: [26] BRDF en BTDF 1 Opmerking: onder de integraal staat in tegenstelling tot de lichtvergelijkingen in vorige hoofdstukken 2π in plaats van 2π. Dit is omdat we het hier hebben over de integraal van de halve bol aan de andere kant van het oppervlak.

79 HOOFDSTUK 11. BREKING 76 primaire ray, r 0, over van stof A naar stof B en later weer van stof B naar stof A. Vanaf het punt a wordt de gebroken ray t 1 uitgestuurd en in het punt b, waar ray t 1 weer van stof B over gaat naar stof A, wordt de ray t 2 uitgestuurd. De dikke blauwe pijlen geven de richting van het licht aan. We zien dat deze tegen de richting van de rays in gaat. In situatie a zouden we de brekingsindex van het licht kunnen berekenen met We zouden dan de volgende brekingsindex krijgen: η B A = ηin η out. Voor de ray doen we het precies andersom, dus krijgen we: η A B = ηout η in. Dus in de functie voor de BTDF moeten we in situatie a voor η t juist η out nemen en voor η i juist η in. Op punt b is het natuurlijk precies andersom: hier moeten we voor η t de η in gebruiken en voor η i de η out. Figuur 11.4: Een ray gaat door een transparant object. [1] In 11.8 is k t tot slot de brekingscoëfficient. Zoals in al is besproken wordt de energie van het licht bij het raken van het oppervlak verdeeld over het gereflecteerde licht en het gebroken licht. Dus moeten de brekingscoëfficient en de reflectiecoëfficient (zie ) samen de coëfficient van het totale invallende licht zijn. Dus geldt k r + k t = 1. Om vervolgens de functie voor de radiance die via breking bij ons raakpunt met de ray komen te krijgen, vermenigvuldigen we de f t,s met het invallende licht. Dan krijgen we voor het gebroken licht: ηt 2 L t (p, ω o ) = k t ηi 2 L i (p, ω i ) (11.9) Hierin is L i (p, ω i ) = L o (r c (p, ω i ), ω i ) (zie 11.7). Dit is de hoeveelheid radiance die we tegenkomen langs de gebroken ray t. Waar we verder nog aan moeten denken is dat we moeten aannemen dat er alleen gebroken licht komt vanuit de richting t, we hebben hier immers te maken met perfect specular breking. We moeten dus aannemen dat de BTDF voor alle richtingen behalve richting t nul is. Dit zullen we doen door de berekeningen simpelweg alleen uit te voeren voor de richting, die aan de gestelde voorwaarden voldoet. Het laatste wat we over breking moeten zeggen, is dat breking een proces in gang zet dat een enorme hoeveelheid rays teweeg kan brengen. Daarom zullen we bij het raytracen werken met een maximum diepte voor rays. Dit betekent dat we alleen rays tot de n de orde zullen raytracen en daarna zullen stoppen. We kunnen hier niet zeggen dat we maar een vast aantal rays zullen raytracen, omdat het aantal rays bij breking en reflectie niet zonder meer vaststaat. Laten we bijvoorbeeld een primaire ray r 0 beschouwen die een transparant object raakt in het punt a. In a treedt geen totale reflectie op, dus zullen er twee extra rays moeten worden uitgestuurd. De gereflecteerde ray r 1, een ray van de eerste orde, raakt een reflecterend object en we zullen hiervoor nog een reflected ray moeten bouwen. Deze ray r 2 is een ray van de tweede orde en raakt, bijvoorbeeld, de achtergrond. Hier zijn we klaar. Dan hebben we van ray r 0 nog de gebroken ray die geconstrueerd werd. Dit is de ray t 1, deze ray is van de eerste orde. Deze raakt de binnenkant van het geraakte object en er treedt totale reflectie op. Er is dus alleen een reflected ray. We construeren r 3, een ray van de tweede orde. Deze raakt het object weer van binnen, maar hier treedt geen totale reflectie op. Er komt dus een gebroken ray en een teruggekaatste ray, deze twee zijn van de derde orde. Als we nu een maximale diepte n hebben ingesteld, zal dit proces stoppen na de rays van de n de orde, waarna er dus geen nieuwe rays meer afgevuurd worden. Dit is nodig om de rendertijden nog een beetje in te perken. De zogenaamde max depth is in onze raytracer in te stellen door de gebruiker. Een lage max depth zorgt voor kortere rendertijden dan een hoge max depth, maar een hoge max depth zorgt voor mooiere reflectie- en brekingseffecten En de raytracer? In dit hoofdstuk hebben we geleerd hoe we transparante transparante objecten in onze raytracer kunnen nabootsen. We hebben hier een simpele vorm van breking behandeld. Hiermee kunnen we dan ook weer een aantal bijzondere plaatjes maken. In figuur 11.5 zien we de scène uit 10.3 met in plaats van een reflectieve rode bol, een transparante rode bol. Links is de rode bol perfect transparant, hij heeft een brekingsindex van 1. Rechts is er sprake van breking. De brekingsindex van de rode bol is in dit geval 1,2. Een ander voorbeeld van transparantie in onze raytracer is te zien in Ballen op een stapel, in figuur 11.6.

80 HOOFDSTUK 11. BREKING 77 Figuur 11.5: Links: Rode bol met η = 1. Rechts: Rode bol met η = 1.2. Figuur 11.6: Tien transparante ballen op een stapel Bronnen en code Bronnen De bronnen die we voor dit hoofdstuk hebben gebruikt zijn: [1], [27], [16], [26], [28] en [29]. Code De code voor dit hoofdstuk is terug te vinden in transparent.h.

81 Hoofdstuk 12 Conclusie In dit concluderende hoofdstuk zullen we nog één keer terugkijken op wat we met ons profielwerkstuk hebben bereikt en vooral ook wat we niet hebben bereikt. We zullen dus een korte samenvatting geven van wat we hebben besproken en uitleggen wat er nog allemaal kan worden gedaan om een nóg betere raytracer te bouwen Samenvatting Figuur 12.1: Een scène, geraytracet met onze eigen raytracer. In dit profielwerkstuk hebben we behandeld hoe we een basis raytracer kunnen maken en de theorie achter de raytracer uitgelegd. Zo kunnen wij nu bollen, vlakken, rechthoeken, driehoeken, cilinders en.obj-modellen raytracen (hoofdstukken 2, 3 en 8). We hebben uitgelegd hoe we kunnen bepalen vanaf welk punt we naar de scène kijken (hoofdstuk 4) en hoe we kartelvorming kunnen tegengaan (hoofdstuk 5). We zijn verder gegaan met een model voor lichten in een raytracer (hoofdstuk 6). We hebben ambient lichtbronnen, directional lichtbronnen en puntlichtbronnen behandeld. Daarnaast hebben we het model van Phong behandeld en hebben we uitgelegd hoe we schaduwen in een raytracer kunnen nabootsen. Ook hebben we uitgelegd hoe we met het belichtingsmodel eenvoudige vormen van reflectie (hoofdstuk 10) en breking (hoofdstuk 11) kunnen renderen. Verder kunnen we nu driedimensionale objecten transleren, roteren om de x-as, de y-as en de z-as, spiegelen in de x, de y en de z-as en verschalen (hoofdstuk 7) en kunnen we tot slot texturen aanbrengen op objecten om ze mooier te maken (hoofdstuk 9). In figuur 12.1 zien we een scène, geraytracet met onze eigen raytracer. In deze afbeelding zit een groot deel van de stof die we in dit profielwerkstuk behandeld hebben. We zien verschillende objecten: een bol, drie vlakken en vier rechthoeken. Ook zien we alle drie de verschillende lichtbronnen: een ambient lichtbron, een directional lichtbron en een puntlichtbron. We hebben op de bol een textuur aangebracht. Om deze bol op deze plaats en van deze grootte te krijgen hebben we dus moeten transformeren. We zien reflectie in de vloer en in de spiegels. We zien diffuus materiaal op de muren en Phongmateriaal op de randen van de spiegels. Verder zien we dat de wereldbol transparant is en dat het licht wordt gebroken. We zien namelijk de vervorming van de randen van de spiegels door de bol. 78

82 HOOFDSTUK 12. CONCLUSIE 79 Verklaring van het plaatje op de voorpagina In deze paragraaf zullen we uitleggen hoe we aan het plaatje zijn gekomen dat op de voorpagina is afgebeeld. In feite zien we dezelfde afbeelding als in Het enige verschil is dat we de transparante wereldbol hebben vervangen door een marmeren standbeeld met diffuus materiaal. Het model voor de man die nu tussen de spiegels staat is een.obj-model, dat men kan vinden in de bronvermelding. [30] Het model bestaat uit vertices, normalen en driehoekjes. Elke keer dat een ray de bounding box om het model heen raakte, moesten er dus driehoekjes geraytracet worden. Het renderen van deze afbeelding duurde dan ook 21 uur en 23 minuten Wat had nog meer gekund? Met alles wat we hebben gedaan kunnen we een hele hoop mooie plaatjes maken, maar écht realistisch wordt het nog net niet. Het is mogelijk om een nog betere raytracer te maken die bijvoorbeeld plaatjes kan maken zoals in figuur We zouden bijvoorbeeld in plaats van alleen spiegelreflectie ook andere vormen van reflectie kunnen behandelen, zoals glossy reflection, metallic reflection en blurry reflection. Ook hadden we nog dieper in kunnen gaan op breking. Wij hebben namelijk alleen breking in één richting behandeld, terwijl licht dat door een oppervlak gebroken wordt, lang niet altijd onder dezelfde hoek gebroken wordt. Zo hebben wij in ons lichtmodel nergens rekening gehouden met het feit dat de verschillende golflengten van verschillende kleuren licht ook anders worden gebroken. Ook hadden we in onze raytracer nog een andere lichtbron kunnen behandelen: de oppervlaktelichtbron. Dit is een object dat licht uitzendt. Bijvoorbeeld een Figuur 12.2: Een geraytracete scène. [31] lichtgevende bol, of een lichtgevend vlak. Hiermee hadden we bijvoorbeeld echte lampen in onze scène kunnen neerzetten en hiermee realistischer schaduwen kunnen nabootsen. Daarnaast hadden we nog de techniek van het path tracen kunnen uitleggen. Bij path tracing worden er vanaf elk snijpunt een aantal rays in willekeurige richtingen uitgestuurd. Deze rays worden vervolgens net zo lang gevolgd (getracet) totdat ze een lichtbron tegenkomen. Op deze manier wordt de hoeveelheid licht die een punt bereikt dus nog beter benaderd dan wij tot nu toe hebben gedaan. Path tracing is een erg rekenintensief proces maar kan tot verbluffende resultaten leiden. In figuur 12.3 (links) zien we het resultaat van een simpele scène waar path tracing op is toegepast. We zien een zweem van de weerkaatsing van de oranje muur op de grond achter de rechter transparante bol. Dit soort effecten zijn ontstaan door path tracing. Een andere techniek die we niet hebben besproken, maar die we wel graag hadden willen toevoegen is de techniek die depth of field heet, oftewel scherptediepte in het Nederlands. Met deze techniek zouden we kunnen scherpstellen op een bepaald gebied van de scène, net zoals we kunnen scherpstellen met een echte fotocamera. In figuur 12.2 zien we deze techniek terug: de kan en glazen die achter in de scène staan zijn vaag. Er is dus scherpgesteld op een gebied daarvóór, waarin bijvoorbeeld de dobbelstenen en de wijnglazen staan. Deze staan namelijk wel scherp op de afbeelding. Er zijn nog veel meer bekende raytracingtechnieken die we hadden kunnen uitleggen als we meer tijd hadden gehad, maar raytracing is dan ook een techniek die nog lang niet uitontwikkeld is. Er zijn namelijk nog vele details in de natuur die we nog niet hebben kunnen reproduceren met raytracers en zelfs de beste raytracer die op dit moment op de markt is, is nog niet af. Toch wordt raytracing steeds vaker gebruikt, want hoewel het een rekenintensieve rendermethode is, is het op dit moment wel de meest realistische rendermethode. 1 Voor het renderen werd een AMD Athlon 64 X2 Dual Core Processor (2CPUs), 2.3GHz processor gebruikt.

83 HOOFDSTUK 12. CONCLUSIE 80 Figuur 12.3: Links: Een scène gerenderd door een raytracer die path tracing ondersteunt. [32] Rechts: Een deels geraytracete scène uit de bekende film: The Lord of the Rings: the Fellowship of the Ring. [33] Raytracing zien we inmiddels terug in de meeste moderne animatiefilms en ook voor de special effects in speelfilms wordt raytracing volop gebruikt. Zo zijn de gezichten van sommige wezens uit films als Lord of the Rings deels maskers, maar ook deels geraytracet (zie figuur 12.3 (rechts)). Wij hebben in ons profielwerkstuk geprobeerd om de basis van dit ingewikkelde proces uit te leggen, en hopen dat u zich als lezer nu enigszins bekend voelt met de elementaire onderdelen van het raytracen.

84 Hoofdstuk 13 Onze raytracer Met de theorie die in de werkstuk staat beschreven hebben we onze eigen raytracer gebouwd. In dit hoofdstuk staat beschreven hoe hij werkt en hoe je hem kunt gebruiken. In figuur 13.2 is een screenshot van de raytracer te zien Werking Wij hebben onze raytracer geschreven in de programmeertaal C++ samen met het QT framework. Daarnaast hebben we de Eigen library gebruikt voor het rekenen met matrices. 1 De raytracer leest eerst een script in om de scène te bouwen. Het script wordt in EC- MAscript, een soort javascript, geschreven. De raytracer rendert vervolgens de scène en kan deze exporteren. De complete scène kan samen met de instellingen in een.ray-bestand worden opgeslagen. We hebben de raytracer geschreven op Windows, maar aangezien C++ en QT op meerdere besturingssystemen werken zou het programma ook op Linux en Mac moeten werken. De raytracer is, evenals de broncode, te downloaden op Onze raytracer is uitgeveven onder de GNU General Public License versie 3.0. [34] Deze houdt in het kort in, dat iedereen ons programma gratis mag verspreiden en aanpassen, onder de voorwaarde dat de broncode wordt meegeleverd. Voor het programmeren met QT hebben we gebruik gemaakt van de bronnen [35] en [36] Gebruik Figuur 13.1: De instellingen voor de raytracer Instellingen In het rechtervenster kun je de instellingen van de raytracer aanpassen (zie figuur 13.1). De volgende instellingen zijn aan te passen: Resolution. De resolutie van de afbeelding 1 Zie en 81

85 HOOFDSTUK 13. ONZE RAYTRACER 82 Sample method, Number of samples en Sample sets. De methode van sampling (regular, random, jittered). Met number of samples kun je het aantal samples per pixel de instellen. Sample sets is het aantal verzamelingen samples dat gegenereerd wordt (de standaardwaarde 83 is meestal goed). Pixel size. De grootte van een pixel. Door deze groter te maken zoom je uit, door deze kleiner te maken zoom je in. Max depth. Hiermee wordt ingesteld hoevaak er maximaal nieuwe rays kunnen worden uitgezonden (bij transparantie en spiegelreflectie). Eyepoint, Look at point en Distance to screen. Hiermee kun je het eyepoint (waar de camera staat) en het look at point (waar de camera naar toe kijkt) instellen. Met distance to screen stel je de afstand van het scherm tot het eyepoint in. Roll angle. Hiermee stel je in onder welke hoek de camera moet rollen (zie het hoofdstuk over camera en perspectief op bladzijde 26). Ambient RGB en Ls: de kleur en sterkte van de ambient lichtbron. Out-of-gamut. Hiermee wordt ingesteld wat de raytracer doet bij overbelichting: de raytracer brengt de waarde van de kleuren weer binnen het bereik (max to one) of de raytracer maakt alle overbelichte punten wit of rood (clamp to white of clamp to red). Met de renderknop kun je tenslotte de raytracer laten renderen. Met de update knop laat de raytracer alvast zien wat er tot dan toe gerenderd is. Met de knop stop kun je de raytracer laten stoppen en met clear kun je het scherm weer leegmaken Licht In het scriptvenster moet de scène worden beschreven in een scriptbestand. Je begint het beschrijven van een object met.create(); en eindigt met.finish(); Elke regel moet met een ; worden afgesloten. Regels worden commentaar door er // voor te zetten. Je kunt een heel stuk tekst commentaar maken door het tussen /* dit is commentaar */ te zetten. Directional licht Een directional licht wordt gedefinieerd door een kleur, de lichtsterkte en de richting. De richting is hierbij van het object naar het licht toe (zie pagina 41). Je maakt een directional light als volgt aan: 1 directional. create ( ) ; //Maak een d i r e c t i o n a l l i c h t b r o n 2 directional. setcolor ( 1, 1, 1 ) ; // Kleur 3 directional. setls ( 1. 6 ) ; // L i c h t s t e r k e 4 directional. setdirection ( 1, 2, 2 ) ; // Richting 5 directional. finish ( ) ; // Finish, d i t z o r g t het d i r e c t i o n a l l i c h t wordt afgemaakt en toegevoegd aan de scene Puntlicht Een puntlicht wordt gedefinieerd door een kleur, de lichtsterkte en een punt. 1 pointlight. create ( ) ; 2 pointlight. setcolor ( 1, 1, 1 ) ; 3 pointlight. setls ( 2 ) ; 4 pointlight. setlocation ( 0, 1 5 0, 0 ) ; // L o c a t i e van de l i c h t b r o n 5 pointlight. finish ( ) ; Als je wilt, kun je instellen dat de kwadratenwet moet worden gebruikt (distance attanuation). lichtsterke moet dan wel veel hoger zijn, omdat deze zeer snel afneemt. De

86 HOOFDSTUK 13. ONZE RAYTRACER 83 1 pointlight. setls (330000) ; 2 pointlight. setdistatt ( true ) ; Objecten Voor elk object moeten we het materiaal en de kleur instellen (texturen komen aan het eind van dit hoofdstuk). Daarnaast kunnen we elk object transformeren. De kleur en het materiaal stel je als volgt in: 1. setcolor ( 1, 0, 0 ) ; // Kleur van het o b j e c t i n r, g, b 2. materialmatte ( ka, kd ) ; // R e f l e c t a n c e voor het ambient d e e l en het d i f f u s e d e e l 3. materialphong ( ka, kd, ks, phongexp ) ; // S t e r k t e van de s p e c u l a r r e f l e c t i e, g r o o t t e van de s p e c u l a r r e f l e c t i e 4. materialreflective ( ka, kd, ks, phongexp, kr, r, g, b ) ; // S t e r k t e van de s p i e g e l w e e r k a a t s t i n g en de w e e r k a a t s t i n g s k l e u r r, g, b 5. materialtransparent ( ka, kd, ks, phongexp, kr, r, g, b, kt, eta ) ; // S t e r k t e van de t r a n s p a r a n t i e en de b r e k i n g s i n d e x De kleur moet eerst worden ingesteld en daarna pas het kan het materiaal worden ingesteld. Je kiest natuurlijk maar één van de vier materialen. Hieronder staan voorbeelden van de verschillende materialen, aangebracht op een bol: 1 sphere. materialmatte ( 0. 2, 0. 5 ) ; 2 sphere. materialphong ( 0. 2, 0. 5, 0. 2, 10) ; 3 sphere. materialreflective ( 1, 0. 8, 0. 8, 2 0, 0. 6, 1, 1, 1 ) ; 4 sphere. materialtransparent ( 0. 0, 0. 2, 0. 2, 1 0 0, 0. 6, 1, 1, 1, 0. 8, 1. 2 ) ; De translaties werken als volgt: 1. scale ( x, y, z ) ; //x, y, z v e r s c h a l e n 2. rotate ( x, y, z ) ; // Roteren om de x, y, z as ( i n graden ) 3. translate ( x, y, z ) ; // Transleren met x, y, z. Hieronder staan voorbeelden van de verschillende transformaties. 1 sphere. scale ( 1, 2, 1 ) ; // Bol wordt in de y r i c h t i n g 2 keer zo groot 2 sphere. rotate ( 9 0, 0, 4 5 ) ; // Rotatie van 90 graden om de x as en van 45 graden om de z as 3 sphere. translate ( 0, 1 0 0, 0 ) ; // T r a n s l a t i e ( 0, 1 0 0, 0 ) Om te spiegelen kun je verschalen met 1. Daarnaast moet het object natuurlijk worden begonnen met.create() en.finish(). Bol Een bol wordt gedefinieerd door zijn middelpunt en de straal. En bol voer je als volgt in: 1 sphere. create ( ) ; 2 sphere. setcolor ( 1, 0, 0 ) ; 3 sphere. setradius ( 5 0 ) ; // S t r a a l 4 sphere. setcenter ( 0, 5 0, 5 0 ) ; // Middelpunt ( x, y, z ) 5 sphere. materialphong ( 0. 2, 0. 5, 0. 2, 10) ; 6 sphere. finish ( ) ;

87 HOOFDSTUK 13. ONZE RAYTRACER 84 Vlak Een vlak wordt gedefinieerd door een punt en en de normaal. Een vlak voer je als volgt in: 1 plane. setnormal ( 0, 1, 0 ) ; // Normaal 2 plane. setpoint ( 0, 0, 0 ) ; //Een punt waar het vlak doorheen gaat Hierbij zijn create(), finish(), setcolor() en het materiaal weggelaten, omdat dit bij elk object op dezelfde manier gaat. Cirkel Een cirkel wordt gedefinieerd door het middelpunt, de straal en de normaal. 1 circle. setnormal ( 1, 1, 1 ) ; // Normaal 2 circle. setpoint ( 2 0 0, 4 0, 3 0 ) ; // Middelpunt 3 circle. setradius ( 3 0 ) ; // S t r a a l Rechthoek Een rechthoek wordt gedefinieerd door een punt en twee vectoren die de zijden aangeven. Je dient er zelf voor te zorgen dat deze vectoren loodrecht op elkaar staan (de normaal wordt door de raytracer berekend). 1 rectangle. setpoint ( 1 0 0, 1 0 0, 0 ) ; //Punt 2 rectangle. seta ( 1 0 0, 0, 0 ) ; // Vector 1 3 rectangle. setb ( 0, 1 0 0, 0 ) ; // Vector 2 Cylinder Een cylinder wordt gedefinieerd door de straal en de hoogte. Je geeft de hoogte aan als een minimale en een maximale coördinaat. Om de cylinder op een andere plek te krijgen, moet hij worden getransformeerd. 1 cylinder. setradius ( 2 5 ) ; //De s t r a a l van de c y l i n d e r 2 cylinder. sety ( 0, ) ; //De minimale en de maximale y waarde > de hoogte 3 cylinder. rotate ( 0, 0, 9 0 ) ; // Transformatie 4 cylinder. translate ( 2 0 0, 2 2 5, 0 ) ; // Transformatie Triangle Een driehoek wordt gedefinieerd door drie hoekpunten, vertices. 1 triangle. setv0 ( 0, 0, 0 ) ; // Hoekpunt 0 2 triangle. setv1 ( 0, 2 0 0, 0 ) ; // Hoekpunt 1 3 triangle. setv2 ( 3 0 0, 0, 0 ) ; // Hoekpunt 2.OBJ bestanden Onze raytracer bevat een simpele.obj bestandenlader. Deze werkt alleen voor.obj-bestanden die uit driehoeken bestaan. Daarnaast moet ook de normaal in de.obj-bestanden staan. De code controleert verder niet of het een goed bestand is. Fouten in het.obj-bestand kunnen dan ook tot rare resulaten of crashes leiden. Het laden van een.obj-bestand gaat als volgt: 1 obj. setfile ( "y:\\ obj \\ cool.obj" ) ; Het.OBJ-bestand moet in dezelfde map als het.ray-bestand staan, anders moet de volledige locatie worden ingevoerd. Hierbij moet je een \ als een dubbele \\ schrijven.

88 HOOFDSTUK 13. ONZE RAYTRACER 85 Textures Onze raytracer kan textures inlezen en over een bol, een cylinder, een rechthoek, een cirkel en over een.obj-bestand heen plaatsen (mits de (u, v) coördinaten in het.obj-bestand staan). Je kunt pas een texture inlezen, nadat het materiaal is aangemaakt. Er moet geen middelpunt, straal, lengte etc. worden ingegeven, aangezien textures alleen over standaardobjecten heen kunnen worden geplaatst. Daarom moet er met transformaties worden gewerkt om het object te veranderen. De raytracer maakt als er niks wordt ingesteld automatisch een standaardobject aan. Dit gaat als volgt: 1 sphere. create ( ) ; 2 sphere. scale ( 1 0 0, 1 0 0, ) ; // In p l a a t s van s t r a a l sphere. materialmatte ( 1, 1 ) ; // Eerst m a t e r i a a l 4 sphere. settexture ( "y:\\ obj \\ bol.jpg" ) ; //Dan textuur 5 sphere. finish ( ) ; De bestandsnaam moet hierbij op dezelfde manier als bij obj worden aangegeven (met \\) Scripten Het scènebestand is een ECMAScript bestand. Daarom kun je hiermee ook echt programmeren 2. Een voorbeeld hiervan is het gebruik van een lus. Hieronder is een voorbeeld, waarin 34 bollen in een ellipsvorm worden neergezet. 1 var i=0; 2 var j = / 3 4 ; 3 var x = 0 ; 4 var y = 0 ; 5 for ( i=0;i <6.28; i+=j ) 6 { 7 x = Math. cos ( i ) ; 8 y = Math. sin ( i ) ; 9 x = ; 10 y = ; 11 sphere. create ( ) ; 12 sphere. setcolor ( 1, 1, 1 ) ; 13 sphere. setradius ( ) ; 14 sphere. setcenter ( x, , y ) ; 15 sphere. materialreflective ( 0. 2, 0. 8, 0. 3, 1 5, 0. 6, 1, 1, 1 ) ; 16 sphere. finish ( ) ; 17 } Voorbeeld Tenslotte zullen we een voorbeeld geven van een complete scène in de raytracer. De afbeelding die met deze code gerenderd is, is te zien in figuur 11.5 (rechts) (pagina 77). 1 plane. create ( ) ; 2 plane. setcolor ( 0, 1, 0 ) ; 3 plane. setnormal ( 0, 1, 0 ) ; 4 plane. setpoint ( 0, 0, 0 ) ; 5 plane. materialreflective ( 0. 2, 0. 4, 0. 4, 1 0, 0. 5, 1, 1, 1 ) ; 6 plane. finish ( ) ; 7 8 sphere. create ( ) ; 9 sphere. setcolor ( 1, 0, 0 ) ; 2 Voor meer informatie over programmeren met ECMAScript kun je zoeken naar ECMAScript en javascript. Bijvoorbeeld op: en loop for.asp

89 HOOFDSTUK 13. ONZE RAYTRACER sphere. setradius ( 5 0 ) ; 11 sphere. setcenter ( 0, 5 0, 5 0 ) ; 12 sphere. materialtransparent ( 0. 2, 0. 4, 0. 4, 1 0, 0, 1, 1, 1, 1, 1. 2 ) ; 13 sphere. finish ( ) ; sphere. create ( ) ; 16 sphere. setcolor ( 0, 0, 1 ) ; 17 sphere. setradius (100) ; 18 sphere. setcenter (0,100, 100) ; 19 sphere. materialreflective ( 0. 2, 0. 4, 0. 4, 1 0, 0. 7, 1, 1, 1 ) ; 20 sphere. finish ( ) ; cylinder. create ( ) ; 23 cylinder. setcolor ( , , ) ; 24 cylinder. materialphong ( 0. 2, 0. 4, 0. 4, 1 0 ) ; 25 cylinder. setradius ( 2 5 ) ; 26 cylinder. translate ( 150,0, 50) ; 27 cylinder. sety ( 0, ) ; 28 cylinder. finish ( ) ; cylinder. create ( ) ; 31 cylinder. setcolor ( , , ) ; 32 cylinder. materialphong ( 0. 2, 0. 4, 0. 4, 1 0 ) ; 33 cylinder. setradius ( 2 5 ) ; 34 cylinder. translate (150,0, 50) ; 35 cylinder. sety ( 0, ) ; 36 cylinder. finish ( ) ; cylinder. create ( ) ; 39 cylinder. setcolor ( , , ) ; 40 cylinder. materialphong ( 0. 2, 0. 4, 0. 4, 1 0 ) ; 41 cylinder. setradius ( 2 5 ) ; 42 cylinder. translate (0,0, 50) ; 43 cylinder. sety ( 0, ) ; 44 cylinder. rotate ( 0, 0, 9 0 ) ; 45 cylinder. translate ( 2 0 0, 2 2 5, 0 ) ; 46 cylinder. finish ( ) ; directional. create ( ) ; 50 directional. setcolor ( 1, 1, 1 ) ; 51 directional. setdirection ( 1, 2, 2 ) ; 52 directional. setls ( 2. 5 ) ; 53 directional. finish ( ) ; pointlight. create ( ) ; 56 pointlight. setcolor ( 1, 1, 1 ) ; 57 pointlight. setlocation ( 50, 300, 50) ; 58 pointlight. setls ( 2. 9 ) ; 59 pointlight. finish ( ) ; In figuur 13.2 is te zien hoe deze scène door de raytracer wordt gerenderd.

90 HOOFDSTUK 13. ONZE RAYTRACER 87 Figuur 13.2: Screenshot van de raytracer

91 Bibliografie [1] K. Suffern, Ray Tracing from the Ground Up. A K Peters, Ltd., [2] E. Deloget, GCDC 07, oktober Op: [3] Crytek s Cevat Yerli Speaks on Rasterization and Ray Tracing, april Op: Ray-Tracing/ [4] R. Boers, Verzamelingenleer, 2008, extra hoofdstuk geschreven voor een vijfdejaars Wiskunde D cluster. [5] C. Wynn, An Introduction to BRDF Based Lighting, Op: Lighting.html [6] M. Zwicker, Computer Graphics II, Rendering, Op: s06/ucsd/lecture08.pdf [7] Kruisproduct. Op: product [8] Determinant. Op: [9] Regel van Cramer. Op: van Cramer [10] Inverse matrix. Op: matrix [11] Steradiaal. Op: [12] Implicit fucntion. Op: function [13] Dependent and independent variables. Op: variable [14] Parametervergelijking. Op: [15] Barycentrische coordinaten. Op: coordinaten [16] P. Shirley en R. K. Morley, Realistic Ray Tracing, Second Edition. A K Peters, Ltd., [17] Phong shading. Op: shading [18] Rendering equation. Op: equation [19] P. Shirley, M. Ashikhmin, M. Gleicher, S. R. Marschner, E. Reinhard, K. Sung, W. B. Thompson, en P. Willemsen, Fundamentals of Computer Graphics, 2nd ed. A K Peters, Ltd., [20] Verschalen (meetkunde). Op: (meetkunde) [21] Transformation (geometry). Op: (geometry) [22] Polygon meshes. Op: meshes 88

92 BIBLIOGRAFIE 89 [23] Flat, Gouraud and Phong Shading. Op: cs442/lectures/gouraud/gouraud.pdf [24] H. Fisher, Images in 3D Graphics. Op: Hugh.Fisher/3dteach/comp2720-3d/index.html [25] M. Steiner, De wereldkaart van Gerardus Mercator, Digitaal Erfgoed Nederland, december Op: [26] Bidirectional scattering distribution function. Op: scattering distribution function [27] Demoproeven Pradem Leuven, Katholieke Universiteit Leuven. Op: [28] Lichtbreking. Op: [29] Brekingsindex. Op: [30] Whole body color 3d scanner samples (model wbx). Op: [31] B. Cromwell, Optics, Op: books/5op/ch01/ch01.html [32] Path tracing. Op: Tracing [33] Parallel processing, what it means to you. Op: ultimate samurai/2007/12/13/74209/ [34] GNU General Public License. Op: [35] J. Blanchette en M. Summerfield, C++ GUI Programming with Qt4, Second Edition. Prentice Hall, [36] Qt Reference Documentation. Op:

2004 Gemeenschappelijke proef Algebra - Analyse - Meetkunde - Driehoeksmeting 14 vragen - 2:30 uur Reeks 1 Notatie: tan x is de tangens van de hoek x, cot x is de cotangens van de hoek x Vraag 1 In een

Nadere informatie

Wiskunde voor relativiteitstheorie

Wiskunde voor relativiteitstheorie Wiskunde voor relativiteitstheorie HOVO Utrecht Les 1: Goniometrie en vectoren Dr. Harm van der Lek [email protected] Natuurkunde hobbyist Overzicht colleges 1. College 1 1. Goniometrie 2. Vectoren 2. College

Nadere informatie

Wiskunde voor relativiteitstheorie

Wiskunde voor relativiteitstheorie Wiskunde voor relativiteitstheorie Utrecht Les : Goniometrie en vectoren Dr. Harm van der Lek [email protected] Natuurkunde hobbyist verzicht colleges. College. Goniometrie 2. Vectoren 2. College 2. Matrixen

Nadere informatie

VISUALISATIE VAN KROMMEN EN OPPERVLAKKEN. 1. Inleiding

VISUALISATIE VAN KROMMEN EN OPPERVLAKKEN. 1. Inleiding VISUALISATIE VAN KROMMEN EN OPPERVLAKKEN IGNACE VAN DE WOESTNE. Inleiding In diverse wetenschappelijke disciplines maakt men gebruik van functies om fenomenen of processen te beschrijven. Hiervoor biedt

Nadere informatie

11.0 Voorkennis V

11.0 Voorkennis V 11.0 Voorkennis V 8 6 4 3 6 3 0 5 W 8 1 1 12 2 1 16 4 3 20 5 4 V is een 2 x 4 matrix. W is een 4 x 3 matrix. Deze twee matrices kunnen met elkaar vermenigvuldigd worden. Want het aantal kolommen van matrix

Nadere informatie

Samenvatting wiskunde havo 4 hoofdstuk 5,7,8 en vaardigheden 3 en 4 en havo 5 hoofdstuk 3 en 5 Hoofdstuk 5 afstanden en hoeken Voorkennis Stelling van

Samenvatting wiskunde havo 4 hoofdstuk 5,7,8 en vaardigheden 3 en 4 en havo 5 hoofdstuk 3 en 5 Hoofdstuk 5 afstanden en hoeken Voorkennis Stelling van Samenvatting wiskunde havo 4 hoofdstuk 5,7,8 en vaardigheden 3 en 4 en havo 5 hoofdstuk 3 en 5 Hoofdstuk 5 afstanden en hoeken Stelling van Kan alleen bij rechthoekige driehoeken pythagoras a 2 + b 2 =

Nadere informatie

9.1 Vergelijkingen van lijnen[1]

9.1 Vergelijkingen van lijnen[1] 9.1 Vergelijkingen van lijnen[1] y = -4x + 8 is de vergelijking van een lijn. Hier wordt y uitgedrukt in x. Algemeen: Van de lijn y = ax + b is de richtingscoëfficiënt a en het snijpunt met de y-as (0,

Nadere informatie

Lineaire Algebra voor ST

Lineaire Algebra voor ST Lineaire Algebra voor ST docent: Judith Keijsper TUE, HG 9.31 email: [email protected] studiewijzer: http://www.win.tue.nl/wsk/onderwijs/2ds06 Technische Universiteit Eindhoven college 4 J.Keijsper

Nadere informatie

Uitgewerkte oefeningen

Uitgewerkte oefeningen Uitgewerkte oefeningen Algebra Oefening 1 Gegeven is de ongelijkheid: 4 x. Welke waarden voor x voldoen aan deze ongelijkheid? A) x B) x [ ] 4 C) x, [ ] D) x, Oplossing We werken de ongelijkheid uit: 4

Nadere informatie

TENTAMEN LINEAIRE ALGEBRA 1 donderdag 23 december 2004,

TENTAMEN LINEAIRE ALGEBRA 1 donderdag 23 december 2004, TENTAMEN LINEAIRE ALGEBRA donderdag december 004, 0.00-.00 Bij elke vraag dient een berekening of motivering worden opgeschreven. Het tentamen bestaat uit twee gedeelten: de eerste drie opgaven betreffen

Nadere informatie

De grafiek van een lineair verband is altijd een rechte lijn.

De grafiek van een lineair verband is altijd een rechte lijn. 2. Verbanden Verbanden Als er tussen twee variabelen x en y een verband bestaat kunnen we dat op meerdere manieren vastleggen: door een vergelijking, door een grafiek of door een tabel. Stel dat het verband

Nadere informatie

FLIPIT 5. (a i,j + a j,i )d i d j = d j + 0 = e d. i<j

FLIPIT 5. (a i,j + a j,i )d i d j = d j + 0 = e d. i<j FLIPIT JAAP TOP Een netwerk bestaat uit een eindig aantal punten, waarbij voor elk tweetal ervan gegeven is of er wel of niet een verbinding is tussen deze twee. De punten waarmee een gegeven punt van

Nadere informatie

2010-I. A heeft de coördinaten (4 a, 4a a 2 ). Vraag 1. Toon dit aan. Gelijkstellen: y= 4x x 2 A. y= ax

2010-I. A heeft de coördinaten (4 a, 4a a 2 ). Vraag 1. Toon dit aan. Gelijkstellen: y= 4x x 2 A. y= ax 00-I De parabool met vergelijking y = 4x x en de x-as sluiten een vlakdeel V in. De lijn y = ax (met 0 a < 4) snijdt de parabool in de oorsprong en in punt. Zie de figuur. y= 4x x y= ax heeft de coördinaten

Nadere informatie

x cos α y sin α . (1) x sin α + y cos α We kunnen dit iets anders opschrijven, namelijk als x x y sin α

x cos α y sin α . (1) x sin α + y cos α We kunnen dit iets anders opschrijven, namelijk als x x y sin α Lineaire afbeeldingen Rotatie in dimensie 2 Beschouw het platte vlak dat we identificeren met R 2 Kies een punt P in dit vlak met coördinaten (, y) Stel dat we het vlak roteren met de oorsprong (0, 0)

Nadere informatie

toelatingsexamen-geneeskunde.be Gebaseerd op nota s tijdens het examen, daarom worden niet altijd antwoordmogelijkheden vermeld.

toelatingsexamen-geneeskunde.be Gebaseerd op nota s tijdens het examen, daarom worden niet altijd antwoordmogelijkheden vermeld. Wiskunde juli 2009 Laatste aanpassing: 29 juli 2009. Gebaseerd op nota s tijdens het examen, daarom worden niet altijd antwoordmogelijkheden vermeld. Vraag 1 Wat is de top van deze parabool 2 2. Vraag

Nadere informatie

Vlakke meetkunde. Module 6. 6.1 Geijkte rechte. 6.1.1 Afstand tussen twee punten. 6.1.2 Midden van een lijnstuk

Vlakke meetkunde. Module 6. 6.1 Geijkte rechte. 6.1.1 Afstand tussen twee punten. 6.1.2 Midden van een lijnstuk Module 6 Vlakke meetkunde 6. Geijkte rechte Beschouw een rechte L en kies op deze rechte een punt o als oorsprong en een punt e als eenheidspunt. Indien men aan o en e respectievelijk de getallen 0 en

Nadere informatie

P is nu het punt waarvan de x-coördinaat gelijk is aan die van het punt X en waarvan de y-coördinaat gelijk is aan AB (inclusief het teken).

P is nu het punt waarvan de x-coördinaat gelijk is aan die van het punt X en waarvan de y-coördinaat gelijk is aan AB (inclusief het teken). Inhoud 1. Sinus-functie 1 2. Cosinus-functie 3 3. Tangens-functie 5 4. Eigenschappen 4.1. Verband tussen goniometrische verhoudingen en goniometrische functies 8 4.2. Enkele eigenschappen van de sinus-functie

Nadere informatie

8.0 Voorkennis. Voorbeeld 1: Bereken het snijpunt van 3x + 2y = 6 en -2x + y = 3

8.0 Voorkennis. Voorbeeld 1: Bereken het snijpunt van 3x + 2y = 6 en -2x + y = 3 8.0 Voorkennis Voorbeeld 1: Bereken het snijpunt van 3x + 2y = 6 en -2x + y = 3 2x y 3 3 3x 2 y 6 2 Het vermenigvuldigen van de vergelijkingen zorgt ervoor dat in de volgende stap de x-en tegen elkaar

Nadere informatie

Appendix Inversie bekeken vanuit een complex standpunt

Appendix Inversie bekeken vanuit een complex standpunt Bijlage bij Inversie Appendix Inversie bekeken vanuit een complex standpunt In dee paragraaf gaan we op een andere manier kijken naar inversie. We doen dat met behulp van de complexe getallen. We veronderstellen

Nadere informatie

Meetkunde en lineaire algebra

Meetkunde en lineaire algebra Meetkunde en lineaire algebra Daan Pape Universiteit Gent 7 juni 2012 1 1 Möbius transformaties De mobiustransformatie wordt gegeven door: z az + b cz + d (1) Als we weten dat het drietal (x 1, x 2, x

Nadere informatie

Hoofdstuk 1 LIJNEN IN. Klas 5N Wiskunde 6 perioden

Hoofdstuk 1 LIJNEN IN. Klas 5N Wiskunde 6 perioden Hoofdstuk LIJNEN IN Klas N Wiskunde 6 perioden . DE VECTORVOORSTELLING VAN EEN LIJN VOORBEELD. Gegeven zijn de punten P (, ) en Q (, 8 ). Gevraagd: de vectorvoorstelling van de lijn k door P en Q. Methode:

Nadere informatie

Vectormeetkunde in R 3

Vectormeetkunde in R 3 Vectormeetkunde in R Definitie. Een punt in R wordt gegeven door middel van drie coördinaten : P = (x, y, z). Een lijnstuk tussen twee punten P en Q voorzien van een richting noemen we een pijltje. Notatie

Nadere informatie

Opgave 1 Bekijk de Uitleg, pagina 1. Bekijk wat een vectorvoorstelling van een lijn is.

Opgave 1 Bekijk de Uitleg, pagina 1. Bekijk wat een vectorvoorstelling van een lijn is. 3 Lijnen en hoeken Verkennen Lijnen en hoeken Inleiding Verkennen Bekijk de applet en zie hoe de plaatsvector v ur van elk punt A op de lijn kan ur r ontstaan als som van twee vectoren: p + t r. Beantwoord

Nadere informatie

1 Vlaamse Wiskunde Olympiade : Eerste ronde.

1 Vlaamse Wiskunde Olympiade : Eerste ronde. 1 Vlaamse Wiskunde Olympiade 1998-1999: Eerste ronde De eerste ronde bestaat uit 30 meerkeuzevragen Het quoteringssysteem werkt als volgt: per goed antwoord krijgt de deelnemer 5 punten, een blanco antwoord

Nadere informatie

Opgaven bij de cursus Relativiteitstheorie wiskunde voorkennis Najaar 2018 Docent: Dr. H. (Harm) van der Lek

Opgaven bij de cursus Relativiteitstheorie wiskunde voorkennis Najaar 2018 Docent: Dr. H. (Harm) van der Lek Opgaven bij de cursus Relativiteitstheorie wiskunde voorkennis Najaar 2018 Docent: Dr. H. (Harm) van der Lek Uitwerkingen worden beschikbaar gesteld op de dinsdagavond voorafgaande aan het volgende college

Nadere informatie

Voorbereidende sessie toelatingsexamen

Voorbereidende sessie toelatingsexamen 1/7 Voorbereidende sessie toelatingsexamen Wiskunde 2 - Algebra en meetkunde Dr. Koen De Naeghel 1 KU Leuven Kulak, woensdag 25 april 2018 1 Presentatie en opgeloste oefeningen zijn digitaal beschikbaar

Nadere informatie

Lineaire Algebra voor ST

Lineaire Algebra voor ST Lineaire Algebra voor ST docent: Judith Keijsper TUE, HG 9. email: [email protected] studiewijzer: http://www.win.tue.nl/wsk/onderwijs/ds6 Technische Universiteit Eindhoven college 9 J.Keijsper (TUE)

Nadere informatie

Appendix: Zwaartepunten

Appendix: Zwaartepunten Appendi: Zwaartepunten Enkele opmerkingen vooraf: Maak altijd eerst een schets van het betreffende gebied (en dat hoeft heus niet zo precies te zijn als de grafieken die ik hier door de computer kan laten

Nadere informatie

16.0 Voorkennis. Voorbeeld 1: Los op in 2x + 3i = 5x + 6i -3x = 3i x = -i

16.0 Voorkennis. Voorbeeld 1: Los op in 2x + 3i = 5x + 6i -3x = 3i x = -i 16.0 Voorkennis Voorbeeld 1: Los op in 2x + 3i = 5x + 6i -3x = 3i x = -i Voorbeeld 2: Los op in 4x 2 + 12x + 15 = 0 4x 2 + 12x + 9 + 6 = 0 (2x + 3) 2 + 6 = 0 (2x + 3) 2 = -6 (2x + 3) 2 = 6i 2 2x + 3 =

Nadere informatie

Voorbereiding toelatingsexamen arts/tandarts. Wiskunde: goniometrie en meetkunde. 22 juli 2015. dr. Brenda Casteleyn

Voorbereiding toelatingsexamen arts/tandarts. Wiskunde: goniometrie en meetkunde. 22 juli 2015. dr. Brenda Casteleyn Voorbereiding toelatingsexamen arts/tandarts Wiskunde: goniometrie en meetkunde 22 juli 2015 dr. Brenda Casteleyn Met dank aan: Atheneum van Veurne (http://www.natuurdigitaal.be/geneeskunde/fysica/wiskunde/wiskunde.htm),

Nadere informatie

klas 3 havo Checklist HAVO klas 3.pdf

klas 3 havo Checklist HAVO klas 3.pdf Checklist 3 HAVO wiskunde klas 3 havo Checklist HAVO klas 3.pdf 1. Hoofdstuk 1 - lineaire problemen Ik weet dat de formule y = a x + b hoort bij de grafiek hiernaast. Ik kan bij een lineaire formule de

Nadere informatie

Lijnen, vlakken, normaalvector, shading

Lijnen, vlakken, normaalvector, shading Lijnen, vlakken, normaalvector, shading Inproduct (dotproduct Parametervoorstelling en vergelijking Uitproduct (crossproduct Normaalvector Flat shading en Gouraud shading Opgaven /7 Februari, 05 Definitie

Nadere informatie

1.0 Voorkennis. Voorbeeld 1: Los op: 6x + 28 = 30 10x.

1.0 Voorkennis. Voorbeeld 1: Los op: 6x + 28 = 30 10x. 1.0 Voorkennis Voorbeeld 1: Los op: 6x + 28 = 30 10x. 6x + 28 = 30 10x +10x +10x 16x + 28 = 30-28 -28 16x = 2 :16 :16 x = 2 1 16 8 Stappenplan: 1) Zorg dat alles met x links van het = teken komt te staan;

Nadere informatie

ONBETWIST ONderwijs verbeteren met WISkunde Toetsen Voorbeeldtoetsen Lineaire Algebra Deliverable 3.10 Henk van der Kooij ONBETWIST Deliverable 3.

ONBETWIST ONderwijs verbeteren met WISkunde Toetsen Voorbeeldtoetsen Lineaire Algebra Deliverable 3.10 Henk van der Kooij ONBETWIST Deliverable 3. ONBETWIST ONderwijs verbeteren met WISkunde Toetsen Voorbeeldtoetsen Lineaire Algebra Deliverable 3.10 Henk van der Kooij ONBETWIST Deliverable 3.8 ONBETWIST ONderwijs verbeteren met WISkunde Toetsen Inleiding

Nadere informatie

1 Vlaamse Wiskunde Olympiade : Eerste Ronde.

1 Vlaamse Wiskunde Olympiade : Eerste Ronde. Vlaamse Wiskunde Olympiade 995 996 : Eerste Ronde De eerste ronde bestaat uit 30 meerkeuzevragen, opgemaakt door de jury van VWO Het quoteringssysteem werkt als volgt : een deelnemer start met 30 punten

Nadere informatie

De grafiek van een lineair verband is altijd een rechte lijn.

De grafiek van een lineair verband is altijd een rechte lijn. Verbanden Als er tussen twee variabelen x en y een verband bestaat kunnen we dat op meerdere manieren vastleggen: door een vergelijking, door een grafiek of door een tabel. Stel dat het verband tussen

Nadere informatie

Lineaire afbeeldingen

Lineaire afbeeldingen Les 2 Lineaire afbeeldingen Als een robot bij de robocup (het voetbaltoernooi voor robots een doelpunt wil maken moet hij eerst in de goede positie komen, d.w.z. geschikt achter de bal staan. Hiervoor

Nadere informatie

Uitwerkingen Mei 2012. Eindexamen VWO Wiskunde B. Nederlands Mathematisch Instituut Voor Onderwijs en Onderzoek

Uitwerkingen Mei 2012. Eindexamen VWO Wiskunde B. Nederlands Mathematisch Instituut Voor Onderwijs en Onderzoek Uitwerkingen Mei 01 Eindexamen VWO Wiskunde B A B C Nederlands Mathematisch Instituut Voor Onderwijs en Onderzoek Onafhankelijkheid van a Opgave 1. We moeten aantonen dat F a een primitieve is van de

Nadere informatie

10.0 Voorkennis. y = -4x + 8 is de vergelijking van een lijn. Hier wordt y uitgedrukt in x.

10.0 Voorkennis. y = -4x + 8 is de vergelijking van een lijn. Hier wordt y uitgedrukt in x. 10.0 Voorkennis y = -4x + 8 is de vergelijking van een lijn. Hier wordt y uitgedrukt in x. Algemeen: Van de lijn y = ax + b is de richtingscoëfficiënt a en het snijpunt met de y-as (0, b) y = -4x + 8 kan

Nadere informatie

Boldriehoeken op een wereldkaart. 1. Op zoek naar de kortste afstand

Boldriehoeken op een wereldkaart. 1. Op zoek naar de kortste afstand Boldriehoeken op een wereldkaart 1. Op zoek naar de kortste afstand Een boldriehoek op een wereldbol kun je je makkelijk inbeelden. Je kiest drie steden, en op het aardoppervlak en je verbindt ze met drie

Nadere informatie

DE GONIOMETRISCHE CIRKEL

DE GONIOMETRISCHE CIRKEL robleemstelling DE GONIOMETRISCHE CIRKEL Tijdens de lessen wiskunde worden verschillende verbanden aangeleerd tussen de goniometrische grootheden us, inus en gens. Het is niet eenvoudig om deze allemaal

Nadere informatie

Gaap, ja, nog een keer. In één variabele hebben we deze formule nu al een paar keer gezien:

Gaap, ja, nog een keer. In één variabele hebben we deze formule nu al een paar keer gezien: Van de opgaven met een letter en dus zonder nummer staat het antwoord achterin. De vragen met een nummer behoren tot het huiswerk. Spieken achterin helpt je niets in het beter snappen... 1 Stelling van

Nadere informatie

More points, lines, and planes

More points, lines, and planes More points, lines, and planes Make your own pictures! 1. Lengtes en hoeken In het vorige college hebben we het inwendig product (inproduct) gedefinieerd. Aan de hand daarvan hebben we ook de norm (lengte)

Nadere informatie

14.0 Voorkennis. sin sin sin. Sinusregel: In elke ABC geldt de sinusregel:

14.0 Voorkennis. sin sin sin. Sinusregel: In elke ABC geldt de sinusregel: 14.0 Voorkennis Sinusregel: In elke ABC geldt de sinusregel: a b c sin sin sin Voorbeeld 1: Gegeven is ΔABC met c = 1, α = 54 en β = 6 Bereken a in twee decimalen nauwkeurig. a c sin sin a 1 sin54 sin64

Nadere informatie

Kwantummechanica Donderdag, 13 oktober 2016 OPGAVEN SET HOOFDSTUK 4. Bestudeer Appendix A, bladzijden van het dictaat.

Kwantummechanica Donderdag, 13 oktober 2016 OPGAVEN SET HOOFDSTUK 4. Bestudeer Appendix A, bladzijden van het dictaat. 1 Kwantummechanica Donderdag, 1 oktober 016 OPGAVEN SET HOOFDSTUK 4 VECTOREN OVER DE REËLE RUIMTE DUS DE ELEMENTEN ZIJN REËLE GETALLEN Bestudeer Appendix A, bladzijden 110-114 van het dictaat. Opgave 1:

Nadere informatie

1.1 Lineaire vergelijkingen [1]

1.1 Lineaire vergelijkingen [1] 1.1 Lineaire vergelijkingen [1] Voorbeeld: Los de vergelijking 4x + 3 = 2x + 11 op. Om deze vergelijking op te lossen moet nu een x gevonden worden zodat 4x + 3 gelijk wordt aan 2x + 11. = x kg = 1 kg

Nadere informatie

Trillingen en geluid wiskundig

Trillingen en geluid wiskundig Trillingen en geluid wiskundig 1 De sinus van een hoek 2 Radialen 3 Uitwijking van een harmonische trilling 4 Macht en logaritme 5 Geluidsniveau en amplitude 1 De sinus van een hoek Sinus van een hoek

Nadere informatie

Lineaire Algebra TW1205TI. I.A.M. Goddijn, Faculteit EWI 12 februari 2014

Lineaire Algebra TW1205TI. I.A.M. Goddijn, Faculteit EWI 12 februari 2014 Lineaire Algebra TW1205TI, 12 februari 2014 Contactgegevens Mekelweg 4, kamer 4.240 tel : (015 27)86408 e-mail : [email protected] homepage : http: //fa.its.tudelft.nl/ goddijn blackboard : http:

Nadere informatie

E = mc². E = mc² E = mc² E = mc². E = mc² E = mc² E = mc²

E = mc². E = mc² E = mc² E = mc². E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² E = mc² De boom en het stokje staan loodrecht op de grond in het park. De boom is 3 en het stokje 1. Hoe lang is de schaduw van het stokje

Nadere informatie

Trillingen en geluid wiskundig. 1 De sinus van een hoek 2 Uitwijking van een trilling berekenen 3 Macht en logaritme 4 Geluidsniveau en amplitude

Trillingen en geluid wiskundig. 1 De sinus van een hoek 2 Uitwijking van een trilling berekenen 3 Macht en logaritme 4 Geluidsniveau en amplitude Trillingen en geluid wiskundig 1 De sinus van een hoek 2 Uitwijking van een trilling berekenen 3 Macht en logaritme 4 Geluidsniveau en amplitude 1 De sinus van een hoek Eenheidscirkel In de figuur hiernaast

Nadere informatie

3.2 Vectoren and matrices

3.2 Vectoren and matrices we c = 6 c 2 = 62966 c 3 = 32447966 c 4 = 72966 c 5 = 2632833 c 6 = 4947966 Sectie 32 VECTOREN AND MATRICES Maar het is a priori helemaal niet zeker dat het stelsel vergelijkingen dat opgelost moet worden,

Nadere informatie

De n-dimensionale ruimte Arjen Stolk

De n-dimensionale ruimte Arjen Stolk De n-dimensionale ruimte Arjen Stolk In het vorige college hebben jullie gezien wat R 2 (het vlak) is. Een vector v R 2 is een paar v = (x,y) van reële getallen. Voor vectoren v = (a,b) en w = (c,d) in

Nadere informatie

Overzicht eigenschappen en formules meetkunde

Overzicht eigenschappen en formules meetkunde Overzicht eigenschappen en formules meetkunde xioma s Rechten en hoeken 3 riehoeken 4 Vierhoeken 5 e cirkel 6 Veelhoeken 7 nalytische meetkunde Op de volgende bladzijden vind je de eigenschappen en formules

Nadere informatie

Aanvullingen bij Hoofdstuk 8

Aanvullingen bij Hoofdstuk 8 Aanvullingen bij Hoofdstuk 8 8.5 Definities voor matrices De begrippen eigenwaarde eigenvector eigenruimte karakteristieke veelterm en diagonaliseerbaar worden ook gebruikt voor vierkante matrices los

Nadere informatie

11.1 De parabool [1]

11.1 De parabool [1] 11.1 De parabool [1] Algemeen: Het punt F heet het brandpunt van de parabool. De lijn l heet de richtlijn van de parabool. De afstand van F tot l heet de parameter van de parabool. Defintie van een parabool:

Nadere informatie

V Kegelsneden en Kwadratische Vormen in R. IV.0 Inleiding

V Kegelsneden en Kwadratische Vormen in R. IV.0 Inleiding V Kegelsneden en Kwadratische Vormen in R IV.0 Inleiding V. Homogene kwadratische vormen Een vorm als H (, ) = 5 4 + 8 heet een homogene kwadratische vorm naar de twee variabelen en. Een vorm als K (,

Nadere informatie

8.1 Rekenen met complexe getallen [1]

8.1 Rekenen met complexe getallen [1] 8.1 Rekenen met complexe getallen [1] Natuurlijke getallen: Dit zijn alle positieve gehele getallen en nul. 0, 1, 2, 3, 4, 5, 6,... Het symbool voor de natuurlijke getallen is Gehele getallen: Dit zijn

Nadere informatie

F3 Formules: Formule rechte lijn opstellen 1/3

F3 Formules: Formule rechte lijn opstellen 1/3 F3 Formules: Formule rechte lijn opstellen 1/3 Inleiding Bij Module F1 heb je geleerd dat Formule, Verhaal, Tabel, Grafiek en Vergelijking altijd bij elkaar horen. Bij Module F2 heb je geleerd wat een

Nadere informatie

Hoofdstuk 2: Grafieken en formules

Hoofdstuk 2: Grafieken en formules Hoofdstuk 2: Grafieken en formules Wiskunde VMBO 2011/2012 www.lyceo.nl Hoofdstuk 2: Grafieken en formules Wiskunde 1. Basisvaardigheden 2. Grafieken en formules 3. Algebraïsche verbanden 4. Meetkunde

Nadere informatie

Gebruik de applet om de vragen te beantwoorden. Beweeg punt P over de cirkel.

Gebruik de applet om de vragen te beantwoorden. Beweeg punt P over de cirkel. Raaklijnen Verkennen Raaklijnen Inleiding Verkennen Gebruik de applet om de vragen te beantwoorden. Beweeg punt P over de cirkel. Uitleg Raaklijnen Uitleg Opgave 1 Bekijk de Uitleg. a) Wat is de vergelijking

Nadere informatie

Analytische Meetkunde

Analytische Meetkunde Analytische Meetkunde Meetkunde met Geogebra en vergelijkingen van lijnen 2 Inhoudsopgave Achtergrondinformatie... 4 Meetkunde met Geogebra... 6 Stelling van Thales...... 7 3 Achtergrondinformatie Auteurs

Nadere informatie

Deel 3 havo. Docentenhandleiding havo deel 3 CB

Deel 3 havo. Docentenhandleiding havo deel 3 CB Deel 3 havo De hoeveelheid leerstof is gebaseerd op drie lesuren per week. Met drie lesuren is het in ieder geval mogelijk om de basisstof van tien hoofdstukken door te werken, eventueel met de verkorte

Nadere informatie

Hoofdstuk 4: Meetkunde

Hoofdstuk 4: Meetkunde Hoofdstuk 4: Meetkunde Wiskunde VMBO 2011/2012 www.lyceo.nl Hoofdstuk 4: Meetkunde Wiskunde 1. Basisvaardigheden 2. Grafieken en formules 3. Algebraïsche verbanden 4. Meetkunde Getallen Assenstelsel Lineair

Nadere informatie

UITWERKINGEN 1 2 C : 2 =

UITWERKINGEN 1 2 C : 2 = UITWERKINGEN. De punten A, B, C, D in R zijn gegeven door: A : 0, B : Zij V het vlak door de punten A, B, C. C : D : (a) ( pt) Bepaal het oppervlak van de driehoek met hoekpunten A, B, C. Oplossing: De

Nadere informatie

Voorbereidende sessie toelatingsexamen

Voorbereidende sessie toelatingsexamen 1/34 Voorbereidende sessie toelatingsexamen Wiskunde 2 - Veeltermen en analytische meetkunde Dr. Koen De Naeghel 1 KU Leuven Kulak, woensdag 29 april 2015 1 Presentatie en opgeloste oefeningen zijn digitaal

Nadere informatie

3.1 Kwadratische functies[1]

3.1 Kwadratische functies[1] 3.1 Kwadratische functies[1] Voorbeeld 1: y = x 2-6 Invullen van x = 2 geeft y = 2 2-6 = -2 In dit voorbeeld is: 2 het origineel; -2 het beeld (of de functiewaarde) y = x 2-6 de formule. Een functie voegt

Nadere informatie

Integratie voor meerdere variabelen

Integratie voor meerdere variabelen Wiskunde 2 voor kunstmatige intelligentie, 27/28 Les 4 Integratie voor meerdere variabelen In deze les bekijken we het omgekeerde van de afgeleide, de integratie, en gaan na hoe we een integraal voor functies

Nadere informatie

opdrachten bij hoofdstuk 7 Lijnen cirkels als PDF

opdrachten bij hoofdstuk 7 Lijnen cirkels als PDF lijnen en cirkels opdrachten bij hoofdstuk 7 Lijnen cirkels als PDF 0. voorkennis De vergelijking ax+by=c Stelsels lineaire vergelijkingen De algemene vorm van een lineaire vergelijkingen met de variabele

Nadere informatie

Domein A: Inzicht en handelen

Domein A: Inzicht en handelen Tussendoelen wiskunde onderbouw vo vmbo Preambule Domein A is een overkoepeld domein dat altijd in combinatie met de andere domeinen wordt toegepast (of getoetst). In domein A wordt benoemd: Vaktaal: het

Nadere informatie

1 Vlaamse Wiskunde Olympiade : Eerste Ronde.

1 Vlaamse Wiskunde Olympiade : Eerste Ronde. 1 Vlaamse Wiskunde Olympiade 199 1994 : Eerste Ronde De eerste ronde bestaat uit 0 meerkeuzevragen, opgemaakt door de jury van VWO Het quoteringssysteem werkt als volgt : een deelnemer start met 0 punten

Nadere informatie

1 Vlaamse Wiskunde Olympiade : tweede ronde

1 Vlaamse Wiskunde Olympiade : tweede ronde 1 Vlaamse Wiskunde Olympiade 005-006: tweede ronde Volgende benaderingen kunnen nuttig zijn bij het oplossen van sommige vragen 1,1 3 1,731 5,361 π 3,116 1 Als a 1 3 a 1 3 a m = a met a R + \{0, 1}, dan

Nadere informatie

Correcties en verbeteringen Wiskunde voor het Hoger Onderwijs, deel A.

Correcties en verbeteringen Wiskunde voor het Hoger Onderwijs, deel A. Wiskunde voor het hoger onderwijs deel A Errata 00 Noordhoff Uitgevers Correcties en verbeteringen Wiskunde voor het Hoger Onderwijs, deel A. Hoofdstuk. 4 Op blz. in het Theorieboek staat halverwege de

Nadere informatie

De hoek tussen twee lijnen in Cabri Geometry

De hoek tussen twee lijnen in Cabri Geometry De hoek tussen twee lijnen in Cabri Geometry DICK KLINGENS (e-mail: [email protected]) Krimpenerwaard College, Krimpen aan den IJssel (NL) augustus 2008 1. Inleiding In de (vlakke) Euclidische meetkunde

Nadere informatie

Inwendig product, lengte en orthogonaliteit

Inwendig product, lengte en orthogonaliteit Inwendig product, lengte en orthogonaliteit We beginnen met een definitie : u u Definitie. Als u =. en v = u n v v. v n twee vectoren in Rn zijn, dan heet u v := u T v = u v + u v +... + u n v n het inwendig

Nadere informatie

Opgave 1 - Uitwerking

Opgave 1 - Uitwerking Opgave 1 - Uitwerking Om dit probleem op te lossen moeten we een zogenaamd stelsel van vergelijkingen oplossen. We zetten eerst even de tips van de begeleider onder elkaar: 1. De zak snoep weegt precies

Nadere informatie

Verbanden en functies

Verbanden en functies Verbanden en functies 0. voorkennis Stelsels vergelijkingen Je kunt een stelsel van twee lineaire vergelijkingen met twee variabelen oplossen. De oplossing van het stelsel is het snijpunt van twee lijnen.

Nadere informatie

Lineaire Algebra. Bovendriehoeks- en onderdriehoeks vorm: onder (boven) elke leidende term staan enkel nullen

Lineaire Algebra. Bovendriehoeks- en onderdriehoeks vorm: onder (boven) elke leidende term staan enkel nullen Lineaire Algebra Hoofdstuk 1: Stelsels Gelijkwaardige stelsels: stelsels met gelijke oplv Elementaire rijbewerkingen: 1. van plaats wisselen 2. externe vermenigvuldiging 3. interne optelling (2. en 3.:

Nadere informatie

Paragraaf 7.1 : Lijnen en Hoeken

Paragraaf 7.1 : Lijnen en Hoeken Hoofdstuk 7 Lijnen en cirkels (V5 Wis B) Pagina 1 van 11 Paragraaf 7.1 : Lijnen en Hoeken Les 1 Lijnen Definities Je kunt een lijn op verschillende manieren bepalen / opschrijven : (1) RC - manier y =

Nadere informatie

Zomercursus Wiskunde. Rechten en vlakken (versie 14 augustus 2008)

Zomercursus Wiskunde. Rechten en vlakken (versie 14 augustus 2008) Katholieke Universiteit Leuven September 2008 Rechten en vlakken (versie 14 augustus 2008) 2 Rechten en vlakken Inleiding In deze module behandelen we de theorie van rechten en vlakken in de driedimensionale

Nadere informatie

1 Inleiding. Zomercursus Wiskunde. Poolcoördinaten (versie 27 juni 2008) Katholieke Universiteit Leuven Groep Wetenschap & Technologie.

1 Inleiding. Zomercursus Wiskunde. Poolcoördinaten (versie 27 juni 2008) Katholieke Universiteit Leuven Groep Wetenschap & Technologie. Katholieke Universiteit Leuven September 2008 Poolcoördinaten (versie 27 juni 2008) Inleiding Y y p o θ r X fig In fig worden er op twee verschillende manieren coördinaten gegeven aan het punt p Een eerste

Nadere informatie

Tussendoelen wiskunde onderbouw vo vmbo

Tussendoelen wiskunde onderbouw vo vmbo Tussendoelen wiskunde onderbouw vo vmbo Domein A: Inzicht en handelen Subdomein A1: Vaktaal wiskunde 1. vmbo passende vaktaal voor wiskunde herkennen en gebruiken voor het ordenen van het eigen denken

Nadere informatie

De wiskunde van de beeldherkenning

De wiskunde van de beeldherkenning De wiskunde van de beeldherkenning Op zoek naar wat er niet verandert! In het kader van: (Bij) de Faculteit Wiskunde en Informatica van de TU/e op bezoek c Faculteit Wiskunde en Informatica, TU/e Inhoudsopgave

Nadere informatie

FACULTEIT ECONOMIE EN BEDRIJFSKUNDE Afdeling Kwantitatieve Economie

FACULTEIT ECONOMIE EN BEDRIJFSKUNDE Afdeling Kwantitatieve Economie FACULTEIT ECONOMIE EN BEDRIJFSKUNDE Afdeling Kwantitatieve Economie Lineaire Algebra, tentamen Uitwerkingen vrijdag 4 januari 0, 9 uur Gebruik van een formuleblad of rekenmachine is niet toegestaan. De

Nadere informatie

Basiskennis lineaire algebra

Basiskennis lineaire algebra Basiskennis lineaire algebra Lineaire algebra is belangrijk als achtergrond voor lineaire programmering, omdat we het probleem kunnen tekenen in de n-dimensionale ruimte, waarbij n gelijk is aan het aantal

Nadere informatie

Examen Wiskundige Basistechniek 15 oktober 2011

Examen Wiskundige Basistechniek 15 oktober 2011 Examen Wiskundige Basistechniek 15 oktober 2011 vraag 1: Gegeven is het complex getal ω = exp(i π 5 ). vraag 1.1: Als we in het complexe vlak het punt P met cartesiaanse coördinaten (x, y) vereenzelvigen

Nadere informatie

Rakende cirkels. We geven eerst wat basiseigenschappen over rakende cirkels en raaklijnen aan een cirkel.

Rakende cirkels. We geven eerst wat basiseigenschappen over rakende cirkels en raaklijnen aan een cirkel. Rakende cirkels Inleiding We geven eerst wat basiseigenschappen over rakende cirkels en raaklijnen aan een cirkel. De raaklijn staat, in het raakpunt T, loodrecht op de straal. Bij uitwendig rakende cirkels

Nadere informatie

3.1 Negatieve getallen vermenigvuldigen [1]

3.1 Negatieve getallen vermenigvuldigen [1] 3.1 Negatieve getallen vermenigvuldigen [1] Voorbeeld 1: 5 3 = 15 (3 + 3 + 3 + 3 + 3 = 15) Voorbeeld 2: 5-3 = -15 (-3 +-3 +-3 +-3 +-3 = -3-3 -3-3 -3 = -15) Voorbeeld 3: -5 3 = -15 Voorbeeld 4: -5 3 9 2

Nadere informatie

Zo gaat jouw kunstwerk er straks uitzien. Of misschien wel heel anders.

Zo gaat jouw kunstwerk er straks uitzien. Of misschien wel heel anders. Spirograaf in Python Een kunstwerk maken Met programmeren kun je alles maken! Ook een kunstwerk! In deze les maken we zelf een kunstwerk met Python. Hiervoor zal je werken met herhalingen en variabelen.

Nadere informatie

1 Vlaamse Wiskunde Olympiade : Tweede ronde.

1 Vlaamse Wiskunde Olympiade : Tweede ronde. 1 Vlaamse Wiskunde Olympiade 1998-1999: Tweede ronde De tweede ronde bestaat eveneens uit 0 meerkeuzevragen Het quoteringssysteem is hetzelfde als dat voor de eerste ronde, dwz per goed antwoord krijgt

Nadere informatie

Inwendig product, lengte en orthogonaliteit in R n

Inwendig product, lengte en orthogonaliteit in R n Inwendig product, lengte en orthogonaliteit in R n Het inwendig product kan eenvoudig worden gegeneraliseerd tot : u v u v Definitie Als u = u n en v = v n twee vectoren in Rn zijn, dan heet u v := u T

Nadere informatie

1 Analytische meetkunde

1 Analytische meetkunde Domein Meetkunde havo B 1 Analytische meetkunde Inhoud 1.1. Coördinaten in het vlak 1.2. Vergelijkingen van lijnen 1.3. Vergelijkingen van cirkels 1.4. Snijden 1.5. Overzicht In opdracht van: Commissie

Nadere informatie

WISKUNDE 5 PERIODEN. DATUM : 4 juni 2010. Formuleboekje voor de Europese scholen Niet-programmeerbare, niet-grafische rekenmachine

WISKUNDE 5 PERIODEN. DATUM : 4 juni 2010. Formuleboekje voor de Europese scholen Niet-programmeerbare, niet-grafische rekenmachine EUROPEES BACCALAUREAAT 2010 WISKUNDE 5 PERIODEN DATUM : 4 juni 2010 DUUR VAN HET EXAMEN : 4 uur (240 minuten) TOEGESTANE HULPMIDDELEN : Formuleboekje voor de Europese scholen Niet-programmeerbare, niet-grafische

Nadere informatie

Les 1 : Vectoren. Hoofdstuk 6 Vectormeetkunde (H4 Wiskunde D) Pagina 1 van 14. Definities Vector x = ( a ) wil zeggen a naar rechts en b omhoog.

Les 1 : Vectoren. Hoofdstuk 6 Vectormeetkunde (H4 Wiskunde D) Pagina 1 van 14. Definities Vector x = ( a ) wil zeggen a naar rechts en b omhoog. Hoofdstuk 6 Vectormeetkunde (H4 Wiskunde D) Pagina 1 van 14 Les 1 : Vectoren Definities Vector x = ( a ) wil zeggen a naar rechts en b omhoog. b Je kunt vectoren tekenen en berekenen. We doen dat aan de

Nadere informatie

Goniometrische functies

Goniometrische functies Goniometrische functies gonè (Grieks) = hoek metron (Grieks) = maat Goniometrie, afkomstig van de Griekse woorden voor hoek en maat, betekent letterlijk hoekmeetkunde. Daarmee wordt aangegeven dat het

Nadere informatie

Bekijk nog een keer het stelsel van twee vergelijkingen met twee onbekenden x en y: { De tweede vergelijking van de eerste aftrekken geeft:

Bekijk nog een keer het stelsel van twee vergelijkingen met twee onbekenden x en y: { De tweede vergelijking van de eerste aftrekken geeft: Determinanten Invoeren van het begrip determinant Bekijk nog een keer het stelsel van twee vergelijkingen met twee onbekenden x en y: { a x + b y = c a 2 a 2 x + b 2 y = c 2 a Dit levert op: { a a 2 x

Nadere informatie

Samenvatting VWO wiskunde B H04 Meetkunde

Samenvatting VWO wiskunde B H04 Meetkunde Samenvatting VWO wiskunde B H04 Meetkunde Getal & Ruimte editie 11 Goniometrie in rechthoekige driehoeken Stap 1: Zoek de rechthoekige driehoeken Figuur 1: Ga na dat in dit voorbeeld alleen ADC en DBC

Nadere informatie

Examen HAVO. wiskunde B (pilot) tijdvak 1 woensdag 20 mei 13.30-16.30 uur

Examen HAVO. wiskunde B (pilot) tijdvak 1 woensdag 20 mei 13.30-16.30 uur Eamen HAV 2015 1 tijdvak 1 woensdag 20 mei 13.30-16.30 uur wiskunde B (pilot) Dit eamen bestaat uit 16 vragen. Voor dit eamen zijn maimaal 76 punten te behalen. Voor elk vraagnummer staat hoeveel punten

Nadere informatie

Samenvatting Wiskunde Aantal onderwerpen

Samenvatting Wiskunde Aantal onderwerpen Samenvatting Wiskunde Aantal onderwerpen Samenvatting door een scholier 2378 woorden 4 juni 2005 5,1 222 keer beoordeeld Vak Wiskunde Gelijkvormigheid Bij vergroten of verkleinen van een figuur worden

Nadere informatie