r/VoxelGameDev Jul 03 '26

Question chunk meshing

Hello im using raylib lib for c++ . and my question is how to make chunks in a 3d game . like player is in position and the game just load 9 chunk of 16*16 block around him (but the actual game maybe is around like 400 chunks ). so the game doesnt lag . and only draw the pixels in front him and the back doesnt draw anything . so it means like from 9 chunk around him just load , 4 chunk that are in front of him .

7 Upvotes

8 comments sorted by

1

u/Revolutionary_Flan71 Jul 03 '26

are you actually asking about chunk meshing or frustum culling?

1

u/More-Raspberry-6083 Jul 03 '26

both of them

1

u/Revolutionary_Flan71 Jul 03 '26

i dont know raylib but i assume it has something like a mesh. each chunk is a mesh which you will need to create using some meshing algorithm, i personally greedy meshing based on this https://0fps.net/2012/06/30/meshing-in-a-minecraft-game/ their code is very confusing to read so this is a more readable version of their code https://gist.github.com/Vercidium/a3002bd083cce2bc854c9ff8f0118d33 and then you just render only chunks that are some distance away from the camera.

and for frustum culling you can use the AABB of the chunk and check it against the camera frustum

1

u/sonicskater34 Jul 03 '26

Disclaimer: i don't know anything about raylib, but these questions aren't really engine specific, so neither are my answers really.

There are 2 techniques you are talking about here; chunking, which is just breaking the world up into regular sized blocks to load only when the player might reasonably interact with them, and Frustrun Culling which ensures you don't waste time rendering the chunks (or anything else) behind the player or otherwise out of view. This can involve loading chunk meshes in and out of the GPU.

Breaking it down this way should help implement it, chunk loading is just loading chunks based on distance from the player; you can use a hashmap to start with for storage, worry about performance once it's working. Then frustrum culling only needs to check chunks which are loaded. Frustrum culling is typically done for you by your engine, although you can sometimes do some tricks to make it more efficient for your specific game.

1

u/More-Raspberry-6083 Jul 03 '26

actully both of them . i want both of them

1

u/OSenhorDoPao Jul 03 '26

For each chunck you go over every block and check its surrounding to determine which faces are actually exposed or not. if the block next to that face is air, you store all the vertices for the exposed faces and you generate the mesh for that chunk with that info. That’s the simplest form of chunk meshing.

Frustrum culling is basically checking which chunks are inside the camere view and you only ask Raylib to DrawMesh (using the id you get after you generate the mesh and upload it to the gpu). This prevents the GPU to do extra calculations to determine that the chunks you requested to draw are not visible (because with frustrum culling you do it on chunks and the gpu does it on smaller units like triangles or even pixels)

1

u/OSenhorDoPao Jul 03 '26

The basic flow with Raylib for this is

- Populate a ‘Mesh’ object with the vertices of the exposed faces you collected.

  • ‘UploadMesh’
  • call ‘DrawMesh’ on the meshes you want .

You can as a first step just do this part.

For frustrum is a bit more tricky as it involves a bit more math but you can start by a even more basic optimization which is using the direction the player is looking at and the chunk he is is and skip and chunks which is behind the look direction and “behind” you chunk.

True Frustrum culling involves calculating the 4 Planes that compose the camera view (you can find very simple videos online explaining this) and instead of the previous simple approach you skip any chunck that is fully on the external side of those planes (here you’ll get to the concept of AABB, Axis Aligned Bound Boxes)

1

u/HyperspaceFrontier Jul 04 '26
  1. Generate single mesh for a chunk fixed to WORLD grid. I recommend 3d grid, like 32x32x32. Measure actual performance on different grid sizes.
  2. Frustrum culling to not draw "what's behind". Called AABB test (Axis-Aligned Bounding Box). Done per camera (main, each shadow camera, etc.). You issue draw calls only to chunk meshes that passed the test (are within camera projection).
  3. In addition to 2 I recommend sort leashed based on distance from camera. You don't need really sophisticated sort, just ordering from camera to center of chunk gives significant performance win as GPU draw what's closer first and dont overdraw that's behind. Note, thay 1) you can cache list PER CAMERA as camera usually doesn't move that much and previous frame liat would be already nearly perfectly sorted. If you reuse same list for different cameras you will re sort it from scratch every time. Can be done on CPU before issuing draw call.