Is it possible to render a HighlightLayer on top of a normal Layer?

Heres my example: https://www.babylonjs-playground.com/#08A2BS#79

The problem is simple, the background layer is rendered on top of the HighlightLayer.

Is it possible to render the HighlightLayer on top of the background Layer?

The 4th parameter of the Layer constructor lets you put it in background/foreground:

https://www.babylonjs-playground.com/#08A2BS#80

1 Like

Thanks for checking it out :slight_smile:
Sadly, this is not the effect I’m trying to achieve. If possible, I’d like to render the background on top of the geometry, and the highlight on top of the background. So the render order would be like:

  1. HighlightLayer
  2. Background
  3. Sphere

Since the Layer doesn’t have support for renderingGroupId I’m at a loss. Got any clues?

You can use the renderTargetTextures and renderOnlyInRenderTargetTextures properties of the Layer class to get the layer applied only after a given render target texture has been generated and not at the end of the rendering pipeline:

https://www.babylonjs-playground.com/#08A2BS#83

There are two problems however:

  • you need to access the private property _mainTexture of the highlight layer to get the render target texture => this one is not really a problem, we could add an accessor for it
  • the layer is applied after the objects are generated into the highlight render texture but before the blur post processes are applied to this texture, which may not be what you want. I guess you would need the layer to be applied after all the highlight processing, meaning the rendering + blur post processing

Another solution that overcomes the 2nd problem is:

https://www.babylonjs-playground.com/#08A2BS#85

This time, renderOnlyInRenderTargetTextures is still true so that the layer is not rendered automatically at the end of the rendering pipeline, but we don’t add anything in renderTargetTextures because we are going to handle the rendering of the layer ourselves in the onAfterBlurObservable event of the highlight layer. This way, we can apply the layer after the blur has been done.

Couple of comments:

  • we must access the private _blurTexture property, but we can easily add an accessor if this solution works for you
  • there’s no predefined constant for the alpha state we need to setup, which is SRC_ALPHA/ONE_MINUS_SRC_ALPHA/0/1 => the 0/1 are the important ones, which are the factor applied on the source/destination alpha, meaning final alpha = 0 * src_alpha + 1 * destination_alpha = destination_alpha as we don’t want to tamper with the alpha values generated by the highlight layer, else the rendering would be screwed up. Because of that, we need a trick which is to set layer.alphaTest = true: this is only to avoid the layer rendering code to call setAlphaMode (and thus overwriting our values) because when layer.alphaTest = true no call to setAlphaMode is issued.

Hi @Evgeni_Popov thanks for your detailed response.

And sorry for my late response, I couldn’t find time to work on this little project.

I must say, I learned a lot from this! I’m fairly new to creating postprocess effects, and the fact that 99% of them use RenderTargetTextures clears up quite a lot for me.

I didn’t know the objects were still visible at the end of rendering the highlight texture. Is there a way to subtract these first? My ideal situation would be to only see an outline and the background and nothing else.

In the second situation, the only thing I see change is the outline color, is that the desired effect?

It might just be that creating an effect from scratch using a renderTarget and post effects might be the way to go since both solutions feel like hacking around since we need to change it’s core behaviour. Please correct me if I’m wrong.

PS: Accidentally made this effect by removing some of your lines and i love it :sweat_smile: https://www.babylonjs-playground.com/#08A2BS#87

You can disable color writing for the material of the sphere:

Look at the outline in the two PGs: the one in the first BG is larger and not very nice. The right one is the one from the second PG (wait a number of seconds to see the outline, as I fade the color from black ↔ red so that we can better see the thickness of the outline).

Well, we could say it’s a creative usage of the existing code :wink:

I see your added line with mat1.disableColorWrite, but sadly I don’t see anything changing.

Ah! Yes ofcourse I see it now. The only thing that I’d like fix about this is the removal of the actual sphere.

I wish added a picture earlier that shows what I want to achieve… that would’ve solved misconceptions right away… thanks again for your time.

Stubborn as I am, I’m trying to create this effect with a custom Postprocess like this PG: Babylon.js Playground

So I’m trying to run a fragment shader on the render target texture. However, when creating a BABYLON.PostProcess like the Blur PostEffects without defining a camera, I get an error saying it can’t read property createEffect of undefined. Do you have any clue on how to create one?

Edit: Missed an Engine reference!

Ok, seeing your picture it seems I did not understand what you wanted to achieve… I thought you wanted to blend the background after the highlight layer. In your picture there’s no blending: why not simply clearing the scene with a black color?

You should not see the sphere:

With disableColorWrite = true:

Without disableColorWrite = true:

1 Like

That’s odd, I was using Chromium on Linux where it still shows the sphere. Tried another browser and it does hide there. Guess I need to switch browsers :sweat_smile:

Because I have a use-case where it needs to fade out the rest of the scene.

One more question about renderTargets, is it only supported in WebGL2?

I seem to get a black image when try it out using WebGL1