Issue with highlighting instances

Hi,

I’m fairly new to babylonjs, but think I have a somewhat solid grip on it. I’m loading in a single glb as the only component in my scene. ~30 megs before compression. When I load the glb, I iterate over the meshes and add metadata when applicable to each mesh based on a variety of factors. When the user hovers a mesh, all the meshes with the same metadata need to highlight. To accomplish this, I’m adding a function to scene.onPointerObservable that picks the mesh they’re hovering, then using the metadata attached to it, iterating over and adding all the meshes with similar metadata to a HighlightLayer. Checks are in place to not do this more than needed, so I’m not iterating over all the meshes every time they move the mouse.

This all works great. The issue, is that a new glb I’m working with uses instanced meshes. When I plug this glb into the existing logic, the instances each get different metadata at load, which is desired. However, When adding the meshes to the highlight layer, it seems to be all or nothing between the instances. I’ve done some googling, and it looks like the highlight layer can not highlight specific instances only.

My scene is not so complex as to need the optimization of instancing to be within my performance requirements. However, it might be a pain to ensure all models I use in the future don’t use instancing.

Does anyone know of a better solution than de-instancing these meshes? And if not, is there a better way of de-instancing the meshes than cloning the original ignoring children, copying the instance’s position, rotation and metadata onto the clone then disposing of the instance?

Thanks

pinging @sebavan

So on one side, it is totally the goal with instances cause we only want one draw call so from this point of view it is all correct.

But on the other hand, I get your point with the need of highlighting only one of the instances.

I would advise to create a clone (only one) that will be used for highlights. Basically when you need to highlight, you disable the instance to highlight and replace it with the clone. When highlight stops put back the instance (enable) and disable the clone. You would need to only forward the parent transform info to ensure they replace each other transparently. This approach would stay constant in memory and probably prevent some hard gymnastics.

2 Likes

Thanks for the reply!

It’ll be a bit of logic since any number of meshes can share the metadata tag that indicates they need highlighting together. So I’ll need to find all the meshes with that tag, for each mesh found, highlight it if there are no instances involved, or if they’re an instance or have instances, clone, hide the original and highlight. Then reverse it out when meshes with that tag are not highlighted any more and do the same to meshes with the newly highlighted tag.

Seeing as I could be creating a number of clones of different meshes with that metadata when they’re supposed to highlight, I’ll need to check the performance hit at the moment of highlighting vs the general performance hit of having them not be instances.

Thanks for the response, I’ve got a few scenarios to test.

Can this be revisited in the future to either put in an engine method, or just a method flag to include instances, or explore options?

It seems that since Highlight is just a 2d layer mask, it should not add that much performance hit to include an instanced mesh into the mask. Though, a bit over my head, so talking from the perspective of the guy that doesn’t have to make it work.

I get why this issue exists but I have numerous models that rely on instances created within modeling software, and those instances need to stay instances for performance - so I can’t start them out as copy/clones. Highlighting them gets rather messy as you have to export every instanced piece separate to do something like what is mentioned above & swap them. What I am building has large scale changes even among the same model. Hoping you get your transforms just right to align back up if calculating scaled positions where rounding seems to becomes an issue… it is making my head spin.

1 Like

I have the same problem. For performance issues i tried to migrate my logic from mesh clones to mesh instances and faced with issue that now all my meshes are highlighted instead of bunch of needed meshes. I think highlight layer should be improved to support instanced meshes

Unfortunately, this won’t be possible with the highlight layer.

The highlight layer uses the stencil buffer, and depending on whether a mesh is highlighted or not, the stencil buffer must be switched on or off. The stencil state is enabled or disabled for a draw call, but cannot be changed during the draw. As all instances are drawn in a single draw call, it’s thus not possible to have some instances highlighted and others not.

I think the solution proposed by @sebavan is pretty good, if you only have a few meshes to highlight?

1 Like