3d landscape proof of concept - Download and source now included!

Update:
Source and binary available here GitHub - webmobster/voxelspaceplaydate: Playdate implementation of the Voxel Space Algorithm

Original:
Threw this together over the bank holiday weekend. Based on GitHub - s-macke/VoxelSpace: Terrain rendering algorithm in less than 20 lines of code. Still horribly unoptimized, so hopefully can see some reasonable speed improvements. Written in Rust using crankstart.
3d Voxel Space Proof of Concept for Playdate - YouTube

5 Likes

I’m working on the same concept in C, with some optimizations like lowering the resolution far away I got pretty good performances. So it’s definitely doable.

1 Like

Nice, would be interested in seeing the final product :slightly_smiling_face:.
I have managed to do some optimizations on mine to get a pretty stable 20fps. In debugging performance issues (buffer/array access expensive :grimacing:) I suspect the very minimal cpu caches are most of the pain here, as it just chews through most of the actual maths.

4 Likes

20fps is already good.

I got 40fps+ drawing from front to back (you need a secondary buffer to save the height as mentioned on GitHub), also you can pack the depth and color into a single value to minimize array access.

While prototyping, I noticed that the front to back approach was pretty limited since it doesn't allow to add sprites, so I switched to "back to front" but it's quite slow.

2 Likes

Wow 40fps, that's impressive, would be interested in any tips/tricks.
So I already am:

  1. Packing 4 vars into a single u32 (2 colours, 2 altitudes) as keeping the cache lines cleaner seemed to improve fps even if it requires more shifts and bit masks. And playdate does 32 bit load/stores anyway if you look at the assembly generated.
  2. I was already using back to front with a depth buffer, but seeing as the cpu seems to be fine at maths and slow at data loads/stores I inverted my loops so that we do the z-buffer for each column rather than the vice versa. This does increase the FP maths quite a bit, but allowed me to remove the y buffer which helped fps, as you can just use a single var. (credit for the idea to a HN discussion from 2021 Voxel Space: Comanche's terrain rendering in less than 20 lines of code (2020) | Hacker News)
  3. I render at 1/2 resolution but do the dithering at the full playdate screen resolution (as it looks better this way).
  4. Removed all intermediate buffers (used to have a framebuffer which was then passed to the dither and screen writing method), now I just directly dither and write to the screen in the main loop.
  5. Rust specific: Used unsafe array access almost everywhere to avoid bounds checks.
  6. Increased the z delta a tiny bit (too high and things look broken quickly). Probably can do quite a bit of tweaking here as I don't think a linear increase in the z delta is optimal.

I hope to be able to open source the code for it soon, once I do would appreciate feedback.

Source now available!

You can also find a pre-compiled version in the repo.

2 Likes