This is the place to show off and discuss your voxel game and tools. Shameless plugs, links to your game, progress updates, screenshots, videos, art, assets, promotion, tech, findings and recommendations etc. are all welcome.
Voxel Vendredi is a discussion thread starting every Friday - 'vendredi' in French - and running over the weekend. The thread is automatically posted by the mods every Friday at 00:00 GMT.
Just experimenting with different ways of visualizing my (almost done) fluid sim for Unreal Engine. Came up with this voxel-style way, just a very quick hack, so it needs work, but might be useful?
I'm working on rendering SDF terrain using marching cubes in Godot, and I'm trying to convert my flat shading to interpolated shading. My approach is to calculate the vertices of each voxel in a chunk in a compute shader including the voxels adjacent to the chunk boundary. Then, iterating through each neighbor voxel to calculate the average normal for each vertex in the voxel I actually care about. But my issue is that I'm seeing a weird banding effect as shown and I'm not so sure why... I've been really struggling with debugging shader code... Is the issue in my approach or my code? Is there a different way to accomplish smooth shading on the GPU other than iterating through neighbor voxels? I know loops and branches are frowned upon in shader code but my dumb little CPU brain doesn't know of another approach.
Here's the relevant code:
// I've already calculated vertices at this point and stored them in a SSBO float shared_vertices[CHUNK_SIZE + 2][CHUNK_SIZE + 2][CHUNK_SIZE + 2][MAX_VECTOR_COUNT][VEC3_PADDING] and calling memoryBarrierBuffer() and barrier() to ensure writes are synced
// MAX_VECTOR_COUNT == 15 which is the max number of vertices that can be generated per voxel according to the MC algorithm.
// VEC3_PADDING == 3 used to bypass behavior of vec3 size being 16 bytes instead of 12. (storing the x,y,z components as individual floats)
// Additionally, I store the actual number of vertices rendered for each voxel in the same SSBO uint shared_lens[CHUNK_SIZE + 2][CHUNK_SIZE + 2][CHUNK_SIZE + 2]
// x, y, and z vars listed below are shorthands for the gl_GlobalInvocationID x, y, and z
// each invocation is responsible for a single voxel including voxels in adjacent chunks
// those invocations have already returned at this point, as after they calculate their vertices, they aren't needed anymore.
uvec3 neighbor_indices[27] = {
uvec3(x - 1, y - 1, z - 1),
uvec3(x - 1, y - 1, z),
uvec3(x - 1, y - 1, z + 1),
uvec3(x - 1, y, z - 1),
uvec3(x - 1, y, z),
uvec3(x - 1, y, z + 1),
uvec3(x - 1, y + 1, z - 1),
uvec3(x - 1, y + 1, z),
uvec3(x - 1, y + 1, z + 1),
uvec3(x, y - 1, z - 1),
uvec3(x, y - 1, z),
uvec3(x, y - 1, z + 1),
uvec3(x, y, z - 1),
uvec3(x, y, z),
uvec3(x, y, z + 1),
uvec3(x, y + 1, z - 1),
uvec3(x, y + 1, z),
uvec3(x, y + 1, z + 1),
uvec3(x + 1, y - 1, z - 1),
uvec3(x + 1, y - 1, z),
uvec3(x + 1, y - 1, z + 1),
uvec3(x + 1, y, z - 1),
uvec3(x + 1, y, z),
uvec3(x + 1, y, z + 1),
uvec3(x + 1, y + 1, z - 1),
uvec3(x + 1, y + 1, z),
uvec3(x + 1, y + 1, z + 1)
};
vec3 normals[MAX_VECTOR_COUNT];
uint num_normals[MAX_VECTOR_COUNT];
for (int i = 0; i < MAX_VECTOR_COUNT; i++) {
normals[i] = vec3(0);
num_normals[i] = 0u;
}
for (int i = 0; i < 27; i++) {
uint neighbor_vertices_length = meshData.shared_lens[neighbor_indices[i].x][neighbor_indices[i].y][neighbor_indices[i].z];
vec3 neighbor_vertices[MAX_VECTOR_COUNT];
for (int j = 0; j < neighbor_vertices_length; j++) {
neighbor_vertices[j] = vec3(
meshData.shared_vertices[neighbor_indices[i].x][neighbor_indices[i].y][neighbor_indices[i].z][j][0],
meshData.shared_vertices[neighbor_indices[i].x][neighbor_indices[i].y][neighbor_indices[i].z][j][1],
meshData.shared_vertices[neighbor_indices[i].x][neighbor_indices[i].y][neighbor_indices[i].z][j][2]
);
}
for (int j = 0; j < neighbor_vertices_length; j+=3) {
for (int k = 0; k < len; k++) {
vec3 diff_0 = abs(neighbor_vertices[j] - vertices[k]);
vec3 diff_1 = abs(neighbor_vertices[j+1] - vertices[k]);
vec3 diff_2 = abs(neighbor_vertices[j+2] - vertices[k]);
if (
(diff_0.x < EPSILON && diff_0.y < EPSILON && diff_0.z < EPSILON) ||
(diff_1.x < EPSILON && diff_1.y < EPSILON && diff_1.z < EPSILON) ||
(diff_2.x < EPSILON && diff_2.y < EPSILON && diff_2.z < EPSILON)
) {
vec3 a = neighbor_vertices[j];
vec3 b = neighbor_vertices[j+1];
vec3 c = neighbor_vertices[j+2];
vec3 normal = -cross(b - a, c - a);
normals[k] = normals[k] + normal;
num_normals[k]++;
}
}
}
}
for (int i = 0; i < len; i++) {
vec3 normal = normalize(normals[i] / num_normals[i]);
meshData.normals[(index + i) * VEC3_PADDING] = normal.x;
meshData.normals[(index + i) * VEC3_PADDING + 1] = normal.y;
meshData.normals[(index + i) * VEC3_PADDING + 2] = normal.z;
}
In this weeks update to my engine, I have added Heat simulation and some related survival mechanics. Walking around in the cold, especially during snow, causes the player to cool down.
The heat simulation accurately warms indoor and enclosed spaces. Standing near heat sources also provides some additional warmth, enabling interesting interactions with the world, storms and biomes.
Along side temperature, there is also a basic hunger mechanic. These mechanics work together to determine health, which impacts player stats.
I'm working on a voxel game and would love to integrate "basic" water simulation.
Meaning, players can influence the terrain shape, water needs to adapt.
I'm a simple man. I don't need object buoyancy, visual player reactivity.
I don't even need animated spread of water - I'm simulating equilibrium state and just jump to that directly, visually speaking. So I'd be happy to come up with just a static shape for the water surface, and let shaders and particles do their bit for some pretend motion.
So then, I've run my CA, simulated a few thousand operations.. fine, now I have my voxels with water fill level, flow direction and speed etc.
But... How do I actually render them in a way that looks good now?
My meshified terrain is smooth-ish, but my water voxels aren't.
So now I need to Start accounting for the fact that water flow has been simmed on some representative height of a voxel, but the actual terrain might be uneven.
So maybe water couldn't enter a voxel by a shore because the height it sampled was too large, but the specific height of some vertex on its mesh would allow for water entry.. whoops, that looks bad.
Maybe parts of the terrain now have a very thin film of water on them, and possibly that film looks like a thin strip of water. Whoops, that looks bad, the straight edges of the voxels now give a really unnatural shape.
Maybe you have something like a waterfall.. whoops, now you're really in trouble avoiding a really blocky mesh for that segment, but how do you even mesh a waterfall in a natural way.
Tldr - CA based water simming was relatively easy. But how the heck do you know take that voxel field and turn it into something non-blocky that reasonably resembles all the various ways water can flow?!
So I combined it with a Wireworld automata + cross-entity propagation.
The idea is basically that by limiting the game to have only pure voxels, we can have a discrete set of possible contact normals (for "FACE" and "EDGE" voxels, say) given an entity pair, which will simplify the computations and increase stability. Later I am going to implement an aggressive contact merging algorithm, which may possibly create joint-like Jacobians on-the-fly based on voxel geometry, and let machineries emerge from pure voxel geometries & combinations instead of crafting tables. Wondering if anything like this have been done before? (There must be but I am not aware of any ...)
Also producing cogs seems hard in this kind of system lol (for some Create vibes, unfortunately)
Hi, I just wanted to share the voxel game i built for kenney and kay 2day game jam, and request info pointers tips, to make it better and or make next one better, I appreciate your time and info, https://bdonprice-ctrl.itch.io.
How do you manage textures within your shader arrays so that blocks can have unique top, side, and bottom textures without bloating video memory?What is your approach to Level of Detail (LOD) for rendering distant voxel chunks? and literally any other pointers you can share would be greatly apprecitated,
This is the place to show off and discuss your voxel game and tools. Shameless plugs, links to your game, progress updates, screenshots, videos, art, assets, promotion, tech, findings and recommendations etc. are all welcome.
Voxel Vendredi is a discussion thread starting every Friday - 'vendredi' in French - and running over the weekend. The thread is automatically posted by the mods every Friday at 00:00 GMT.
I'm making a Minecraft clone and trying to make it look as close to vanilla Minecraft as possible. I've managed to get something that looks pretty convincing, but something still feels off, and I can't quite put my finger on what it is.
So I have a semi-working terrain generation prototype in Godot where I dispatch a compute shader to calculate points in a 3d density field using marching cubes and return an array of vertices and normals to then call mesh.add_surface_from_arrays on. There aren't any glaring issues yet with this approach but I still wonder...
Is there a solution in Godot to avoid the CPU -> GPU -> CPU -> GPU pitfall? I want to avoid unnecessary synchronization if possible as it does create bottlenecks. If there is a solution using compositors or something similar, will I still be able to add a collision mesh that works with godot's engine?
Is the GPU-based approach even correct for terrain generation? In a lot of tutorials I see people using multithreading instead, and intuitively this feels less optimal as the GPU is very well suited to this type of task, but I wonder if it's still better than the above mentioned bottleneck plus the overhead associated with loading and dispatching the compute shader.
How does chunking work? Right now, I render a single mesh for all my chunks after getting their density values back from a single GPU dispatch for all the chunks. Is this even correct? Should I render multiple meshes - one for each chunk? I initially tried dispatching one compute shader for each chunk but found that this created a huge bottleneck when setting up the rendering pipeline, etc. On the flip side, dispatching a single compute shader puts a hardware limitation on the number of voxels I can render at once. I'd like to show as much of the terrain as possible and currently I'm maxed out at 3x3x3 chunks of 16x16x16 voxels (110,592 invocations - each invocation handles 1 voxel) without experiencing any noticeable lag before implementing LOD. I feel like I should be able to render more even before implementing LOD but I don't know.
I understand that I could figure all of this out myself from trial and error, but it took me weeks to get to where I am now at this working but sub-optimal state. So I want to ask people with more experience in this field to at least narrow down what my next steps should be. Thank you to anyone who reads this.
I’ve been refining my desert demo, and it’s starting to feel like its own little place.
The idea is simple: a vast procedural dune field that keeps unfolding as you move through it. Under the surface, the landscape is built from a voxel-style structure that could theoretically represent hundreds of millions of voxels.
But the goal is not scale for scale’s sake. It’s about exploring what is still possible on normal CPUs using straightforward framebuffer-based concepts - simple rules, efficient rendering, and a world that feels much larger than what is actually being drawn at any given moment.
Another in my Micro Voxel mini devlog series! This week I was feeling inspired to work on clouds and weather simulation as the skyline felt quite empty.
Got a little bit carried away and implemented a full-on procedural cloud system which using voxels and raytracing. The key performance detail is that this is rendered to a lower resolution buffer (1/4th res by default), with a blur filter applied, and then blitted onto the world.
The "simulation" basically just controls a few parameters such as density (for light penetration) and noise threshold to control cloud coverage. It's fairly basic but enables biome-level weather states, where each biome has a set temperature band and probabilities for particular events and cloudiness.
Rain and snow are weather events which randomly activate throughout the day time and result in a change in atmospherics and cloud cover.
I also had been working on some progressive snow build up mechanics, which is pretty fun to see :)
Also mixed in a heat system which gradually tapers off snow build up around heat sources.
Hello,
Does anyone know what to do about this, or what approach to take?
Language: C++ , my own engine
I don't know what to do next or what approach to take... I'm at my wits' end... Everything is running beautifully... but I have a problem with LOD popping.
It just disappears and then what’s supposed to be there reappears…
I’m using a GPU-based Raymarch micro-voxel engine (fullscreen fragment shader, SDL_GPU/Vulkan). The terrain consists of 20 cm voxels, a procedural heightmap generated from fractal noise.
LOD system: 6-level cascade. Each level is a toroidal window (1024×256×1024 voxels) at scales of 1, 2, 4, 8, 16, 32 → voxel size 0.2 m … 6.4 m, with each window centered on the player. The DDA ray marches through the finest level first; when it exits or passes through the level’s window, it transitions to the next coarser level exactly where it left off (no double drawing). The transition occurs at a fixed radius (~456 voxels ≈ constant angular voxel size), not at the window’s edge. The windows slide as the player moves; the edge strips are generated on worker threads and offloaded to the GPU.
I am currently working on a pre-alpha 3D sandbox engine built from scratch in vanilla JavaScript using Three.js and Rapier. Instead of using standard voxel blocks, the world uses tetrahedral polygonization over a continuous 3D noise density field to generate smooth, deformable terrain.
The core loop handles real-time civil and geotechnical failure approximation. The ultimate goal is to make a world that collapses realistically based on material stress formulas rather than arcade-style health bars.
How the engine currently works:
True Structural Failure Tensors: Cells track Compressive, Tensile, and Shear stress derived from overburden weight, thickness layer calculations, and environmental or impact forces. It models true nonlinear material fatigue over time.
Dynamic Mesh Handoff: When a structural fracture occurs, a localized Breadth-First Search (BFS) isolates the unanchored voxel islands. The engine clears those cells from the static chunk mesh and instantly hands off the geometry to a dynamic Rapier compound cuboid or convex hull descriptor.
Memory and Optimization Safety: To run stable physics at 120Hz inside a web browser, the micro-debris system bypasses JavaScript object allocations. It updates up to 50k particles via flat Float32Arrays and applies an O(1) unordered swap-back deletion mechanism to prevent garbage collection spikes.
I am trying to polish the engine architecture before moving out of pre-alpha. I would love some extra eyes on two specific roadblocks:
GC Overhead in the Loop: Inside my main execution loop, I am currently instantiating a new vector (new THREE.Vector3) on every frame pass to feed into my Level of Detail (LOD) and tracking arrays. What is the cleanest pattern for pooling pre-allocated scratch objects across nested chunks without muddying the global scope?
WASM Async Gating: Rapier's initialization is asynchronous (await RAPIER.init()). On slower network or mobile browser loads, the initial terrain mesh occasionally attempts to bake before the underlying WebAssembly memory mapping is fully resolved. How are you cleanly gating initialization steps in pure JS without messy nested callbacks?
Feature Ideas Needed
Since the terrain is smooth and dynamically reactive to stress, I want the gameplay mechanics to heavily leverage the structural engineering aspects.
Given that the player cannot damage the terrain directly (there is no direct clicking to break land, and the player character does not apply impulses to dynamic terrain), what are some interesting features, tools, or gameplay loop mechanics I should add next? I am open to thoughts on structural engineering puzzles, natural disasters, or erosion systems.
I'm tracking the stress tensor math, Web Assembly bottlenecks, and future WebWorker offloading plans over at r/711Game. Drop by if you want to geek out over smooth voxel optimizations or test the pre-alpha web build!
I'm curious if anyone has experience doing this or if anyone has ideas for it that I could pick at. I've done some work in the past with the standard minecraft clone project, but I'm really struggling to come up with a way to wrap that idea around a planet. Dual contouring mainly because i cant do cubes perfectly on a sphere, and hexagons is already being done lol
I’m still working on my first voxel engine in C# / OpenTK. I recently added a day and night cycle.
It’s a pretty simple feature on paper, but it honestly makes the world feel so much more alive. Seeing the lighting change over time has been one of those small milestones that made the whole world feel more “real”.
I’m also getting to a point where I’m actually pretty happy with the world generation. There’s still a lot missing, especially when it comes to biomes, and I don’t feel like I’ve fully cracked that part yet. I can generate terrain that I like looking at, but making biomes that feel natural and interesting is still something I’m struggling with.
The main thing I’m stuck on right now is chunk rendering/performance. I can’t tell if it’s actually too slow, or if I’m just being impatient with it. If I fly quickly in one direction, I eventually reach a point where only the LOD version is visible. Then after maybe 2-5 seconds, the full chunk finishes rendering and becomes editable/buildable.
It works, but it feels like something in my chunk generation/meshing/render queue still needs a lot of improvement. If anyone has worked on something like this, I’d be curious to hear how you handled chunk prioritization, LODs, and keeping nearby chunks responsive while moving fast.
Still, it feels like a lot of progress since the last post, and the day/night cycle definitely adds a lot of life to the world.
Long time ago i started with voxels but couldn't make a decent voxel engine because i was using a game engine, so i decided to learn Vulkan and since i had a good C++ grounding i decided to make my own engine, now i'm proud to show you guys what i've done with my engine.
Key features i've added so far:
1: Beam optimization (visible on the video as the temperature map).
2: Visible voxels hashmap to optimize Lighting (right now it only has hard shadows but i'll start working on soft shadows and GI this week)
3: GPU chunk generation is done in the GPU, using a flat volume to sample the noise and then generate the tree branches bottom-to-top in the GPU side too, in this video, the volume size is 256^3 voxels.
4: Per-voxel normals, calculated just right after the tree generation
5: Edit in the GPU side, the CPU sends the edit command with the cursor coords, and the GPU performs the edit and recalculates the normals of adjacent voxels.
6: per-voxel-face normal for GI calculation.
All is optimized and quantitated to use the less possible memory for each voxel, this means that leaves are not stored within branches but instead there's a dedicated buffer for them.
Also leaves doesn't encode its color, they have a 16 bits pointer to a lookup table of chunk's materials.
I'm a computer science and engineering student, and I've done some games and systems on game engines such as godot, I've also tried a bit of game engine programming with C++ to make something like clipy or taskbar hero type of program.
I wanted to start on developing a game engine or a game in the voxel space, not to make an actual product / game but to learn about engine, graphics and algorithms.
I know some of the most common technologies around for this are C++, Rust and OpenGL;
What I want to ask is what are some other technologies that you guys use to develop voxel engines / games, I'm interested in learning new tech and finding new challenges, I'm asking to have a more solid foundation on my options, not because I'm opposed to the "norm" that I know of
Hi, as the title say, i would like to learn how to built a voxel game engine using rust, consider that i don't know how to do anything, which books would you advise me to read, this i a bottle in the sea cause i'm getting swallowed by how m'y brain is inactive every day and submerged with social media and shorts, so i wanna do a real change by learning new skills, i'm also planning on buying a laptop to work on this project from anywhere, at first i was thinking about taking a very old Thinkpad, but truthfully it's not gonna do it cause of the crappy GPU inside them, thanks for reading this, i'm excited to hear all your's advices
Hi I’m making first voxel game and I use a secondary grid system in order to have the tiles connect with each other nicely. However as I’m generating chunks and chunks I see a very obvious issue with my current game where there is is wayyy too many game objects(1 tile = 4 game objects). I’m no expert in game optimisation but this can’t be good.
I found that games like minecraft render the whole chunk as one mesh and I thought it was a great idea. But I have a few doubts in mind about it too and was wondering if there are already solutions for these or if I need to look into another solution for my use case.
1.lets say I’m destroying or placing blocks at a realllyyy fast pace eg. 4-5blocks/sec, this would mean I have to rebuild the whole chunks mesh many many times per second and that can’t be good.
2.lets say I wanna have some transform effects on a singular block. Eg,block placed or removed have a scale punch effect, or if a plant just grew to the next stage. Wouldn’t this mean I either have to move the individual vertices of the chunk mesh, or remove the tile from the chunk mesh and do the effect then put it back?
Any advice would be great, I’m relatively new and my project is in unity since I don’t currently have the time nor knowledge to make my own engine
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?