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.
https://www.youtube.com/shorts/G_K_Xrac5GI?feature=share

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