OrderIndependentTransparency and HighlightLayer issue

Hi everyone,

I’d like to have a Highlight layer effect on translucent objects rendered with OrderIndependentTransparency activated. The highlight effect does not seem to be applied correctly in this case (compared to when OrderIndependentTransparency is not activated).

Steps to reproduce the bug:

  • Open this Babylon activity: https://playground.babylonjs.com/#TQ2MVI#2
  • Notice that the Highlight effect is correctly applied on one of the spheres.
  • Press [Space] key to activate the OrderIndependentTransparency rendering for the scene.

Expected:

  • The hilight effect is the same as before.

Observed:

  • The highlight effect is applied on the whole sphere (not just its outer border).

This looks like a bug to me, but maybe there’s some rendering or materials configuration workaround that could work ? I’ve already tried lots of different things with no succerss so far.

Unfortunately, the depth peeling renderer used by OIT is not compatible with the highlight layer. All techniques using the stencil buffer won’t work, for that matter (so outline rendering won’t work either).

I can’t see a way to do it, because the depth peeling renderer is processing all the transparent objects together, so it’s not possible to apply some special effects to some objects and not to some others in this process.

I was afraid it would be that but waited for confirmation from the expert.
So I guess back to the ‘old’ method of ordering these manually. :sweat_smile: using the ‘alphaIndex’, coupled with needDepthPrePass on materials and further ‘culling’ methods and stuff.
I just hope you don’t have all too many of these. Honestly, with just a few, it’s ez. With a lot, it can become somewhat tedious.
Oh and btw, welcome to the Community. I hope that despite of the deceiving answer above you are still enjoying the many amazing aspects of BJS,
GL and have a great day :sunglasses:,

Thanks Evgeni and Mawa for the welcome and quick answers here :slight_smile:

I’m working on an educational geometry teaching application, where seeing the intersection of solid objetcs can be interesting for the students (and of course they can do anything and place as many intersecting objets as they want :slight_smile: !).

The original version of our application was using OpenGL 1.0 (so we did the translucent rendering using geometric splitting and then sorting, which was quite CPU costly). We switched to Bablyon when we ported our application to the Web, and that allowed us to simplify a lot our code, and we are quite happy with it so far.

OIT implementation in Babylon is quite appealing for us. It works well and is quite fast, so I think we’ll stay on it and try to have our own “hilight” mechanism. We did that in the past in OpenGL by rendering the selected objects “expanded” in a stencil, then rendering them again “unexpanded” in order to remove the inner parts of the highlight. I’m pretty sure this could be redone (and probably optimized using shaders today), in a separate stenil that would then be rendered on top of the final scene. Of course that requires additionnal rendering steps. When writing that I realize that this is maybe the way Babylon works for the HighlightLayer (stencil rendering then shader to create the borders ?) :slight_smile:

I’m not completely sure of the best way to combine the “natural” Babylon scene-rendering with OpenGL / stencils / etc… lower level code (that’s something we did not had to use so far). I guess I’ll see and come back with questions here, but of course any hints on the best way to start that would be greatly appreciated :slight_smile:

I understand. In this case, may be you should take a look at NME (the node material editor).
You could likely fairly easily create your shader with low impact on performance.
There are already a number of base examples available you could may be use as a start. Unfortunately, they are all a bit dispatched here and there. I know there’s a project on with V6 to consolidate all NME examples. Meanwhile, you would just need to make a search in this forum and come back here with your questions.
The team and community has some incredibly knowledgeable and willing to help individuals you can cc to help you with creating this shader that would match your needs.

Edit: Oh, And I forgot this GLSL editor that just came in lately. May be this could also help.

Thanks for the directions mawa, I’ll check that. The GLSL editor looks impressive !

Also, I’m just curious : there must be a good reason, but I do not fully understand what’s preventing Babylon to handle Depth Peeling and Highlight layers at the same time ?

The way I woud l naively have done that:

  1. Render the whole scene using Depth Peeling for translucent objects. So far so good.
  2. Render only the hilighted objets, as opaque, in a stencil buffer without ZBuffer testing (for our application we do not mind seeing the highlighted outline “behind walls” but that might not be true for FPS of course :)). For textured objets, we probably need to define an alpha cut-off threshold (if the stencil is only 1 bit).
  3. Apply a shader on the stencil to create the outline.
  4. Render the stencil.

The “outline” stencil is separated with this approach (maybe that’s what’s blocking in Baylon ?), and this involves an extra-rendering step.

Maybe there’s a documentation describing the Babylon pipeline ? I never had to read it so far because our port to Babylon went pretty smoothly :slight_smile:

Here’s a workaround to do it in your example:

It renders a copy of the sphere into the stencil buffer to make sure this buffer has the right values (the same values the highlight layer write). This rendering must occur after all other rendering have been done (most importantly after the transparent rendering) but before the post processing are applied (which is where the highlight effect is performed), so scene.onAfterRenderingGroupObservable is a good place.

Also, a side effect of using the depth peeling renderer is that the stencil buffer for the default frame buffer is not cleared anymore (it’s an offline render target which is cleared instead), so we have to issue a clear call ourselves at the start of the frame.

OMG, thanks a lot Evgeny for the workaround, everything with only 18 extra lines :slight_smile: !!

I’ll integrate that in our engine and let you know of our results, but that should be a piece of cake now.

Thanks a lot again !