问题
I'm currently in the process of creating a voxel engine in order to familiarize myself with many of the concepts involved, It also happens to be an exercise in optimization for me. When searching around I've seen multiple sources across several websites suggust that I not use ModelBuilder().createBox() or createRect() to do anything but troubleshooting.
Instead they recommend creating your own cube models in something like blender, than using those in place of createBox. I've just finished Implementing culling for optimization, and rewriting my code to change over to custom models would take some time. I want to understand what I'm doing and why I'm doing it before committing to something like that.
Why exactly is createBox not recommended? is creating individual models really the best idea in this situation?
回答1:
The ModelBuilder#createBox
method is a convenience method to create a Model
with a single Node
that contains a single NodePart
which contains a single box shape. It is exactly the same as doing:
ModelBuilder builder = new ModelBuilder();
builder.begin();
builder.node();
MeshPartBuilder mpb = builder.part("box", primitiveType, attributes, material);
BoxShapeBuilder.build(mpb, width, height, depth);
model = builder.end();
It creates a Mesh
object, which is an OpenGL resource, which contains (depending on the attributes) only 8 or 24 vertices and 36 indices. Unless it is the only thing you want to render, it is very bad for performance to have such small Mesh
.
This is because every Mesh
(or (part) of a Node
) implies a render call. This means that it has to wait for the previous render call to be finished and the CPU and GPU to synchronize. It would be far more performant to combine as many shapes as possible into one Mesh
and render that at once. After all, the GPU is intended to be executed on many vertices in parallel at once.
This is the same reason as why e.g. SpriteBatch
combines as many sprites as possible before rendering it. And it is also the reason why using a single TextureAtlas
is better for performance than using separate textures.
So, if you would create a voxel engine using models that contain only a single box then you would end up with thousands of render calls. That would be so slow that it would make your game practically unplayable.
Ofcourse, the solution to this is easy, just add multiple boxes to the part:
ModelBuilder builder = new ModelBuilder();
builder.begin();
builder.node();
MeshPartBuilder mpb = builder.part("box", primitiveType, attributes, material);
BoxShapeBuilder.build(mpb, x1, y1, z1, width1, height1, depth1);
BoxShapeBuilder.build(mpb, x2, y2, z2, width2, height2, depth2);
//...
BoxShapeBuilder.build(mpb, xn, yn, zn, widthn, heightn, depthn);
model = builder.end();
The ModelBuilder#createBox
(and other create methods) hide this logic, which makes it less obvious to see what is going on behind the scenes and how easily it can be optimized. Therefor I will probably remove those methods some day. Unfortunately the createXXX
methods are quite helpful for newcomers learning the 3D API (e.g. I use it in the tutorials on my blog), who want a quick start. Which is the reason I still haven't removed them.
Btw, using ModelBuilder
for a voxel engine is an overkill. You might want to have a look at this tutorial instead, where I show a simple way to combine simple shapes at runtime. The latest release of libGDX even contains ShapeCache, which does practically what you can use directly as chunk of voxels.
I'm not sure though why you'd think that creating a box in a modelling application is any different than creating it by code. Perhaps you can link to the reference where you found that.
来源:https://stackoverflow.com/questions/37353883/why-excatly-shouldnt-i-use-libgdxs-createbox-or-createrect