I was using InstancedMesh
with custom InstancedBufferAttribute
s. Then I got to have many of such InstancedMesh
s that use the same material, so I tried to use BatchedMesh
to draw them at once. But I was getting some internal errors so I checked the ThreeJS code and then I found a big difference between InstancedMesh
and BatchedMesh
which was that InstancedMesh
use InstancedBufferAttribute
while BatchedMesh
use DataTexture
to manage per-instance data (this part). Does it mean BatchedMesh
doesn’t use drawArraysInstanced
internally therefore I can’t use InstancedBufferAttribute
? If so, do I need to use DataTexture as well to achieve the same thing?
BatchedMesh uses multidraw.
Yes, you should use DataTexture.
Do you need help? (I’m using DataTexture also for my InstancedMesh2 library).
Yes I do! How do I access per-instance data using DataTexture? Meanwhile I’ll try to figure out myself by looking at the yours and THreeJS’s code
Create DataTexture:
You can find utility methods for creating DataTexture
here:
Like with BatchedMesh
, create textures with equal width and height, because creating a texture width = N and height = 1, might fail.
Get Instance index in the shader
I recommend this site to check the shaders of three.js:
https://ycw.github.io/three-shaderlib-skim/dist
You should check these two parts
#include <batching_pars_vertex>
...
#include <batching_vertex>
You can get the instance ID in this way:
getIndirectIndex( gl_DrawID )
Get instance data
You can find utility methods for get data from texture here:
Obviously pay attention to the types and declare the texture uniform in your shader.
I hope I haven’t forgotten anything
I managed to use BatchedMesh instead of InstancedMesh, but the result performance was, even with dramatic decrease in the number of draw calls, not as good as expected. So I did some researching and It seems like, to benefit from both multi-drawing and instancing, you should use multiDrawElementsInstancedWEBGL or multiDrawArraysInstancedWEBGL. But my debugger said it was using multiDrawElementsWEBGL. So I checked the ThreeJS code and there was indeed a code that use the multiDrawElementsInstancedWEBGL but the code seemed unreachable. Because _multiDrawInstances has to be not null but there’s no code in ThreeJS that sets it with any value.
Is ThreeJS is still under development on using both MultiDraw and Instancing? cc @donmccurdy @agargaro
It’s possible to use those commands but it’s not recommended because they don’t work on firefox.
I created an example (not cleaned) that use multidrawInstanced to handle InstancedMesh LODs with a single drawCall, but I don’t think I’ll ever use it:
If individual frustum culling by instance might be useful to you, you might take a look at the library I linked to earlier.