- VoxelRay - Blocky voxel raymarcher for the TI-84+CE
- 24 Feb 2021 05:01:35 am Permalink
- Last edited by mid on 26 Feb 2021 07:54:11 am; edited 1 time in total
This is a raymarching renderer that marches through one 40x40x40 voxel space written in Assembly. I chose that chunk size because 40 is the largest number, the cube of which is less than the max size of an appvar (one byte for each block).
It fakes a resolution of 80x60 as that would be 16 times less rays to render than in 320x240.
You can move forward, backward, left, right, up, down. You cannot yet rotate. The long delay you see at launch is it calculating each ray position and direction. That is very slow due to the complexity of the formulas being evaluated and I'm not sure of a way to optimize it.
The raymarcher is very inaccurate as well for speed's sake. It uses a form of sphere tracing, but distances are whole numbers, so rays often jump too far.
The reason that is is that the signed distance field (the function that returns the signed distance from any point to the surface of the shape) is encoded in the appvar itself as bytes. I had thought to maybe store half units instead of whole units to approximate better, but decided not to due to the lack of simple long bitshifting on the ez80.
You'll see an extreme case of this inaccuracy when you put the camera close enough to the shape. You get some fisheye distortion effect. Here's a thin straight line as the chunk and the camera pointing toward it. Depending on the angle, the rays may jump too far ahead, over the blocks, thus not hit them, making it look like the line is bent:
Calculating the signed distance field is not very fast either on my i7 Skylake. If you limit the max SDF distance to ~11 units, the chunk generator script takes 2m14s. For this reason I might not add a way to edit the world on the calculator itself (this means no 3D Minecraft clone, very sorry).
Other than that the actual rendering function is relatively quick. It takes around 0.8 seconds to render a full frame at first and slows down as more rays start to hit nothing (because those take up all of the raymarching iterations before hitting the limit). This is as fast as I could make it.
I plan on putting up the source online very soon, once I clean it up.