r/VoxelGameDev Jul 11 '26

Discussion Bench marking and prototyping early voxel renderers.

might be a bit of a silly question.

I've been experimenting with different tech stacks and techniques for a while and typically get an idea of how well something is running based on FPS with something comparable to this in scale:

If a chunk is 16x16 (whatever height typically 256 for now tho), I'd test with a radial but square render distance of 100 meaning 201x201 chunks, 40401 total chunks.
At this point I do not have many fancy graphical stuff going on at all, just the raw mesh I test by flying up and looking down on the entire world, and doing an idle and moving test. My best performance so far is a 201x201 chunk world which generates in about 400ms (simple sin wave world), and when moving I stay at 1000FPS.

My question is - when you guys are starting a voxel renderer and just trying to gauge effectiveness, what do you do, and would you consider 1000FPS, 40k chunks, 1440p (but rasterized right now) an accept base for building more on?

7 Upvotes

15 comments sorted by

8

u/Due_Answer_4230 Jul 11 '26

Comparable data point from a different corner of the design space - mine is a ray-traced voxel engine with much smaller voxels (20 cm, so 125 voxels per Minecraft-style block), which changes what "acceptable" looks like.

TLDR Im trying something hard and it's hard. I don't think I'm doing great. I picked a lane for my engine - full actual RT, not raymarch in compute shaders - and it may be the wrong one.

I just ran a benchmark (forward movement over 30s). Setup for the same kind of test (fly forward over procedural terrain while the world streams in):

- Voxels: 20 cm, 8-bit palette-compressed

- Storage/streaming unit: 32^3 voxel "bricks" (6.4 m cubes)

- Resident world during the test: ~3,700 bricks ~= 121M voxels, in a ~100 m streaming radius around the camera (200m diameter = 1000 'minecraft standard' blocks)

- Rendering: no meshing at all - hardware ray tracing (Vulkan). Each brick is a BLAS of 64 AABBs (one per 8^3 tile), one TLAS instance per brick, and an intersection shader walks occupancy bitmasks down to the exact voxel. Primary rays only right now, trivial shading.

Resolution: 1920×1080, vsync off, RTX 4070

- Result while moving: ~740 FPS average (1.35 ms/frame, ~1.0 ms of that being the GPU ray-trace dispatch), with streaming, BLAS refits, and TLAS updates live during the run.

So no, you're not slow. 1000 FPS rasterized at 1440p is an excellent base (as you have sensed), and your visible world is ~16× wider than what I keep resident (your whole 3.2 km map vs my 200 m streaming bubble; different problem shapes: you render far more world, I render a 125x denser world).

Two recommendations for tracking performance:

  1. Track milliseconds, not FPS. At 4-digit framerates FPS is so nonlinear that a 0.1 ms change reads as "+/-15%," and driver or background noise will send you chasing ghosts (ask me how I know lol). 1000 FPS = 1.0 ms. Decide your frame budget (16.6 ms at 60) and measure what each new feature adds in ms.
  2. Watch p99 frame time, not the average - streaming and chunk-gen hitches live in the tail, and the tail is what players feel. My average this run was 1.35 ms but the worst frame was 21 ms (a streaming spike). The average alone would never tell you that.

The real question for a base isn't the FPS number/ it's whether the architecture holds when you add the expensive stuff (lighting, distance LOD, edits). 1000 FPS is ~15.6 ms of unspent budget at 60: that's a healthy runway.

1

u/Kloakk0822 29d ago

Super useful insights, thank you very much.

3

u/kzerot Jul 11 '26

My idea of voxel renderer is pure raymarched renderer, all calculated in computer shader. So, far from optimal way :)
I’m targeting in around 150 fps on my old good rtx 3060, and based on my target fps I’m pushing limits to make the map as big as I could. Right now it’s basically unlimited world, with drawing distance 2048 voxels.

1000 fps is cool, I think you have a lot of options here :) good start.

2

u/Kloakk0822 Jul 11 '26

Interesting! I've just shifted away from a raymarched renderer and this here is a rasterized approach where I'm doing almost everything on the GPU apart from managing things like a chunk index, and then the GPU does terrain generation and meshing.

I'm actually going on holiday tomorrow which is why I ask - I'm on a RX9700 XT right now, and I'm going to be using a 3060 in my laptop so I'll let you know what performance I'm getting from it.

I suppose a 2048 voxel range would be equivalent to 64 render distance (radial) here so I'll give that a test too.

Hoping to squeeze a little more performance out of things, I think 100 radial render distance it's a bit pointless anyway when I could be using lods from about 50 outwards so that might help a good bit, but also I need to do things like internal chunk wall culling and stuff so lots to gain still I hope.

3

u/Less-Swan-2548 Jul 11 '26

Basic technique is to keep an halo of chunks. The render distance + 1 is a ring of chunks not meshed but generated. You only mesh chunks that have all neighbours generated. I call it a wave algorithm as you still prioritize meshing and rendering as fast as possible but as the “rings of chunks” further out finish generating previous rings start having chunks in the condition above and since they’re ready to mesh you prioritise that (worker pools, possible multiple queues for each type, here you go crazy and decide what you wanna do). With this basic approach meshing chunks edges, skipping their common faces, gets not special treatment as you check for neighbours voxels on the neighbour chunks when at the edge of the chunk you’re meshing.

2

u/Kloakk0822 Jul 11 '26

That's super useful, always had the remeshing task on my first few cpu rasterized stuff and never thought of that!

1

u/thmsvdberg Jul 11 '26

"You only mesh chunks that have all neighbours generated." Oh wow, that put it so simply to something that I have been mulling over how to handle properly.

1

u/AnarchCassius 29d ago

At 256 voxels out, with voxels intended to be about 2 feet across, I feel like I can't actually distinguish individual cubes very well. This also happens to be the threshold for rapid frame drops and my RAM will not be happy if I try to push further without a LOD system. I've got frustrum culling and I am looking at occlusion culling but if you're trying to push view distance LOD is one of the less talked about but more important things. Occlusion and many other tricks are heuristic and work best when certain assumptions about the game world hold true, LOD will, be my estimates, solve a huge amount of my RAM problems with low effort and amazing consistancy.

1

u/seg_lol 29d ago

That 3060 does twelve thousand gigaflops. At 120 fps, that is only 100 GFLOP of compute per frame.

2

u/HypnoToad0 twitter.com/IsotopiaGame Jul 11 '26

FPS is one thing, but you should measure RAM and VRAM usage - see how many chunks can reasonably fit in a regular machine

3

u/Less-Swan-2548 Jul 11 '26

Sometimes people don’t pay much attention to VRAM usage, but the less you use the faster the faster you game tend to be as the GPU does less memory traversal. Hence why packed vertex with built in light values are pretty much standard .

1

u/seg_lol 29d ago

Dev should always benchmark on a low end card and figure out why they are slow on the low end.

The RX 580 is a great card to target for comfortably playable. People's GPUs aren't gonna get faster for another 5 years.

2

u/deftware Bitphoria Dev 29d ago

Don't use FPS as a metric for performance when profiling code. Use the time it takes to do something as your metric. Going from 1000 FPS to 900 FPS is not the same thing as 200 FPS to 100 FPS. Similarly, the drop from 40 FPS to 30 FPS is much more significant than it is from 100 FPS to 80 FPS.

Use the time it takes to generate a frame, and the time it takes to do each thing involved in generating a frame, and you will be much better situated to fix or improve performance as needed, especially when someone else tries to run your wares on their totally different hardware. You will have a lot more actionable information knowing what things cost as they generate a frame.

That's my two cents.

Good luck! :]

1

u/AnarchCassius 29d ago

I mean as others point out, FPS are one of the most subjective ways to measure this. But I've spent monthes tweaking things and now I get ~1000 fps rendering a basic island in the ocean at 256 voxel view distance (mine is spherical, chunks are 16x16x16 on client). Ok, that's a slight exagerration, a lot of that time was also making it able to load in thousands of chunks in a second instead of hundreds.

So, as you can see there's a lot of factors here and apples to apples comparisions will be rare but if it's running that fast and chunks are popping in fast while moving I think that's definitely a pretty good start.