hardware instancing?

Started by
14 comments, last by ChristianFrantz 10 years, 6 months ago
For a minecraft type game, would it be better to use hardware instancing or create faces of cubes based on what's visible? I'm not sure on how many cubes can be rendered using instancing, but i want to know if it's worth my time to try it out.

Each side of the cube has the same texture so using a texture atlas isn't an issue. Cubes will be constantly removed or built also.

If you see a post from me, you can safely assume its C# and XNA :)

Advertisement

What type of container do you have for all your cubes? Do you split them up in several containers?

I think what you need to focus on is to figure out what cubes are actually visible to the user. Say a cube has 6 neighbours one on each side, this means that it will not be visible to the user and can be exluded from the drawing list. Frustrum culling is also a way to exclude unseen cubes.

Traverse your container and begin filtering cubes on different criterias and build a std::vector of all visible cubes. Now that you have an array of cubes that contain transformation, texture atlas index and color, you can copy that to your instancing buffer. One drawcall later and all the cubes are drawn!

You are always better of drawing only what is necessary. 100x100x100 cubes are 1.000.000 cubes that have 12.000.000 faces which is very very much compared to thr vissiblr are.

Once you have a list of drawable cubes you can traverse that list and extract visible faces using the normals. Using the faces, populate another array that you copy to your instance buffer. The geometry buffer would then only be a quad.

Very good idea. I haven't thought to do it like that before :D

I just have to figure out how to compare sides. Maybe a foreach with 6 if statements for each side of the cube?

If you see a post from me, you can safely assume its C# and XNA :)

For a minecraft type game, would it be better to use hardware instancing or create faces of cubes based on what's visible? I'm not sure on how many cubes can be rendered using instancing, but i want to know if it's worth my time to try it out.

HW instancing will win by a mile, but that doesn't mean you have to draw all of the blocks! I'd be tempted to split your world up into batches of say 20x20x20 cubes (possibly even larger than that), and then only draw those groups that are visible (with a single instanced draw call per group).


Once you have a list of drawable cubes you can traverse that list and extract visible faces using the normals. Using the faces, populate another array that you copy to your instance buffer. The geometry buffer would then only be a quad.

Or you know, just enable backface culling and let the hardware do that for you! Performing your own culling algorithms with that granularity isn't worth it. Throwing stuff at the GPU in big batches is....

Or you know, just enable backface culling and let the hardware do that for you! Performing your own culling algorithms with that granularity isn't worth it. Throwing stuff at the GPU in big batches is....

Yup, it sounds to me as though the CPU-side culling approach here is going to have more overhead than just throwing it all at the hardware; a cube is a very lightweight geometric construct that the GPU can cull very easily and quickly, compared to traversing a scene, doing all of those dotproduct tests, building up dynamic buffers, etc. The cost of doing this for even a single face may well outweigh the cost of just submitting all 6 and letting the GPU do it.

CPU-side culling works best when it's done on a quite coarse scale than can reject 10s, 100s or 1000s of objects with a single test, but when you get down to individual faces or triangles, you're talking serious diminishing returns.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

I used a tutorial i found online and could draw 20000 cubes no problem. If i can get the cubes into chunks and use frustum culling, i think this could work

If you see a post from me, you can safely assume its C# and XNA :)

For a minecraft type game, would it be better to use hardware instancing or create faces of cubes based on what's visible? I'm not sure on how many cubes can be rendered using instancing, but i want to know if it's worth my time to try it out.

HW instancing will win by a mile, but that doesn't mean you have to draw all of the blocks! I'd be tempted to split your world up into batches of say 20x20x20 cubes (possibly even larger than that), and then only draw those groups that are visible (with a single instanced draw call per group).


Once you have a list of drawable cubes you can traverse that list and extract visible faces using the normals. Using the faces, populate another array that you copy to your instance buffer. The geometry buffer would then only be a quad.

Or you know, just enable backface culling and let the hardware do that for you! Performing your own culling algorithms with that granularity isn't worth it. Throwing stuff at the GPU in big batches is....

Yes! Yikes. Don't do this on the CPU. Let the graphics card do its job.

Casadilla, have you researched all the functionality of the default graphics pipeline? I keep seeing questions like this from you. The pipeline is designed to take this kind of work off the hands of the CPU. Any time you're looking at running some operation on all your graphical entities you should immediately be looking to offload that to the GPU. The common operations are just a matter of throwing a switch, and more complex operations are available through shaders. Don't optimize until you start to approach reasonable performance limits, and once you do reach that point, optimize at the large scale, like menyo and Rob are saying rather than at the per-instance scale. The GPU is designed to do batch geometry operations. It can likely cull the faces on thousands of cubes in parallel.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Everything i know about the graphics pipeline I've learned from tutorials our books. I haven't actually looked at the xna documentation about it. The tutorial on float4x4.net explained hardware instancing pretty well. Because the computer I'm using is so crappy, i need to get the optimization of my map done before i can work on other features.

What i was doing before was completely wrong. Over 10000 draw calls a frame. With instancing the draw calls drop. I just need to put the blocks into chunks now

If you see a post from me, you can safely assume its C# and XNA :)

This topic is closed to new replies.

Advertisement