How are VertexBuffers associated with Material property for an InstancedMesh

I am looking at this example - https://www.babylonjs-playground.com/#8L50Q3#1

These are InstancedMesh(s) and there is a VertexBuffer

var buffer = new BABYLON.VertexBuffer(engine, colorData, BABYLON.VertexBuffer.ColorKind, false, false, 4, true);
box.setVerticesBuffer(buffer);

It is not clear to me how is this buffer connected with the color property of the material. Is it by default because of the ColorKind? What if the Mesh has a material with 4 different color properties?

I am trying it for a InstancedMesh with a PBRMaterial but the PBRMaterial has no color property. It has four different color property but not a single one.

The documentation at Use Instances - Babylon.js Documentation says

mesh.registerInstancedBuffer("color", 4);

Is there a list of what else could be registered instead of “color”. Can a buffer for “material.diffusiveColor” be registered?

Thanks.

1 Like

I might be misunderstanding, but I don’t think you can use it with an existing material, i.e. PBR material, instead you create your own shader material i.e. https://www.babylonjs-playground.com/#EK6GAC#13 (or extend one like PBR material)

I think the important thing is the second parameter, which 4, will give you a vector4, which can be used to pass color data to the shader. Note how I am passing cellInfo which didn’t exist before, but becomes an attribute in the vertex shader, that I can then assign a vector 4 on each instance uniquely.

Thanks. That’s a powerful example. I feel I understand part of the concept as a general, but lack any understanding of some of the important details.

So the VerterxBuffer is passing data to the Shader and you register mesh.registerInstancedBuffer(‘cellInfo’, 4);
‘cellInfo’ becomes a data attribute for the vertex shader.
Using BABYLON.Effect you register in the SharedStore and implement you own ‘shared effect’ that takes into account the ‘cellInfo’.
When the cellInfo is passed the shader computes the value of vUV based on the cellInfo.

What you are doing there is

mesh.material = shaderMaterial

But I can not do this, because my mesh is an InstancedMesh and it lacks a .material setter.
So I can not create a new material, and if I could I would not create a buffer at all. I will just change the material to a new material and my InstancedMesh will change color.

(I understand that I again open a new topic when there is an existing on the similar subject - Can not make a mesh blink because it is an InstancedMesh and I now understand that they are very much connected. But initially I though they were different)

Not sure whether you have an answer to this part of your question as yet. Just in case you have not -

the string “color” gives a reference to the vertexBuffer property ColorKind. All ‘kind’ properties of the vertexBuffer can be found at https://doc.babylonjs.com/api/classes/babylon.vertexbuffer

1 Like

If you want to do it that way then you need to use two different source meshes (with the materials applied already), because you cannot switch the material of the instanced meshes. I do something currently with a highlight type mesh, but I will soon be replacing it now that we have instancedBuffers, as I can change the color of the instanced mesh on a per instance basis.

If for some reason you want to do it that way, you just enable or dispose then mesh when you want to switch it out and replace it with the new one. It’s a bit wonky though, and prone to errors. If you are just trying to switch the color, I’d highly recommend using instancedBuffers instead.

Thanks. Creating a new mesh was my first thougth. But sometimes on a user action some 743 instanced meshes had to change visual property and I had to create 743 new meshes and this takes time.

I could not get instancedBuffers working in the amount of time I could afford to this. InstancedBuffers are the way to go. I hope there would be a few more examples and tutorials in a few months to give it to some of my colleague to dig dipper into it.