Raytracers make a decent benchmark for measuring CPU and floating point performance: a lot of home computers from the 80s had raytracing software, so why not the humble Arduino? Well, it’s not just a benchmark for processors - it’s a good one for developers too, as a somewhat typical toy program to learn more about recursion… and feature creep : )
Here is a raytracer which handles purely ray-triangle intersection from a fixed camera viewpoint and one light source. It outputs square images, using scene data compiled-in as a .h file (and stored in PROGMEM). Each face may have an attached material, allowing a custom setting of ambient, diffuse, transparency and reflection per surface.
The heart of this raytracer is the Moller-Trumbore algorithm, which was invented by a couple guys far smarter than me! It does ray-triangle intersection, returning true if the two collide (as well as u-v coordinates, surface normal, and distance - all important for material calculation). A Google search will turn up plenty of resources to find out more about it.
All math is done using “double” floating point data types (on Arduino, double and float are the same). This means that there is a LOT of software floating-point calculation, which is grindingly slow. One improvement would be to convert to 16.16 fixed-point, but I’m already at the fringe of what should be done on a microcontroller and don’t feel like sinking more time into this.
The output feeds back to the PC pixel-by-pixel over serial. Once the image is complete, the Arduino goes into an infinite loop. Copy-paste the output from serial monitor into a .ppm file and open in a graphics editor.
I actually wrote this as a standalone PC application first, and then converted the bits to Arduino. It can be compiled for either platform by using a shim arduino.h file which fakes things like millis(), Serial.print() and a couple other things.
Code is attached, and some test images to follow. Fun modifications to this would be texturing (procedural based on u-v, or just raster), other non-triangle primitives, fixed-point calculations, multiple light sources, … Well, fun for you maybe. Me, I’ll just use POVRay instead.
Raytracer.zip (11.7 KB)