Rendering 3D Graphics Using an Arduino Nano.

This started as the result of misreading the title of a Reddit post by u/Trotztd and lead to rendering 3D graphics on an Arduino.

The title of the post was “Raymarching on Arduino Uno OLED 128×64 with dithering. 15 seconds per frame.” which I erroneously read as 15 frames per second.

I had been previously looking at raytracing in the hope of inspiration of making a simple 3D game. I also happened to have a SSD1306 OLED display running (alongside a ST7920 LCD), so thought I would give it a try.

To be honest, I only realised that I had misread the title of the post when the display didn’t show anything for 15 seconds and froze for 17-20 seconds after each frame.

I also noticed that the Arduino outputted the time taken between frames to the serial monitor, so I captured some data, slapped it in excel and created an x-y scatter plot.

Please excuse the erroneous title on the graph; the unit of measurement on the Y-axis is milliseconds (ms), not seconds (s).

Interestingly, the graph produced a sinusoidal wave that was in phase with the rotation of the torus on the display.

In a comment reply from u/Trotztd , they suggested using an ESP32 for a faster experience. So, I pulled out a 38 Pin ESP32 DEV Kit, wiggled the wires in to place and uploaded the code.

With the added computational power, the refresh rate increased from 0.05Hz to 4.6Hz. That’s a 9200% improvement.

The blistering 4.6Hz display can be seen in this video.

Again, the time taken to render each frame varied in phase with the rotation of the torus; albeit a lot faster.

I did consider the time taken by the display driver chip may be the cause of the rhythmic timing as it will take longer to address a greater number of pixels (or vice versa) so I played around with the code.

In the first instance I commented out the outputMatrix( ); function call; however, this buggered the program and the serial monitor just spat out a random list of 0’s and 1’s.

The second attempt to disable the display was to comment out the ssd1306_lcd.next_page(); command within the outputMatrix( ); function. However, this appeared to change absolutely nothing. So my theory remains nothing more than a theory.