Ideas on combining voxel surfaces to improve performance

User avatar
MirceaKitsune
Member
 
Posts: 848
Joined: Sat May 21, 2011 22:31
Location: Romania, Bucharest
GitHub: MirceaKitsune
IRC: Taoki
In-game: MirceaKitsune

Ideas on combining voxel surfaces to improve performance

by MirceaKitsune » Fri Apr 05, 2013 19:57

One of the main remaining issues in the MineTest engine is performance. Although at the default view range FPS is acceptable, increasing draw distance too much causes performance to drop drastically... especially when there are complex buildings made by players nearby. And I don't mean setting it to huge levels, but even 150 blocks can be too far in places. MineCraft is written in java and handles better on this subject, while MineTest uses C++ and Irrlicht which can be several times faster and more optimal.

From what I'm aware MineTest does have the basic 3D optimizations any engine should. It doesn't render backfaces, unless they're transparent and culling is intentionally disabled. I also tested occlusion and that also works fine... so if a chunk is within draw range but closer geometry covers it entirely it's excluded from rendering. Still, it's very slow. So here's a description of what I'm aware to be possible and suggest doing:

Optimization 1 - Merging all surfaces of a chunk in one mesh.

I had a discussion about this with celeron55 months ago, and he mentioned this an optimization that needs doing. Apparently nodes are still drawn as individual faces instead of being merged into a single mesh, which could improve render speeds drastically. I believe chunks should be what's rendered as whole models, their geometry modified when nodes are being placed or removed.

Consider for instance that if you place two blocks next to each other and look at the top surfaces, you're rendering two different planes. That means 8 vertices, 8 lines, 2 faces (2 vertices and 1 line of each box at the exact same location). If they were combined into one mesh, you'd still be rendering 2 faces, but only 6 vertices and 6 lines. This could be a huge improvement and have noticeable impact on performance.

Optimization 2, Possibility 1 - Combining similar surfaces into larger squares / rectangles

Now to take the idea even further. Let's consider that someone places 3 blocks of the same type in an L shape at the same height (place a block then place one to its right and one to its front). Focusing on the top surfaces again, we'd have 12 vertices 12 lines and 3 faces. With the first optimization, we'd have 8 vertices 8 lines and 3 faces. But since all three surfaces have the same texture / mapping / color and are continuous, what if 2 squares were merged into a single rectangle? In that case we'd only be rendering 8 vertices 8 lines but 2 surfaces.

If that happened at large scale, those enormous landscapes would become a joke to render. All continuous block surfaces would be merged into rectangles and squares wherever possible, highly reducing surface count and improving performance by as much. However, all surfaces would need to be of the same node type so that the texture is the same, and this should only be done on a per-chunk basis.

Optimization 2, Possibility 2 - Combining similar surfaces into a single surface with any number of vertices

An alternative to the above idea, which would be even better as long as it's possible with Irrlicht and OpenGL. It's what people seem call ngons; A surface which consists of more than 5 vertices, as long as they're in a straight line from one to the next the surface remains flat between all lines. Most engines use triangles (3 vertices) and at best quads (4 vertices), but if n-gons are possible too then this would be a huge thing.

All flat surfaces of the same node are then combined into a single surface. So for example, if you place 10 stone blocks in any order but all at the same height and touching each other, then analyze the top surface; You would have about a dozen vertices and lines, but only on the exterior of the whole shape (vertices only at each corner). However, it would all be a single face. Performance improvement with this would be sky-high.

End

IMHO those two things needs to be attempted, and at least the first one done. But I have no idea where to even start at my current programming skill so don't count on me to do much in this area. If I can help with testing or anything else however, I'd love to in order to solve this major issue in MineTest. What are your thoughts on the whole idea? Anyone already working on it or know how to do such?
 

hdastwb
Member
 
Posts: 106
Joined: Tue Jan 01, 2013 18:47
Location: United States
GitHub: hdastwb
IRC: hdastwb
In-game: hdastwb

by hdastwb » Fri Apr 05, 2013 20:13

I'm honestly surprised that these haven't already been done in the engine; I thought combining the meshes was the point of rendering in chunks…

However, I'm not quite sure how it would work with textures and lighting; I believe light is calculated for each corner of each node, thus one would still have to render all of the vertices (Firefox thinks this word is vertexes; I disagree). Perhaps a more uniform way of calculating lighting would be needed…
 

User avatar
MirceaKitsune
Member
 
Posts: 848
Joined: Sat May 21, 2011 22:31
Location: Romania, Bucharest
GitHub: MirceaKitsune
IRC: Taoki
In-game: MirceaKitsune

by MirceaKitsune » Fri Apr 05, 2013 20:16

hdastwb wrote:I'm honestly surprised that these haven't already been done in the engine; I thought combining the meshes was the point of rendering in chunks…

However, I'm not quite sure how it would work with textures and lighting; I believe light is calculated for each corner of each node, thus one would still have to render all of the vertices (Firefox thinks this word is vertexes; I disagree). Perhaps a more uniform way of calculating lighting would be needed…


Hardware lighting is another thing that will be needed, but that's a very complicated area too. Will probably be making a separate thread to discuss that.
 

User avatar
sfan5
Moderator
 
Posts: 3776
Joined: Wed Aug 24, 2011 09:44
Location: Germany
GitHub: sfan5
IRC: sfan5

by sfan5 » Fri Apr 05, 2013 20:44

Implementing this would yield a HUGE speed optimization of Chunk/Block Rendering
Mods: Mesecons | WorldEdit | Nuke & Minetest builds for Windows (32-bit & 64-bit)
 

moukotiger
New member
 
Posts: 4
Joined: Mon Mar 25, 2013 23:31

by moukotiger » Sat Apr 06, 2013 01:28

There are also LOD methods as mentioned here, but it is using different stuff than minetest, so it might not be pratical.
This using polyvox, which is designed for holding and using voxel data.

http://www.volumesoffun.com/lod-for-cubic-style-terrain-with-polyvox/
 

User avatar
MirceaKitsune
Member
 
Posts: 848
Joined: Sat May 21, 2011 22:31
Location: Romania, Bucharest
GitHub: MirceaKitsune
IRC: Taoki
In-game: MirceaKitsune

by MirceaKitsune » Sat Apr 06, 2013 10:36

moukotiger wrote:There are also LOD methods as mentioned here, but it is using different stuff than minetest, so it might not be pratical.
This using polyvox, which is designed for holding and using voxel data.

http://www.volumesoffun.com/lod-for-cubic-style-terrain-with-polyvox/


LOD would be another thing we can do. Less important than optimizing the actual surface as a mesh, but important still.

After a certain distance, vertices could be merged and reduced... so we'd basically have a low-poly version of the terrain / buildings which are too far away. This would yield in slopes and diagonal surfaces in our (blocky) case, but since it's far and you only need an interpretation of the landscape that's ok.

From what I'm aware, farmesh is meant to do just that. But I tested it again last night and currently it's VERY broken. Not only that it doesn't even look right in many circumstances, but it also murders the FPS instead of improving it. So on this chapter, I think the way is for someone to get farmesh properly working and change what's needed in its functionality.
Last edited by MirceaKitsune on Sat Apr 06, 2013 10:36, edited 1 time in total.
 

tinoesroho
Member
 
Posts: 570
Joined: Fri Feb 17, 2012 21:55
Location: Canada

by tinoesroho » Sat Apr 06, 2013 15:03

What would be nice would be to render anything outside a "4-chunk square" as a single mesh. It's not like you'll be firing arrows or cannons (and the server would update the mesh on interaction anyways), so...
We are what we create.

I tinker and occasionally make (lousy) mods. Currently building an MMO subgame and updating mods. Pirate Party of Canada member. Sporadic author. 21 years old.

My github:
https://github.com/tinoesroho/
 

celeron55
Administrator
 
Posts: 450
Joined: Tue Apr 19, 2011 10:10
GitHub: celeron55
IRC: celeron55

by celeron55 » Mon Apr 08, 2013 12:35

Ehm. 1 and 2 are already done. At least in some applicable way. The factual basis of the whole post is kind of nonexistent.

EDIT: The simple combination-tiling of faces does not give much more performance though; it'd need to be much more advanced than it currently is, and in non-flat or inside surfaces it always ends up being unused if smooth lighting is used, because all the vertices are required for applying correct lighting.

EDIT2: So I think this can be talked about more if/when in some distant future an another lighting implementation is made.
Last edited by celeron55 on Mon Apr 08, 2013 12:41, edited 1 time in total.
 

User avatar
MirceaKitsune
Member
 
Posts: 848
Joined: Sat May 21, 2011 22:31
Location: Romania, Bucharest
GitHub: MirceaKitsune
IRC: Taoki
In-game: MirceaKitsune

by MirceaKitsune » Mon Apr 08, 2013 12:39

celeron55 wrote:Ehm. 1 and 2 are already done. The factual basis of the whole post is kind of nonexistent.


Really? My mistake then, I remembered that neither of those things were implemented yet. This topic is indeed pointless then. Great work to who added those optimizations also.
 


Return to Feature Discussion



Who is online

Users browsing this forum: No registered users and 0 guests