Three.js: Why don't we add material properties to InstancedMesh so that materials can vary over instances? Is it gonna hurt performance?

Created on 8 Oct 2020  Â·  6Comments  Â·  Source: mrdoob/three.js

I am impressed by what InstancedMesh can do in the aspect of performance.
But I also find it difficult and messy to manage different instance meshes on same geometry because of some material property differences.

I saw some examples which add some properties(ie: color) to solve this problem.
Then why don't we add most material properties(of MeshPhysicalMaterial) to InstancedMesh so that materials can vary over instances?

Is it gonna hurt performance in any way?

Question

Most helpful comment

Per-instance color has been added recently, see setColorAt(index, color). GPU instancing does not allow per-instance textures, and there's a limit to how many scalar/vector/color properties can be used as instance properties... more could be added in the future, but I think we'd need to prioritize specific properties that are helpful rather than trying to include them all. Custom shaders or NodeMaterial will provide you more options beyond that.

All 6 comments

Per-instance color has been added recently, see setColorAt(index, color). GPU instancing does not allow per-instance textures, and there's a limit to how many scalar/vector/color properties can be used as instance properties... more could be added in the future, but I think we'd need to prioritize specific properties that are helpful rather than trying to include them all. Custom shaders or NodeMaterial will provide you more options beyond that.

Thank you.
So is it ok to add other properties but textures? like metalness, roughness etc. Can this break limit on number of instance properties?
And how would it affect the performance?

It shouldn't affect performance, but this sounds pretty complicated to support — and avoid hitting vertex attribute limits — to me. The upcoming work on WebGPURenderer will use NodeMaterial as its primary material system, which handles these things pretty well. So that's where I think we should invest most development time, and new properties for InstancedMesh before then should probably be justified on a case-by-case basis.

I think of instancing as being used for things like trees, grass, and buildings. Those might differ with different shades, but not usually different metalness... do you have examples where these specific properties are important to vary with instancing?

I am building sth like editor/viewer so there isn't a specific property. I would like to know if adding 6-7 attributes might break that limit or not in case I add them using custom shaders. Thank you.

The limit is a bit complicated. You can expect at least 16 vertex or instance attributes to be supported, and more on some devices. three.js requires:

  • 1 vertex attribute for each vertex attribute used by the mesh: position, uv, uv2, normal, tangent, color, skinWeights, skinIndex, ...
  • 4 instance attributes (?) for the instance transform
  • 1 instance attribute for each other per-instance property, such as color.
  • 1-8 vertex attributes for morph targets

So depending on your input model, you might have >11 attributes still available, or none at all.

Ok. Got it. Thank you very much.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

danieljack picture danieljack  Â·  3Comments

scrubs picture scrubs  Â·  3Comments

fuzihaofzh picture fuzihaofzh  Â·  3Comments

seep picture seep  Â·  3Comments

akshaysrin picture akshaysrin  Â·  3Comments