Ray tracer on Arduboy [WIP]

hi,

I’ve started a tiny ray tracer on arduboy, I was just curious how far I can push it. It’s currently only ~2fps, but I thought l’ll share a screen of it with the community:
image

The goal is to create a tiny tech demo that resembles the look of “Descent” back then.

******** update ********
now it’s around 8 to 60 fps, depends heavily on the complexity of the geometry you see
Tracino.ino.hex (42.9 KB)

Left/Right/Up/Down to strave/move
hold A and Left/Right/Up/Down to rotate

after some amount of rotation, the view matrix gets messed too much and it all will fall apart :sweat: I have a fix (works on the PC version) but it’s using just that tiny bit too much memory to hold the temporaries.

on request, license is: you can play it on the emulator and download it to play it Arduboy.

9 Likes

This is super cool!

1 Like

i can check the fps on ESPboy - ESP8266 160Mhz. Probably it will be enough for the game right now

This is very cool but also feel like I have to be “that guy” and say I think this is actually a rasterizer not a ray tracer…

How did you arrive at that conclusion, might I ask?

I wouldn’t have thought it was possible to tell the difference at such a low bit depth.

Maybe it is, I see it’s only running at 2fps so possibly.

Basing my assumption on the fact of how computationally difficult raytracing is.

The difficulty of computing a single ray depends on what settings and effects you use.
If you keep it simple, with low settings, then it’s generally not too bad, most of the heavy lifting is multiplication.

The biggest issues with ray tracing are how many bounces are involved, what effects you allow (e.g. refraction is perhaps worse than reflection) and how many pixels you actually have to trace a ray for.

The number of pixels is a big problem for high resolutions like 1920x1080 (2,073,600 pixels, thus 2,073,600 rays, each potentially bouncing multiple times, multiple times per second) but not quite so demanding for lower resolutions - 128x64 is only 1024 pixels, which is still a lot for an 8-bit CPU, but not so bad in the grand scheme of things.


I doubt raytacing is ever going to be fast enough on the Arduboy to achieve something playable in real time, even with fixed point arithmetic, but it could possibly be used for generating a static background scene for a game like Dark & Under or something a bit like the original MYST.

Ideally the background would be computed once, perhaps over several updates if it’s particularly slow, and then the frame buffer wouldn’t be cleared, or only parts of it would be cleared.


There’s a pretty good discussion of how raytracing works, including calculations, here:
http://www.cs.unc.edu/~rademach/xroads-RT/RTarticle.html

(Since it isn’t mentioned in the article: dot_product(N, V) = (Nx * Vx) + (Ny * Vy) + (Nz * Vz).)

Lol, I just checked out the OP’s twitter and:

Past: Graphics Software Architect @ Id Software, Rendering Lead Crytek, Engine

Ok might be raytracing :joy: my bad.

4 Likes

That looks like a cool device, with 32bit and 160MHz, life/RT would be so easy :slight_smile: ; I might check, ones I feel I got to the limits of that tiny 8bit CPU.

edit → I’ve tried to reply to multiple person in one post, hence it looks like the reply is linked to the wrong post, sorry.

It’s really a ray-tracer; I’ve just done a rasterizer project and I’ve also seen someone already created a nice Star Fox rasterizer, hence I had an urge to go one step crazier.

I doubt raytacing is ever going to be fast enough on the Arduboy to achieve something playable

It won’t be more than the first bounce, hence no reflections, shadows etc. (at least I’m not planing it rn), but I hope to get this to a 20-30 fps range.

it could possibly be used for generating a static background scene for a game like Dark & Under or something a bit like the original MYST.

I wasn’t considering that, but this is actually a very nice idea. With per-pixel evaluation and a tiny rolling buffer, it could generate a high quality dither image.

6 Likes

Great works rapso. Good luck i hope you’ll success, it’s could have alot of interests

1 Like

This is really cool!

If it is going to be in motion with ordered dither, I have found that you can pretty much get away with running at quarter resolution without really noticing the resolution drop.

Have a look at the GIF I posted in my flight sim demo thread to see what I mean.

Everyone keeps asking me if the nano runs doom, @rapso if you want to put a flag for a 64x32 resolution output I’ll make it worth your while! :slight_smile:

Isn’t everyone rather asking you when ArduBoy Advance gonna be out? :wink:

A tiny update: I have the ray tracer running at 210ms at the slowest place in the tiny demo map, up to 20ms if you face the wall. I had to cut a few optimizations as I ran out of progmem and “dynamic memory” a few times.
I will polish it over the weekend (trying out some control variations, timing output on-screen, maybe some bobbing)

You mean Arduboy XL? Well, I’d like to actually ship the Arduboy FX first… but also still have plenty more work on the design for the XL, but I did recently get the link cable working. Main thing left to do is how to manage the power switching between batteries and USB and have the power switch isolate everything so there is no current draw when switched off. Also the mechanicals for the OLED module that is commonly available is different than the one I tested with, so I need to make some changes to the pcb layout… “When it’s done” but probably at the middle to end of the year.

the company I work for allowed me to release my tiny ray tracer, I’ve attached it to the first post, have fun :slight_smile:

2 Likes

So cool! Thanks for sharing @rapso !

WOW too cool! I think technically without any bouces it’s ray casting, ray tracing is recursive, but whatever, it’s amazing.

@raspo, is it using floating or fixed point? Floating point is gonna slow that down as hell without HW support. I have a raytracing library planned that would be friendly to embedded in which I’ll only use integers (I’ve already made a rasterizer in a similar manner).

Typically these ray tracing/casting demos use shapes like spheres and cylinders as these are fastest to trace against, I was expecting to see that here. A 3D mesh composed of quads/triangles is going to be pretty slow. I’m actually impressed it even works at 2 fps :slight_smile: These checkerboards are “procedural textures” or are they multiple quads (computing texture coords may eat additional cycles, not sure which way would be better)? What is the scene representation? Is is just a list of quads or is it maybe a voxel representation? I think I’m seeing angled walls there?

A source code would be great :slight_smile:

Yeah, thanks for making this.

I think technically without any bouces it’s ray casting, ray tracing is recursive, but whatever, it’s amazing.

ray tracing is just the shallow high level term, there is no real limit of bounces or ray queries. When you say “ray casting” most people will think of a wolfenstein engine, hence to avoid confusion whether this is really ray traces per pixel, “ray tracing” is a more fitting term imho.(And it still caused confusion here :slight_smile: )

is it using floating or fixed point?

it’s fixed point; I would not recommend to use emulated floats on the Arduboy CPU. Your rasterizer looks like a nice start. I’d love to see it running 60FPS. I’ve also written “some” rasterizers, my most recent was Wipeout on GBA - YouTube

I have a raytracing library planned that would be friendly to embedded in which I’ll only use integers

I hope you’ll make an Arduboy ray tracing demo as well, would love to see how well it performs and looks!

Typically these ray tracing/casting demos use shapes like spheres and cylinders as these are fastest to trace against, I was expecting to see that here. A 3D mesh composed of quads/triangles is going to be pretty slow. I’m actually impressed it even works at 2 fps

Sorry, that was just the first implementation back in February, I’ve updated the description. It’s now rather 8 FPS to 60 FPS, depends heavily on how much you need to ray trace; tracing across the room gonna take longer than when you’re close to a wall. (try it out in the emulator, it’s quite accurate)

These checkerboards are “procedural textures” or are they multiple quads (computing texture coords may eat additional cycles, not sure which way would be better)?

These are dither patterns to represent some color brightness per surface, it’s similar to what James uses in his flight simulator rasterizer: Flight simulator
and his catacombs ray caster Catacombs of the damned! (Formerly Another FPS style 3D demo)
I have 5 levels in 2x2 pixel patterns (from all pixels black to all pixels white), but the tracing is still full 128x64 !
It’s a lovely flash back to when I had a monochrome monitor on my 8086 :slight_smile:

What is the scene representation? Is is just a list of quads or is it maybe a voxel representation? I think I’m seeing angled walls there?

As an homage to Descent, I’ve tried to recreate the same way of level editing and freedom it offered.

A source code would be great

It took me already months talking to legal of Activision to just get this permission, I won’t stretch this :sweat_smile:

Yeah, thanks for making this.

thanks, I’m happy you like it. I hope it motivates everyone to believe in the crazy solutions. (And maybe bateske to release an ArduBoy advance, then I’ll add one more bounce :smiley: )

4 Likes