I would like to customize visibility of every single instance (InstancedMesh).
First I tried to set InstancedMesh.visibility, but using this API does not have any effect
Then I tried to use custom buffers with registerInstancedBuffer() API, but this does not seem to work with scalar values (see Babylon.js Playground → Uncaught TypeError: h.copyToArray is not a function)
I need to use PRBCustomMaterial. Then creating a custom attribute called myalpha. Make sure the attribute is passed from Vertex shader to Fragment shader. Then use the custom alpha hook in the PBRCustomMaterial to update the alpha.
@slin that’s insane! Good but insane I could use something like this, but then I would have a custom fragment shader to maintain, instead of what StandardMaterial provides out of the box (which is good enough for my use case). This makes me slightly hesitant… But thank you for this. If nobody comes up with something simpler, I will use it.
@Evgeni_Popov I realised that in my project I am actually instantiating a merged mesh with MultiMaterial. After applying your idea of using vertex color to imitate partial visibility, I achieved the effect, but also got some undesirable side effects. I reproduced this in https://playground.babylonjs.com/#LFXT0L#8
The instance of merged mesh, which consists of a red ball on a green rod, behaves odd when rotating around it. The green rod sometimes overlaps the red sphere.
The problem disappears when I comment line 33 out
mesh.hasVertexAlpha = true;
but then the transparency effect disappears as well.
This seems to be a known problem (see post), but this prevents me from using this approach. Unless perhaps you know a workaround to this problem? After all, the post comes from 5 years ago.
Unfortunately, I don’t think there’s a solution here because all the instances are drawn at once. So you will have either the spheres drawn first then the boxes, or the other way around. For a correct rendering, you would need each object to be drawn separately, something you won’t be able to do with instances (order of drawing with transparency is already a tough problem when no instances are involved).
@Evgeni_Popov Setting transparency is not good enough in my opinion. Can we have a solution make instancedMesh not to be render instead of “isVisible = false” ? This makes we can control single instancedMesh display or not easier
You cannot set transparency on a single instance of a textured material. It seems invalid to use instancedBuffers.color for materials containing textures?
If you set the instance to have the same parent as the mesh like below then it does work. @Evgeni_Popov would know better why thou, I just remember once he told me that it needed to be that way for instances to work properly, IIRC particularly with glb meshes because the parent has negative scaling? EG it also works if you call setParent(null) on the mesh or if you change the root mesh’s z scaling from -1 to1.
OK Thank you, but I have a few questions to clarify. First, the transparency cannot be changed through instancedBuffers.color. How can we achieve.
let boomBoxInstance = BoomBox.createInstance('boomBoxInstance');
boomBoxInstance.instancedBuffers.color = new BABYLON.Vector4(1, 1, 1, 0.6);
Second, I need to wrap the object into a TransformNode. If a mesh has many child meshes, it is not feasible to use the same parent. They will have separate parents
For the second part, you can call setParent(null) on the mesh like below instead of using the same parent for them. But for the first part, IDK why the alpha channel of the color attribute isn’t having any effect. Only the rgb channels are, like below where I tinted it purple after nulling the mesh’s parent…
EDIT: PS I found the doc section here where it talks about gltf instancing for more info.