Updated on my Ray Tracer


My little ray tracer project has had a few improvements since my last post at the start of the year so I thought it would be good to do a new post on the progress. I have mainly been working on a native version using SDL2 for user input (moving the camera) and presentation. However the web version in my previous post was simply returning a list of RGB values which I would then draw directly to the canvas, and using the left-right buttons for input. Then I discovered that Emscripten has a port of SDL2 so I could use the same approach for the web version as for the native one.

I also wanted the web version to be multithreaded. The simplest way to do this would be to use pthreads, however it seems that not all browsers implement the SharedArrayBuffer object required to make this work. So to make my ray tracer work on all modern web browsers, I used web workers (with no shared memory). How it works is that one worker parses and serialises the scene, then returns a scene binary, which is then distributed to the other web workers for rendering. Each worker renders 1/(number of possible CPU threads) rows of the scene. Keep in mine the first time you render something after loading the page, it will be a slower because the browser needs to create the web workers, and download the data for textures and 3D models.

Since my last post I’ve implemented texture mapping (see skybox and globe scenes), 3D models and bounding volume heirarchies (see Models scene). After rendering a scene you can click on the canvas, then use your keyobard arrow keys (up,down,left,right) of orbit the scene. I have preloaded a few scenes that you can find in the dropdown list. Also there are the following 3rd models located in /rayTracerModels:

  • Stanford Armadillo (armadillo.obj)
  • Stanford Dragon (dragon.obj)
  • Stanford Bunny (bunny.obj)
  • Porsche 911 (porsche.obj)
  • Blender’s Suzanne (suzanne.obj)

You can use the syntax in the Models (hippy) scene to define a 3D model object and add it to your scene. Keep in mind this has a 3 models with tens of thousands of triangles so it will be slower to render than the other scenes. It takes about 30 seconds on my 4 core laptop. Just change the camera resolution in the YAML to something smaller to render it faster.

So try it out below! I have done some but not a huge amount of error handling so just reload the page if anything breaks. I’ll continue to work on this to make it better, but wanted to get it out there for people to try for now.