Hi, I’m quite new to Threejs and haven’t quite got everything perfect yet I was hoping to get some help to reduce drawcalls as after loading this model I’m stuck with over 8K drawcalls.
How can I reduce this whilst still retaining the option to select individual objects?
— I should probably say now that I don’t have control over the input model or it’s contents.
You can only reduce draw calls by merging 3D objects or by using techniques like instanced rendering. Both approaches can be implemented with
three.js but they will make the interaction with your scene more complicated.
Unfortunately, the engine requires that the user explicitly performs merging or instanced rendering.
three.js does not perform this actions automatically for the user (often called auto-batching and auto-instancing).
That’s bad since the easiest way to optimize your model is during the design phase. Another problem is that your asset is very big (61MB). This is not a usable size for the web. Consider to Draco-compress you model in order to speed up the transmission time.
Thanks for your insight I should first say that the model is compressed before delivery to the end user, we don’t transfer this much data, I gzip and use draco compression to drastically reduce the size
Is instanced rendering something I could achieve with models like this? Possibly during the loading stage.
Here is the long (and a bit sad) story about automated instancing in Three.js: https://github.com/mrdoob/three.js/pull/10093
It doesn’t look too promising
The IndexedVolume object i made does auto-instancing also with culling and full matrix optionally, though i do understand why it is problematic to implement auto instancing for a regular THREE scene as default, also the assets would cause multiple unecessary stacks if they don’t consist of a single geometry and material, this is why i added mesh packing.
@Harry the model itself really isn’t optimal itself, a lot triangles in small and thin details. Try merging it first and see how it performs for a low-end device. The mesh packing method i mentioned about does that btw, also merging an asset with multiple materials and textures into one draw call.
It could also help to merge some regions but not all, you could benefit from culling some chunks.
Any chance that it will be made public and free?
Public yes, probably next week, but it is part of a commercial project, it’s been a lot work and not everyone can afford to fully work for free just a few bucks to support development though, volumetric impostors are coming too.
Exciting! Will some of it be published for free under a nice license?
It is one system, even though auto-batching and auto-impostors are plugins they are made for this system. You can write me a DM if you have any further questions.
This sounds very nice @Fyrestar! Do you have any demos available? I’d love to see a side-by-side comparison if possible.
Yes but i’m setting up a better demo with higher quality assets currently. I will post a video summarizing it a little too, while i get 55-60 fps with IndexedVolume in a stress test, it can crash without, so the difference can be quite noticable, rendering through the index alone already, since it drastically cuts down the amount of frustum tests.
You mainly benefit in huge scenes from it, you have a single model. I didnt looked at the polycount but you should first try to merge it with a modelling tool and see how it performs then.
Sounds good I did run a test with the model merged and it’s running well over 60fps consistently. I would be happy to merge the geometry, although I need to somehow retain the ability to control individual parts of the model, mostly just highlighting parts.
Can you pass me a hint on how to make ThreeJS merge 3D objects?
Merging is usually done via BufferGeometryUtils.mergeBufferGeometries().
webgl_geometry_minecraft is one example that uses this function.
It’s also worth noting there are offline tools that can help you optimize a glTF model and reduce draw calls: