aboutsummaryrefslogtreecommitdiff
path: root/src/index.ts
diff options
context:
space:
mode:
authorJames Barnett <noreply@jamesbarnett.xyz>2022-01-01 21:21:52 +0000
committerJames Barnett <noreply@jamesbarnett.xyz>2022-01-01 21:21:52 +0000
commit7ad1b7efabea1349107669a432e6c88305f8d825 (patch)
tree8de34e4b3e20e4e8c0c01578ce0b0cfaa46cc6cf /src/index.ts
parentdc5e815da04d7c377b3cb51558d6fe7b8e0fd7c0 (diff)
downloadjs-raytracer-7ad1b7efabea1349107669a432e6c88305f8d825.tar.xz
js-raytracer-7ad1b7efabea1349107669a432e6c88305f8d825.zip
Implement basic ray tracing
Diffstat (limited to 'src/index.ts')
-rw-r--r--src/index.ts84
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();
+});