Raytracing 03 - Schaakborden en meer objecten

Dit bericht is onderdeel van een langere serie over raytracing. Voor de hele serie, zie hier.

De wereld ziet er nu prachtig uit, maar kan alleen bestaan uit oneindige vlakken en bollen. Beiden zijn niet heel handig bij het ontwerpen van nieuwe omgevingen. Daarom voeg ik in deze versie twee nieuwe elementen toe, de cylinder en de doos. Die laatste gaat in volgende versies veel nut hebben, maar dat komt later. Daarnaast hebben alle dingen in de ruimte nog een specifieke kleur. Dat hoeft natuurlijk niet, dus heb ik ook een schaakbordpatroon als kleur-optie toegevoegd.

Nieuwe objecten

De cylinder was het makkelijkst om toe te voegen. Immers, ddie heeft net zoals de bol een directe formule waaraan ieder punt op de cylinder aan voldoet en voor de normaal, te zijnde:
(p_x - c_x)^2 + (p_z - c_z)^2 = r^2
n = {p_x - c_x, 0 , p_z - c_z}

De bovenste formule is uit te werken tot een kwadratische vergelijking en dan op te lossen, de onderste geeft natuurlijk direct al een antwoord.

De doos was daarentegen lastiger. Deze heeft namelijk 6 oppervlakken, die allemaal een snijpunt kunnen hebben. Om het makkelijker te maken definieer ik de doos evenwijdig aan alle assen. Hierdoor kan je eenvoudig de snijpunten met alle zijden berekenen. Daarna moet je alleen nog kijken of ieder van die snijpunten wel op de doos ligt en welke het dichtstbijzijnd is.

Schaakborden

Schaakborden zijn vrij simpel, je moet zorgen dat je afwisselend 1 en 0 hebt over je coördinatensysteem laten lopen. Dit kan je vrij simpel doen met
(x XOR z)&1 maar hierbij bleek dat JavaScript zijn float/integer conversie ietwat ongewoon doet. Zie onder.
Verwacht:
1.5  | 0 -> 1
-1.5 | 0 -> -2
Werkelijkheid
1.5  | 0 -> 1
-1.5 | 0 -> -1

Dit leverde wat extra uitzonderingen op die helaas iets langzamer waren, maar het resultaat is nog steeds vrij efficiënt.

En verder

Verder heb ik ook nog progressive raytracing geïmplementeerd. Ik zou dit verder kunnen uitleggen maar als men de link volgt komt men bij een artikel van iemand die dat een stuk beter doet.

Daarnaast heb ik nog een extreem klein begin gemaakt aan een "scene" editor, die uiteindelijk scènes voor de raytracer met klik en sleep moet kunnen gaan maken. Deze is gebaseerd op WebGL en Three.js, omdat je daarmee heel simpel basis vormen kunt maken. Het enige nadeel is dat oneindige vormen, zoals cylinders en vlakken, niet gemaakt kunnen worden. Ik verzin hier nog wel wat op. Voor de rest, bekijk zoals altijd de changelog en geniet van het programma.

Nieuwe scene in de raytracer

Verder in deze serie

Raytracing 02 - Reflectie en supersampling
Raytracing 01 - De basisstappen
Bert Peters | 19:08:50 01/02/2012 | Link | 0 reactie(s) | Tags: Serie ray tracing 
tweet


Raytracing 02 - Reflectie en supersampling

Bij de vorige versie van mijn javascript raytracer slaagde ik er maar niet in om daadwerkelijk Anti-aliasing door middel van supersampling (zie referentie) te implementeren. Lang verhaal, maar de clou was dat ergens in dat proces iets ontplofte waardoor de helft van het resultaat alleen maar wit werd.

Daarnaast moest ik natuurlijk ook nog een van de meest overtuigende effecten met raytracing implementeren, namelijk reflecties. Deze zijn simpel, doch zeker effectief en geven het eindresultaat een veel realistischer "gevoel" (weinig gebruikt woord in mijn vakgebied) dan zonder.

Reflectie

Het fijne aan raytracing is dat reflecties relatief makkelijk gaan. Het enige dat je hoeft te doen, is de nieuwe lichtstraal berekenen en deze dan weer het algoritme in gooien. De lichtstraal heeft twee eigenschappen, een oorsprong en een richting. De oorsprong is het makkelijkst, dat is namelijk het punt waar je oorspronkelijke lichtstraal het object raakte. De richting is iets lastiger, maar vrij simpel in code;
Vector normaal, richting, nieuwerichting;
nieuwerichting = richting - normaal * normaal.dot(richting);

Hierbij is de * operator de scalarvermenigvuldiging van een vector en vector.dot rekent het inwendig product van de twee vectoren. Juist. Nu enkel nog de raytrace functie weer aanroepen en de reflectiekleur is gevonden. Voor een extra beetje realiteit vermenigvuldig ik de reflectiekleur ook nog met de kleur van het object, zodat bijvoorbeeld rode objecten ook een rodere reflectie opleveren.

Supersampling

Supersampling is een eenvoudige techniek, waarbij je simpelweg meervoudig de pixel (een klein beetje opgeschoven) bekijkt, en het gemiddelde van het resultaat neemt. Dit heeft als voordeel dat de kartelige randjes inderdaad weg gaan.
Helaas is dit ook heel veel extra rekenwerk. Het is niet efficiënt, en zelfs in het midden van een object (waar toch de meeste stralen zullen vallen). Hiervoor is multisampling bedacht, maar daar ben ik nog niet aan toe. Eerst dit maar.

En verder

Verder zijn er nog een paar fouten gerepareerd, lees vooral het changelog. Ook is er een debugoptie toegevoegd, highlight object. Het object met als ID deze waarde zal paars worden weergegeven. Object IDs zijn altijd >= 0, dus met -1 wordt niets gemarkeerd.

Huidige versie van de scene, 4x4 anti-aliasing en een hoge tracediepte.

Verder in deze serie

Raytracing 01 - de basisstappen
Bert Peters | 10:02:16 18/01/2012 | Link | 0 reactie(s) | Tags: Serie ray tracing 
tweet

Korte update

In het berichtje over de kansverdeling van het Collatz vermoeden (de vorige, wel te verstaan) sprak ik over een onderzoekje naar de daadwerkelijke kansverdeling van deze reeks.
Ik heb nu de demo geüpdatet zodat deze ook de verdeling van het interval geeft.
Onderstaande grafiek geeft de verdeling weer van het interval beginnende op 1000, strekkende tot 210000, met distributie accuratie 1. Deze laatste parameter geeft weer hoe groot de stukjes zijn waarin de distributie is opgedeeld, volgens de formule:
grootte = 1/accuratie;
Distributie van 1000 tot 210000
Bert Peters | 14:49:25 11/12/2011 | Link | 0 reactie(s) | Tags: HTML5 
tweet


Willekeurige getallen (en simpel)

Zo'n studie is best interessant. Je krijgt voor de verandering opdrachten die je wel aan het denken zetten. Daar wordt een mens gelukkig van. In ieder geval levert het ideeën op. Zo ook deze.

Voor een verder volstrekt willekeurige opdracht werd een zijspoortje aangeleverd, namelijk het Collatz vermoeden. Uitleg op de Wiki pagina.

Dit eenvoudige gegeven levert voor ieder getal een aantal stappen op dat nodig is om tot 1 te komen. Dit blijkt vrij willekeurig te zijn, en daarom dacht ik dat daar een fatsoenlijke random generator uit gemaakt kon worden. Vandaar dit experiment.
Omdat het aantal iteraties voor grote getallen natuurlijk meestal groter is dan dat van kleinere getallen, deel je het resultaat door het binair logaritme van het getal in kwestie. Hierdoor krijg je een getal dat altijd tussen de 1 en circa 20 ligt, Zie de grafiek.
een plot van de pseudo-willekeurige getallen 2 tot 101

Een goed onderzoek naar de willekeurigheid (en de implementatie) moet ik nog doen, maar tot nu toe ziet het er redelijk uit. Voor mensen die andere intervallen willen plotten, kijk eens op de demo.
Bert Peters | 21:57:13 10/12/2011 | Link | 0 reactie(s) | Tags: HTML5 
tweet

Raytracing 01 - De basisstappen

Zo, er kwam tijdelijk iets te veel voorbij om een zinnig stuk te schrijven, maar dan nu toch echt. Raytracing. Had ik beloofd.

Wat is Ray Tracing?

Ray tracing is een algoritme om een weergave van een drie dimensionale omgeving te creëren op een tweedimensionaal vlak. In monkey terms, om afbeeldingen te renderen. Ray tracing heeft als voordelen dat vrij veel visuele effecten zoals schaduwen en reflecties eenvoudig te implementeren zijn en dat het algoritme ook vrij logisch is. Het grote nadeel is dat het ongelofelijk veel zinloos rekenwerk is, duizenden keren zo veel als noodzakelijk voor wireframe-rendering.

Het algoritme is simpel. Men heeft namelijk een camerapunt en een "denkbeeldig" scherm. Vervolgens stel je voor iedere pixel van dat scherm een "lichtstraal" op, die door die pixel gaat vanuit het camerapunt. Dan is het een kwestie van het eerste object vinden waar die straal op botst. Dit is tijdrovend en daarmee ook het grootste punt van vertraging. Tot zover de theorie, nu het programma.

Licht en schaduw

Om mee te beginnen wilde ik net als dit artikel op Flipcode, dat geholpen heeft bij het schrijven van mijn profielwerkstuk, beginnen met simpele diffusie en schaduw.

Schaduw kan je berekenen door vanaf het punt in de ruimte dat je gevonden hebt te kijken of er een vrij pad bestaat tussen dat punt en de lichtbron(nen). Dit is eigenlijk hetzelfde als een gewone intersectietest, dus niet heel bijzonder.

Diffusie is daarentegen een stuk moeilijker correct te simuleren. Eigenlijk zou je miljarden fotonen moeten afvuren en kijken waar ze een beetje terechtkomen. Helaas, dit is veel werk, en dus doen we een benadering. Deze gaat als volgt:
for(iedere lichtbron) {
  if(!in_schaduw()) {
    lichtsterkte += lichtsterkte_bron * (oppervlaktenormaal * lichtinvalshoek) / afstand_lichtbron^2;
  }
}

Zoals te zien is deze verre van correct, maar het ziet er verder redelijk uit en daar gaat het om.. Zie onder.
Resultaat van raytracer 1
Bert Peters | 20:30:52 21/11/2011 | Link | 0 reactie(s) | Tags: Serie ray tracing 
tweet


Javascript image viewer

Het schrijven van een artikel over ray-tracing duurt iets langer dan ik tijd voor heb; in plaats daarvan iets waar makkelijker tijd voor vrij te maken is, namelijk iets wat ik toch al nodig had. Wat dan? Een lichtgewicht programma om simpel te schrijven afbeeldingsformaten (NetPBM, SWI) te lezen.

Blijkbaar kan dat ook in javascript, want het is gelukt. De bediening is vrij simpel, sleep een afbeeldingsbestand van je computer naar het venster, en hij wordt weergegeven. Voor ondersteunde formaten en exporteren moetn men even de muis over de menutab rechtsboven houden.

Dit projectje was ook voor mij een ervaring om een keertje met CSS3 te spelen, in dit geval transities, gradienten en "position:fixed".

Mocht iemand nog een goed idee hebben voor een te ondersteunen bestandsformaat, laat deze achter als reactie. (en suggereer geen TIFF, daar wordt al aan gewerkt)
Bert Peters | 18:42:29 07/10/2011 | Link | 0 reactie(s) | Tags: HTML5 
tweet

Raytracing - The prequel

Voor mijn profielwerkstuk heb ik het afgelopen jaar een Raytracer geschreven. Eigenlijk acht, trouwens. Waarom is dit relevant? Dat is het ook niet. Maar het resultaat is wel leuk. (versie 2 werkt niet, geen zin om die te fixen. Alle andere versies werken wel.)

De reden dat ik dit op schrijf, is dat ik niet helemaal tevreden ben met het eindresultaat. Het ziet er allemaal wel redelijk uit, maar vanaf een bepaald punt moest ik enkel en alleen om mijn eerdere fouten in het ontwerp heen werken. Het resultaat is langzaam en bovendien een "amateuristische hack" te noemen.

Dit bracht mij tot het plan om een serie over ray-tracing te gaan schrijven. Te beginnen zo snel mogelijk. In een aantal delen ga ik een ray-tracer schrijven, waar steeds weer nieuwe grafische mogelijkheden aan toe gaan worden gevoegd. Ik hoop een deel per maand te kunnen gaan schrijven, maar helaas ben ik begonnen met studeren (iets nuttigs) dus wordt er meer beslag gelegd op mijn tijd. We zien wel. Dit was deel 0, dus nu gaat het beginnen.

Bert Peters | 16:21:57 04/09/2011 | Link | 0 reactie(s) | Tags: Serie ray tracing 
tweet


Pagina 1 van 5. Ga naar 1, 2, 3, 4, 5