At first, I saw a demo where a student implement a voxelspace algorithm with compute shaders. Voxelspace is a tech invented in the '90s by Kyle Freeman at Novalogic to render landscape. Games like Comanche, Deltaforce used it. It was based on heightmap and voxels, not polygon. I don't know much about shaders, but I know it is better at rendering polygons. So... I try to understand how all this work and here is the result: my voxelspace implementation on Pico 8
With freds72 optimization
first release
Here is an implementation of voxelspace rendering algorithm, with a little perlin noise map generation. Features :
- Generate a 128x128 height map in memory,
- Generate a color map base on height with some noise (I could also use height difference to better show cliffs and flat grounds, maybe latter),
- colors fadding with distance
- We can move, with player one controls, zoom map with X (or M), strafe with player 2 left and right (s,f)
I don't know where it will go, or if it will become a game, but here is my work :D Have fun tweaking or exploring !
for a more advance experience, you can check electricgryphon work https://www.lexaloffle.com/bbs/?uid=10844
Works very well with the new colors!
Minor perf tips:
- reuse the yb array (avoid GC)
- use shl instead of x width
- move cos/sin calc out of the column loop
(at the very least, avoid calculating them twice!) - sx/sy are used only once in the inner loop, it is faster to use rxdx/rxdy
Thanks ! Thanks for the tips, too ! I tried them and it saves 8% more cpu, with shl for the most. That allow distance to be pushed to 50 instead of 44 with same quality.
I got down to 0.6863 cpu at startup pos :]
Minor perf tips +
- band(xxx,0x3fff) is useless for numbers in 0-0x7f range
- bor(x,y) is faster than x+y when you don't want carry
Well done ! The bor trick work well in this case, as Y will never walk on X bits :)
I don't get what you want to say with "band(xxx,0x3fff) is for numbers in 0-0x7f range"
I use band(xxx,0x7f) to keep integers in 0-127 range and band(xxx,0x3fff) in 0-16383
So the expression I started from
local idx= (flr(sx)%width +(flr(sy)%width) *width)%hlen |
became (because width=128, and hlen=128*128),
local idx= band( (band(sx,0x7f) +(band(sy,0x7f))*width), 0x3fff) |
and now with your tips:
local idx= bor(band(sx,0x7f), shl(band(sy,0x7f),7)) |
In this case, that's crazy fast !
edit: fix 3rd step :)
My last word: 0.6535 :]
Previous perf tips +
- simplified cos/sin formula (see: https://www.maths-france.fr/MathSup/Cours/FormulaireTrigo.pdf)
- replaced yb array by 0x4300 and peek/poke (did not fully bench but memset is faster than for i=0,127 do...)
I tried to use yb on 0x4300 user memory, but it was not faster, and I got a strange behaviour with negative values, but I obviously have missed something :D
Thanks a lot for digging !
EDIT : you have the same issue, maybe a poke4 could help
[Please log in to post a comment]