Changing visibility of individual instances?

Hello,

I would like to customize visibility of every single instance (InstancedMesh).

  1. First I tried to set InstancedMesh.visibility, but using this API does not have any effect
  2. Then I tried to use custom buffers with registerInstancedBuffer() API, but this does not seem to work with scalar values (see Babylon.js PlaygroundUncaught TypeError: h.copyToArray is not a function)

Is there any other way I did not try yet?

Hi Iguminski,

This is how I would get it to work: https://playground.babylonjs.com/#LFXT0L#1. I hope there is better solution for this.

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.

 material.Fragment_Custom_Alpha(`alpha = vmyalpha.x;`);
1 Like

@slin that’s insane! Good but insane :slight_smile: 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.

You can use a float as an instance value with a little trick:

https://playground.babylonjs.com/#LFXT0L#2

But that will do you no good because it won’t be used by the standard shader code.

What you can do instead is using the vertex color:

https://playground.babylonjs.com/#LFXT0L#4

4 Likes

@Evgeni_Popov

Wow. I didn’t know about this: copyToArray : (data, offset) => data[offset] = 0.4

Is it possible to pass instanced attributes that contain more than 4 floats. Like float arrary?

No, it seems passing an array of floats as attributes does not work. What you can do is using a texture instead and put your data there.

@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.
visibility_of_instanced_mesh___Babylon_js_Playground

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 that’s too bad. At least I can now understand better the limits of what instances can do and what not. Thank you for that

@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

I think InstancedMesh are already not displayed if isVisible=false?

1 Like

Correct!