diff options
| author | James Barnett <noreply@jamesbarnett.xyz> | 2022-01-01 21:21:52 +0000 |
|---|---|---|
| committer | James Barnett <noreply@jamesbarnett.xyz> | 2022-01-01 21:21:52 +0000 |
| commit | 7ad1b7efabea1349107669a432e6c88305f8d825 (patch) | |
| tree | 8de34e4b3e20e4e8c0c01578ce0b0cfaa46cc6cf /src/index.ts | |
| parent | dc5e815da04d7c377b3cb51558d6fe7b8e0fd7c0 (diff) | |
| download | js-raytracer-7ad1b7efabea1349107669a432e6c88305f8d825.tar.xz js-raytracer-7ad1b7efabea1349107669a432e6c88305f8d825.zip | |
Implement basic ray tracing
Diffstat (limited to 'src/index.ts')
| -rw-r--r-- | src/index.ts | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..f10ef84 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,84 @@ +import {Colour} from './Colour'; +import {Framebuffer} from './Framebuffer'; +import {Plane, Sphere} from './Geometry'; +import {Light} from './Light'; +import {Material} from './Material'; +import {Raytracer, RaytracerOptions} from './Raytracer'; +import {Vector} from './Vector'; + +function parseOptions(): RaytracerOptions { + return { + shadows: getInputElement('shadows-toggle').checked, + diffuseLighting: getInputElement('diffuse-toggle').checked, + specularLighting: getInputElement('specular-toggle').checked, + reflections: getInputElement('reflections-toggle').checked, + maxRecurseDepth: 5, + maxDrawDistance: 1000, + }; +} + +function initRaytracer(options: RaytracerOptions): Raytracer { + const width = 960; + const height = 720; + const fov = Math.PI / 3; + + const framebuffer = new Framebuffer(width, height); + + const matWhite = new Material(new Colour(102, 102, 77), 0.6, 0.3, 0.1, 50); + const matRed = new Material(new Colour(77, 26, 26), 0.9, 0.1, 0.0, 10); + const matMirror = new Material(new Colour(193, 193, 193), 0.0, 10, 0.8, 1000); + const matGreen= new Material(new Colour(77, 255, 26), 0.3, 0.1, 0.0, 2); + + const spheres = [ + new Sphere(new Vector(-3, 0, -16), 2, matWhite), + new Sphere(new Vector(-1, -1.5, -12), 2, matGreen), + new Sphere(new Vector(1.5, -0.5, -18), 3, matRed), + new Sphere(new Vector(7, 5, -18), 4, matMirror), + ]; + + const planes = [ + new Plane(-4, 10, -10, -30, 0.7) + ]; + + const lights = [ + new Light(new Vector(-20, 20, 20), 1.5), + new Light(new Vector(30, 50, -25), 1.8), + new Light(new Vector(30, 20, 30), 1.7), + ]; + + return new Raytracer(framebuffer, fov, spheres, planes, lights, options); +} + +function render() { + const raytracer = initRaytracer(parseOptions()); + showLoadingIndicator(); + + // Give browser time to repaint + setTimeout(() => { + const startMs = new Date().getTime(); + raytracer.render(); + console.log(`Render took ${new Date().getTime() - startMs}ms`); + hideLoadingIndicator(); + }, 50); +} + +function registerEventListeners() { + document.getElementById('render')?.addEventListener('click', render); // TODO disable once clicked +} + +function showLoadingIndicator() { + document.getElementById('output-wrapper')?.classList.add('loading'); +} + +function hideLoadingIndicator() { + document.getElementById('output-wrapper')?.classList.remove('loading'); +} + +function getInputElement(elementId: string) { + return document.getElementById(elementId) as HTMLInputElement; +} + +document.addEventListener('DOMContentLoaded', () => { + registerEventListeners(); + render(); +}); |