Ray Tracing On An Arduino

[Greg] implemented a simple ray tracer for Arduino as a fun exercise and a way to benchmark the processor. He started out with the Moller-Trumbore algorithm, a common ray-tracing algorithm that calculates the intersection of a ray with a triangular plane without doing any pre-calculation of the planes. His code supports one static light and one static camera, which is enough to render a simple scene.

[Greg] started out with a small scene composed of a few polygons, but just finished up a scene with 505 vertices, 901 faces, and reflective surfaces (shown above). He made the above render on his PC emulator, but estimates that it would take just over 4 days to render on the Arduino. [Greg]’s project supports multiple bounces of light, which differentiates his ray tracer from some we’ve covered before (and which explains why it takes so long to render).

The ray tracer is implemented entirely with double-precision floats. This translates to a ton of software float emulation instructions, since the Arduino doesn’t have a floating-point unit. While this ray tracer can’t render anything near real-time graphics due to the slowness of the microcontroller, it’s still a great proof of concept.

The title image for this post was rendered on a modern PC, taking 263 seconds to complete. The same scene, at 64×64 resolution, was rendered on the Arduino, taking 4008 seconds to complete. That render is below.


22 thoughts on “Ray Tracing On An Arduino

  1. “The ray tracer is implemented entirely with double-precision floats. ”
    Unfortunately, the arduino (based on avr-gcc) doesn’t support double precision floats. It accepts them syntactically, but converts them all to single precision

  2. I don’t want to be mean, but I would have expected something more exciting than a suboptimal (doubles on an 8 bit MCU?) implementation of a standard algorithm. This somehow lacks the “hack” and the hack…

    Also, triangles are not very suitable for raytracing. He could have easily built his scene from planes and spheres and get a massive speed up by reducing the number of intersections to calculated.

    1. Don’t worry, the avrcc compiler doesn’t do doubles, it only does floats (it accepts ‘double’ in the source code but it uses ‘float’ to implement them).

      Anyway; it sounds like you’ve just seen a glove hit the floor. We expect you to pick it up and post your riposte on here real soon…

  3. As the article clearly states this is to benchmark the Arduino against other platforms, if the goal is simply to draw 3d scenes then of course there are much faster ways to do it. Wolf3D-type engines can run on much less than this, I wrote a simple engine for the Arduino-based Gamebuino a while back (see https://www.youtube.com/watch?v=4m-Nj2IkDpo) and the bottlenecks in that demo were entirely due to the display, the 328p itself is surprisingly capable.

  4. I wonder what kind of bounding a limits he used. Stop calculating after the X’th refraction/reflection. Y distance is ‘infinite’. Invisible bounding spheres around complex shapes.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.