Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Concept

I'm currently looking in to how voxel engines work with a view to possibly making one myself.

I see a lot of stuff like this ...

https://sites.google.com/site/letsmakeavoxelengine/home/chunks

... which talks about how to go about reducing the draw calls.

What I can't seem to understand is how it actually saves draw call counts on the basis of the logic being something like this ...

Without chunks

foreach voxel in myvoxels DrawIfVisible()

With Chunks

foreach chunk in mychunks DrawIfVisible() which then does ... foreach voxel in myvoxels DrawIfVisible()

So surely you saved nothing ?!?!

You still make a draw call for each visible voxel do you not?

A visible voxel needs a draw call in either scenario.

The only real saving I can see is that the logic that evaluates a chunk will be able to determine if a large number of voxels are visible or not effectively saving a bit of "is this chunk visible" cpu time.

But it's the draw calls that interest me ...

The fewer of those, the faster the application.

EDIT:

In case it makes any difference I will probably be using XNA (DX not OpenGL) for my engine so don't consider my choice of example in the link above my choice of technology.

But this question is such that I doubt it would matter.

share|improve this question
    
Related: gamedev.stackexchange.com/questions/45148/… –  Byte56 Mar 11 '13 at 15:19
    
@Byte56 similar but not what i'm asking. That question refers to LOD and draw calls (saving by reducing detail), this question is trying understand the logic prior to the draw calls and understand "chunk" savings (saving by rendering less). –  Wardy Mar 11 '13 at 16:41
    
Yep, that's why it's only related and not a duplicate. It's primarily there so that when people are learning about chunks, they can look to the right and see the "Linked" section to get relevant questions about the subject. –  Byte56 Mar 11 '13 at 16:43
    
The ideal setup is that you make a single draw call per chunk, not per voxel. As Byte56 stated below, each mesh is an entire chunk. With that system in place, you'll have to experiment with chunk sizes for performance trade-offs. Smaller chunks: less expensive updates per chunk, but more of them in a given space, and more draw calls. Larger chunks: more expensive chunk updates but fewer of them and potentially fewer draw calls. –  ChrisC Mar 11 '13 at 18:44
    
That makes sense, the setup i have at the moment is something like this: class Model { Chunk[] Chunks } class Chunk { block[,,] Blocks } The model class is abstract so I can then create something like "class TerrainModel : Model" which contains a chunk[] ... good approach? i don't know ... i was also thinking about animation and building say limbs for people a limb could be a chunk in a PersonModel object, then I can for example rotate just that chunk to move the persons arm. –  Wardy Mar 13 '13 at 13:36
add comment

1 Answer

up vote 4 down vote accepted

If you're testing each voxel individually for visibility each time, I suppose you won't save much. However, typically you'd want to build a buffer that represents the surface of your voxel world.

You don't just "draw" voxels, you need to build a mesh that represents the voxels. Building that mesh is expensive, so you want to reduce the number of times you need to do that. The first way is by only rebuilding the mesh when voxels change. So you build a buffer containing the vertices that represent your voxels. Then you draw that buffer every frame.

Now that you have a buffer, you need to rebuild it every time something changes. That means throwing the entire thing away and rebuilding it all. But building is expensive, so maybe there's a way we can reduce the amount of waste when something changes? Yes, we can just rebuild the world around the voxels that changed. If we only have to update the chunk around the changed voxel, we save ourselves a lot of time in rebuilding something we already had.

Now the terrain is chunked into smaller parts, we can just draw the chunks that are visible to us and we can just rebuild the chunks that have voxels change in them. We can do even more now that we have chunks. For example, with chunks that are far away, we can build buffers for those that have reduced polygon count, so they're not so expensive to draw.

All in all, chunks allow us to have more control over what we draw and when. It enables us to implement performance features we wouldn't be able to otherwise.

share|improve this answer
    
so the real challenge in this scenario is not about reducing draw calls ... its about reducing the amount of times I check if something is drawable / needs rebuilding. Since the draw calls in theory should remain constant (based on the number of chunks in the cameras view box) –  Wardy Mar 11 '13 at 16:33
    
when i say constant, i mean that the view distance is fixed and has an upper limit, and that what you can get in there is finite in terms of chunk count so you will likely only ever make "Number of Chunks In View" draw calls. The bonus being that draw distance could be reduced by say walking in to a small room or cave thus drastically reducing the chunks in view count. –  Wardy Mar 11 '13 at 16:37
    
It does have the benefit of reducing draw calls, but it's not where the most significant bonuses are. It also makes the infinite worlds possible by being able to unload chunks that are beyond the draw distance. The draw calls don't have to remain constant. You can use a viewing frustum to check if a chunk is in bounds so you only draw those visible to the camera. But yes, typically the draw count is just whatever the number of chunks is within the bounds of the draw distance. –  Byte56 Mar 11 '13 at 16:38
    
Cheeers for the help @Byte56 but there's still something i don't understand ... if a chunk is in view you still have to assess every voxel in it for visibility so you gain nothing from it ... in fact in some respects it's less efficient because you have to make an extra layer of call depth in your logic surely? (not that you'd lose much but in 3d apps all time is precious) –  Wardy Mar 11 '13 at 16:45
    
The visibility check is not done from the camera's perspective. You check to ensure the voxel is not buried in other voxels. It depends on your rendering style, but for example if you look at the marching cubes algorithm, you're building faces to represent a voxel volume. Once those faces a built, you don't have to check the visibility again, you just draw the buffer that was created. Let the graphics card discard the faces that aren't visible. –  Byte56 Mar 11 '13 at 16:53
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.