Showing highlighted silhouette of mesh ONLY when it is occluded

OK! I might create a PG these days but we have @Evgeni_Popov, the mastermind here to help you and it’ll be hard to introduce something new but NGL I have an idea :smiley:

  1. The override applies all the time but there’s no performance penalty by itself as it is simply calling the old method and returning false.

  2. There’s no overhead if you are using the occlusion queries only for the purpose of drawing silhouettes. If you are also using them to avoid drawing meshes that are not characters then there’s an overhead because the meshes will be drawn even if they are occluded. We would need a new property on the mesh that would tell that we want to compute the visibility using an occlusion query but not using the result to cull the mesh. That way, we could enable this mode on a per-mesh basis instead of making a global change by overriding _checkOcclusionQuery.

2 Likes

Ok thanks @Evgeni_Popov I think for the moment i’m only using the occlusion queries to draw the silhouettes of the avatars but i was planning to cull occluded non-avatar meshes to increase performance which is concerning. Are you saying it’s possible to only apply the override on a mesh by mesh basis? Because I only really need it on the avatars and nothing else. So that option appeals to me. Although not sure how exactly you could do that.

If this PR is merged:

You will be able to enable this behaviour for some meshes and not for others.

3 Likes

@Evgeni_Popov you are an absolute legend. I see the changes were approved so I hope that it gets merged in soon!

1 Like

Hey guys! Recently decided to take another look at this after wrapping up some other things. @Evgeni_Popov Seems like your PR was merged into master since last i checked which is awesome. I’ve tried implementing it the way you’ve outlined in the playground on github but for some reason the occluded shape is coming back as pure black rather than the highlighted silhouette. I suspect it might have something to do with the fact that i’m adding the avatar object to the highlight layer AFTER the scene has been created. I am also performing the occlusion check in a render function for the avatar as opposed to the scene observable in the playground. These are the only things that are done differently in my code vs yours. Any ideas as to why this might happen?

It should still work.

Reproducing it in a PG would be nice. You can simulate doing some operations after scene creation by using a setTimeout in one of the PG of this thread.

hmmm i can’t seem to replicate it in a playground. I really don’t understand why then. I have just updated my project to latest version of babylon but I also collaborate with other people on this project so most likely its one of them has changed something since last i worked on this code. Will have to investigate i suppose.

I’ve realised that its only coming as black when behind actual 3D models rather than shapes. I think the method whereby we load models has since changed and so I think i am no longer excluding them from the highlight layer properly when they load into the scene

Edit:
Yep that was exactly what was breaking it. Working nicely again!

@Evgeni_Popov Once again calling upon your help for hopefully the last time. I’m seeing strange behaviour when two occluded avatars occlude each other. I recreated this behaviour in this playground: https://playground.babylonjs.com/#JXYGLT#16 I think for me the ideal behaviour is that both rings show at all times when occluded. Not sure if you know why this might be happening?

Writing to the depth buffer should also be disabled when the sphere is occluded to avoid writing wrong depths (because we set depthFunction = BABYLON.Constants.ALWAYS):

image

However, you will get some rendering artifacts when one sphere is visible and not the other:

image

That’s because the sphere which is visible still writes to the stencil buffer. To fix the problem, the sphere should be added to the excluded meshes when it is not occluded:

image

The PG:

2 Likes

Ok amazing! It works nicely. I feel like i’m learning so much thanks to you. One more thing though. Is it possible to prevent the conjoining of the silhouettes in favour of displaying them individually somehow. Perhaps showing the full rings of circles that are closer to the camera while the more distant circle is only seen partially? To make them look as if they were overlapping each other.

No, unfortunately I don’t think it is possible, it is how the highlight layer works. If you really want that each object be highlighted separately, you will need a shader based solution, something like in post #2 Showing highlighted silhouette of mesh ONLY when it is occluded - #2 by Evgeni_Popov

2 Likes

Ok cool. This will definitely suffice for now. Thanks again for everything. You’ve been a huge huge huge help. Hopefully i’ll be able to show you something soon.

@Evgeni_Popov is awesome !!!

3 Likes

Yeah! He is! :vulcan_salute:

IMHO this topic became one of the most interesting around here!

2 Likes

Hi all! I’d like to resurrect this thread :skull: for an issue that I have just come across that I would love some assistance with. So during my implementation of this feature, I realised that there were certain times where I wanted the occlusion ring to NOT show up behind certain meshes. For such cases, I have managed to successfully prevent that from happening by firstly not adding that mesh to the highlight layer’s excluded meshes and secondly, by enabling the following properties on the mesh material:

material.diffuseTexture.hasAlpha = true
material.useAlphaFromDiffuseTexture = true

However it is worth noting that should the occlusion ring be behind a mesh such as those mentioned above AND a regular non-altered mesh, the occlusion ring will still show up (this is desired behaviour)

I noticed my current problem after adding a mesh that uses a video texture. My issue is that when adding the material properties listed earlier to a mesh with a video texture, the texture itself seems to break (no video is shown) but without those properties enabled the occlusion ring shows up behind the video as a pure black circle.

All of this behaviour can be seen in this PG: https://playground.babylonjs.com/#ISNIBB#2

I’m struggling to find a solution around this. Perhaps I need to implement a better way to prevent the occlusion ring from showing up behind particular meshes? or maybe I need to alter the underlying system whereby the occlusion ring is enabled/disabled? Or maybe there is even a quick material property i can enable that works with video textures? I’ll take any advice or suggestions any of you can give. @Evgeni_Popov you were a massive help in designing this system in the first place so maybe you’d like to chime in with some advice? Thanks to all in advance.

You can add the bigDisc mesh to the excluded mesh list. That way, you don’t need to set alpha properties, even for the plain texture case:

1 Like

Ok thanks so much for the reply @Evgeni_Popov Unfortunately I don’t know if the above playground necessarily addresses the whole issue. The desired behaviour i’m looking to accomplish is to NOT show the highlighted ring behind the video circle while at the same time making sure it still shows up behind other meshes. Adding bigDisc to the excluded mesh list does indeed fix the filled black circle problem but also doesn’t illicit the type of overall behaviour I’m looking for as it then shows up behind the video circle.

hmmm for some reason adding the hasAlpha property to the video texture before it is applied to the material seems to illicit the same effect as when used on an image material. Have no idea why that is the case but it has seemed to address the issue I’m facing. Would love to know if there is a better way for me to do this though.