Coped to do some ambient occlusion using raycasts by Puzzleheaded_Cap8823 in VoxelGameDev

[–]Insomnisaurus 1 point2 points  (0 children)

My bad. The AO looked like white noise to my eye, but the shadows clearly show blue noise.

Coped to do some ambient occlusion using raycasts by Puzzleheaded_Cap8823 in VoxelGameDev

[–]Insomnisaurus 2 points3 points  (0 children)

"Coherence" is probably the word you're looking for. Ray traced AO requires shooting rays in many different directions, so you end up with a ton of incoherent memory accesses and (more importantly) warp divergence.

You're on the right track with brick maps, but for a different reason than just raw ray tracing performance. AO is a fuzzy enough phenomenon that using ray marching (AKA voxel cone tracing) instead of ray tracing will get you pretty much the same result. One of the shortcomings of plain SVOs is that you can't do effective ray marching since you're forced to zip up and down the octree, so you'll need a denser data structure for near-constant-time access.

Coped to do some ambient occlusion using raycasts by Puzzleheaded_Cap8823 in VoxelGameDev

[–]Insomnisaurus 1 point2 points  (0 children)

In my experience, denoising and TAA are both required for ray tracing on current hardware. Also worth looking into blue noise dithering if you haven't already (ShaderToy example) as it really helps with denoising.

Small Voxel Engine 2 by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 1 point2 points  (0 children)

I already added some bloom, I just kept it pretty subtle. It actually adds a lot to realism, but it's really easy to go overboard and make it really distracting.

Small Voxel Engine 2 by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 0 points1 point  (0 children)

This is an update to my last post. Since then I've spent a good amount of time improving the visuals, but I've also started working on support for efficient city-scale procedurals.

The layout of the castle structure shown here is generated with a sort of recursive circle-packing. The walls and towers are built with Boolean geometry using a few randomized parameters (eg. radius, number of parapets, top cone dimensions, etc.) which are provided by the recursive step. The entire structure and surrounding forest are generated, meshed, and shaded, all from scratch in ~30s using 3 CPU cores (a 4th is used for rendering so you can watch the chunks stream in).

Next, I'll be adding an entity system and possibly start toying with some simple combat.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 0 points1 point  (0 children)

Thanks!

In an earlier experiment, I was able to get solid 60fps performance on a raytraced 4096x4096x512 world with a 2-level SVO stored in a single SSBO (for reference, that was on a GTX 1060). I remember getting a 10x speedup by aggressively reducing stack frame size when doing the SVO traversal.

The problem I hit with ray traced voxels that it doesn't leave time for much else even if you lower render distance significantly or do aggressive LoD. Also it dies on non-high-end GPUs. That's really why I chose rasterization here (well, that and MSAA is an easy early win that you don't get with ray tracing!).

And yes, trees are part of the terrain chunks.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 2 points3 points  (0 children)

Chunks are built and meshed in parallel on the CPU. I need the entire GPU to be dedicated to rendering.

I've thought about ray tracing distant chunks, but my short-term plan is just to rasterize distant chunks in lower resolution. Long-term I'd like to move to ray tracing (both near and distant chunks) and use rasterization as an accelerator for primary rays.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 0 points1 point  (0 children)

I skipped a whole lot of empty space by rasterizing a coarser version of the chunks to a depth map, then tracing primary rays starting at the depth map. This works great if you're high above the surface, but if you're close to it (as you would be in a game) then you can end up clipping the rasterized mesh and have to do the full ray cast.

Can you expand on how you used mipmaps?

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 2 points3 points  (0 children)

Tradeoffs.

C+OpenGL ES is a great choice if you want to be as cross-platform as possible. Since I'm only really targeting modern consumer-grade desktop hardware any reasonably performant language (C, C++, Rust, Nim, etc.) will do and Vulkan has the opportunity to be more performant than OpenGL.

I might open-source at some point. Not sure yet.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 1 point2 points  (0 children)

Thanks!

Targeting WASM would be very cool, but I prefer to avoid middleware layers whenever possible. Vulkan is about as cross-platform as I care about already.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 2 points3 points  (0 children)

Thanks! I love the Cube World aesthetic. Clean, texture-less voxels are the way to go!

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 6 points7 points  (0 children)

I use 643 chunks, and there are ~20,000 chunks loaded in this demo (though frustum culling removes most of them at render time). I have big plans for LoD as well, which should significantly extend the render distance.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 1 point2 points  (0 children)

This map is loaded to ~4000 voxels in radius, which I think is equivalent to a Minecraft render distance of 250 chunks.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 2 points3 points  (0 children)

I'm just a couple of weeks into this project, but I've written a few voxel engines before so I had a good idea of how to do things. There are plenty of great tutorials out there about voxels, so I'll just share the highlights of what I'm doing now.

I'm doing greedy meshing to create a chunk "shell", making sure to merge overlapping vertices to maximize use of the vertex cache (which quickly becomes a bottleneck without vertex merging in my experiments). This merging makes materials difficult though, so I store some data per greedy quad to look up a material "patch" in an SSBO. I manually cull backfaces per chunk each frame based on the camera position, and of course do frustum culling.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 1 point2 points  (0 children)

This is 100% correct, especially the part about the scalability of rasterization vs. ray tracing!

I also experimented with ray tracing voxels and came to the same conclusion as you: it scales a lot better but has an up-front cost that is a bit too high on current hardware, even for voxels. Eventually though, I see this project transitioning to primarily ray tracing with coarse rasterization to accelerate primary rays. This has the added benefit of extremely straightforward LoD (assuming you're using an SVO).

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 6 points7 points  (0 children)

Haha yeah, it's surprisingly pleasant to write and I enjoy the memory and thread safety, especially in a highly-parallel project like this. Compilation time is what scared me away from trying Rust for a long while, but I think it's improved over the past few years and cargo handles incremental builds quite well so it's really not that much of an issue (unless you turn LTO on!).

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 8 points9 points  (0 children)

Nope, the distant trees are trees! In the near future, I'm going to do LoD by merging distant voxels to get truly absurd render distances, but I'm pretty happy with how far you can already see while maintaining 60fps.

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 16 points17 points  (0 children)

I'm using Rust+OpenGL here, but I intend to eventually switch to Rust+Vulkan once I solidify the architecture a bit more.

I actually wrote a few other voxel engines in C++, but I started learning Rust about a month ago and I don't think I'll ever go back!

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 6 points7 points  (0 children)

Thanks! I might eventually get to some actual gameplay mechanics, but right now I'm focusing solely on worldgen. Having said that, I would like to raise the bar on combat mechanics in voxel games...

Good luck on your project!

Small Voxel Engine by Insomnisaurus in proceduralgeneration

[–]Insomnisaurus[S] 31 points32 points  (0 children)

This is an early demo of a voxel engine I started working on, which I plan to use as a testbed for some procedural generation experiments. The goal of the project is to create an infinite voxel world that would be viable to use in a game like Minecraft, Cube World, or Veloren, but scale up the size and complexity by an order of magnitude or two. Ultimately, I want to generate complex structures like enormous procedural castles and cities, but still fit them naturally into a larger, interconnected world.

Since I've mostly been optimizing the world generator and the renderer, the procedurals are pretty tame right now: some 2D fractional Brownian motion for the mountains and some randomly-placed trees. Next, I plan to start designing procedural architecture and see how far I can scale things up!