Unexpected mesh behaviour in scene with glow layer and frozen active meshes

Hello! I encountered two strange issues with glow layer in combination with scene.freezeActiveMeshes.

First issue:

  1. Have a glow layer in the scene
  2. Create two instanced meshes, with backFaceCulling = false and mirror one of them (e.g. mesh.scaling.x = -1)
  3. Call scene.freezeActiveMeshes()
    Result: The instanced mesh disappears

Second issue:

  1. Have a glow layer in the scene
  2. Create a mesh and use a clip plane to clip this specific mesh
  3. Call scene.freezeActiveMeshes()
    Result: The mesh is not clipped anymore

Here is a playground replicating these two issues:
https://playground.babylonjs.com/#JDM7P3

It looks like if one of the mentioned steps is skipped, everything is working fine. I would like to know what you think about these. Maybe there are things I missed, or workarounds, but nevertheless, this behaviour is still unexpected to me.

1 Like

Yup this highly sounds like side effects of freezing which prevents computing back the list :frowning:

@Evgeni_Popov , can you have a look into those ?

Looking into it.

2 Likes

Here’s the PR to fix the sphere disappearance:

Regarding the cylinder that is not clipped anymore when in frozen mode, that’s a side effect of the frozen mode itself because when in this mode a material is not re-evaluated and is returned in the state it was at freezing time:

public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances: boolean = false): boolean {
    if (subMesh.effect && this.isFrozen) {
        if (subMesh.effect._wasPreviouslyReady) {
            return true;
        }
    }
   ...

The thing is that the material is returned as it was compiled by the glow layer sub-system because this code is executed first. And because the clip planes are not in effect in the glow layer, you get a material without clip planes.

You can use a hack to set the clip planes in the glow layer:
https://playground.babylonjs.com#JDM7P3#4

It is using the onBeforeRenderObservable / onAfterRenderObservable observers of the RTT used by the glow layer (which is not directly visible to user code, hence the casting to any of the glow layer RTT). Note that this sets the clip planes for the entire glow layer, not only for the cylinder (it’s not possible to do it only for the cylinder in the context of the glow layer).

@Deltakosh / @sebavan There is not (won’t have) this problem with the WebGPU engine because what I’m currently doing in my PR (to support the fast path) is adding a new specific context each time a mesh is drawn, so we have a different context when drawing the mesh in the glow layer than when drawing it in the regular scene, meaning in frozen mode it will work as expected: I have just tested locally that with my current changes it does work in WebGPU.

I have a new feature property to enable this mode that is true only in WebGPU but maybe it would be beneficial to also enable it in WebGL to fix this problem (I have also tested locally that enabling this mode in WebGL fix the problem)? I did not enable it by default in WebGL because 1/ we didn’t need it (until now) and 2/ some checks are skipped when not in this mode so you could get some tiny perf gains by not enabling it.

Or maybe when the PR is merged we should document this new feature and explain that it can be used to fix some problems in WebGL (and still keep it disabled by default)?

Yup that !!! :slight_smile: you could add it to the glow layer documentation ? it is pretty edge case so I would prefer to target perf first and not introduce any perf regression on users updating.

I will do it, but note it’s not specific to the glow layer, that’s something that could happen with any sub-system that uses RenderTargetTexture internally.

1 Like