Jump to content

  • Log In with Google      Sign In   
  • Create Account


Best Algorithms for Rendering Voxels


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 dustin321   Members   -  Reputation: 151

Like
0Likes
Like

Posted 18 August 2012 - 01:32 PM

Hello, I know that there have been several posts like this, but each one only seems to answer pieces of my questions. In my game, I have 10x10 chunks loaded at a time, which contain 3d arrays of Block objects. I am at the point where I need to start rendering this data to the screen. My plan was to store a list referencing visible voxels in each chunk(if surrounded on all 6 sides by opaque voxels, it is not visible). Next, in the Draw method, check each if each chunk's boundingBox is in the view frustrum. If it is, render the visible blocks. Is this a good approach? I am unsure of exactly what to do after that. Also, I have read that octrees are a good way of checking visible faces in a voxel world. I know how to use these to compress data, but I don't understand how they could be used to help with rendering.

Edited by dustin321, 18 August 2012 - 01:50 PM.


Sponsor:

#2 Programmdude   Members   -  Reputation: 120

Like
0Likes
Like

Posted 19 August 2012 - 01:23 AM

A long time ago(3ish years) I worked with some friends on a voxel engine. I wasn't directly working with the graphics, but we did talk about it a lot.
The first try was to render lots and lots and lots of cube models. Even with a frustum culling it was awfully slow. The approach we went with is construct a vertex buffer & index buffer based upon all of the visible faces. You shouldn't do that every frame either, just when blocks change.
If I remember correctly the approach we had for different textures was have a set of vertex buffers, one for each texture.

#3 larspensjo   Members   -  Reputation: 1526

Like
0Likes
Like

Posted 19 August 2012 - 02:08 AM

Hello, I know that there have been several posts like this, but each one only seems to answer pieces of my questions. In my game, I have 10x10 chunks loaded at a time, which contain 3d arrays of Block objects. I am at the point where I need to start rendering this data to the screen. My plan was to store a list referencing visible voxels in each chunk(if surrounded on all 6 sides by opaque voxels, it is not visible). Next, in the Draw method, check each if each chunk's boundingBox is in the view frustrum. If it is, render the visible blocks. Is this a good approach? I am unsure of exactly what to do after that. Also, I have read that octrees are a good way of checking visible faces in a voxel world. I know how to use these to compress data, but I don't understand how they could be used to help with rendering.


The way I did this was to translate the list of blocks in a chunk into a list of visible faces (triangles). Each triangle then contains information about vertex coordinate, UV coordinate (texture), normals, and possibly other data (pre computed lighting information, etc). You will want to use different textures for different types of blocks. You can do this by either having several lists of triangles (one for each block type), or by having a single list. If you go for the single list, then you will need a texture atlas for all block materials and clever UV coordinates that address the correct part of the texture. Minecraft did it the atlas way, but I did it with separate textures.

Instead of determining what blocks are visible, you should check what faces are visible. I use the simple algorithm to include all faces that are adjacent to air (or a transparent medium, like water).

The advantage of doing it the atlas way is that you only need one draw function for all triangles in a chunk. However, I did some performance testing, and couldn't find any obvious improvements from this. The advantage with having one list for each block type is that you have have bigger textures with higher level of details.

Your idea of checking the chunk for visibility in the view frustum is what I am also doing. There are some complications later on when doing shadows, etc, as some chunks are not visible but will still have an effect on your scene. But that can safely be ignored for now. It is a little tricky to determine if a chunk is inside the view frustum or not. You could check each of the 8 corners of the chunk, but there are possible situations where a small part of a chunk is visible, but all corners are still outside. I am using a simplification here. I check if all corners of a chunk are outside the view frustum on the same side. For example, if all corners have an 'x' that is bigger than the biggest 'x' of the view frustum, then you can safely say that the chunk is not visible. This will generate a few cases where chunks are drawn that are actually not visible, but it is better to draw a little too many than a little too few.

There are also more advanced ways of culling chunks. You can ask OpenGL (if that is what you are using) to draw an invisible bounding box representing the chunk, and then use queries to check if the box was "seen" or not. There are some tricky things here, because you can disturb the drawing pipeline, if you don't know what you are doing, and get much slower drawing.

Octrees Are very good when you have many objects and want to find out which ones are inside a specific volume. In case of your chunks, I think you already know which ones there are. That is, you may have an access method where you can quickly (constant time) determine what chunk is at a specific place. If so, I don't think an Octree would help you.

If you have many monsters walking around, it will most probably be very good to keep track of them using an Octree. Especially if you are going to use collision detection.
Current project: Ephenation.
Sharing OpenGL experiences: http://ephenationopengl.blogspot.com/

#4 Programmdude   Members   -  Reputation: 120

Like
0Likes
Like

Posted 19 August 2012 - 03:09 AM

Another idea that could work with regards to the texturing is have vertices have a texture index, and then use that to get the right texture. Then all you need to do is send in either a 3D texture, or a 2D texture array. The exact implementation would depend on whether you are using DX9, DX10+ or OpenGL.

#5 dustin321   Members   -  Reputation: 151

Like
0Likes
Like

Posted 19 August 2012 - 10:44 AM

These approaches are exactly what I was looking for. I think that holding which faces are visible and rendering them will work well. Thanks for the help.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS