SelectionOutlineLayer rendering abnormal in multi views

Hey, I recently tested many use cases of SelectionOutlineLayer. First, to process transparent meshes occlusion, I apply scene.enableDepthRenderer().forceDepthWriteTransparentMeshes = true to make it work normally. Since I opened this setting and used the multi views, I found that the outline would draw abnormal like below:


code:

When I use the real dom to create engine, it will render like this:


code:

Comparing two graphs and you will find some differences.
Any ideas about this issue?
Since the PG not support the multi views, I provide a demo here, you can try it!

outline-babylon.zip (21.6 KB)

1 Like

@noname0310 Would you help?:smiley:

I’ll check it out tomorrow. Thank you.
At a glance, it seems to be a hardware scaling issue.

3 Likes

:eyes: Any news?

Also, I found that the HighlightLayer would blink at the very first render step in multi views. Maybe some issues related to the Layers or EffectLayers? What do you think @Evgeni_Popov ?

HighlightLayer in multi views:


HighlightLayer in real dom:

@Evgeni_Popov

The code is easy. Just replace the code I provided before.

let highlightLayer: Nullable = new HighlightLayer(“layer”, scene, {
renderingGroupId: 0
})

scene.onPointerPick = function (_, pickInfo) {
// if (!outlineLayer) {
// outlineLayer = new SelectionOutlineLayer(“selection_outline”, scene, {
// mainTextureRatio: 1,
// outlineMethod: Constants.OUTLINELAYER_SAMPLING_OCTADIRECTIONAL,
// });
// outlineLayer.outlineThickness = 3;
// outlineLayer.occlusionStrength = 0.5;
// }
// outlineLayer.clearSelection();
if (pickInfo.pickedMesh) {
highlightLayer.addMesh(pickInfo.pickedMesh as Mesh, Color3.Red())
// outlineLayer.addSelection(pickInfo.pickedMesh);
}
}

If I make the virtualDom’s width and height equal to the real dom, all things seem normal.

I tested it, but the issue you mentioned does not reproduce in Microsoft Edge on Windows or Firefox.

Sorry, I used it in MacOS Edge

Maybe you need to change your device scale to something other than 100% @noname0310

I test it on Windows. If I opened the dev panel, it seems normal. If I closed the dev panel, and refresh the page, it‘s still abnormal.

I know what happened, do not let your page too small, make it fill your device.

Another issue that the SelectionOutlineLayer would not correctly process occlusion when a mesh with visibility 0 even if the depthRenderer.forceDepthWriteTransparentMeshes enabled.
But a mesh with material.alpha 0, it handles correctly.

Issue graph:

PG:

@noname0310

I found that the clientRect of the canvas which used to initialize the Engine would affect the EffectLayer render when rendering multi views. I debug a lot and I still don’t know why. @Evgeni_Popov

I can reproduce artifacts with the outline layer in the multi-views case:

That’s because the depth renderer is created right from the start by the scene.enableDepthRenderer().forceDepthWriteTransparentMeshes = true; call, and at this time, the current canvas size is 400x400 (the virtualDom size). The size will only be updated later on, when we first render to the view.

A simple fix is to move scene.enableDepthRenderer() just before the initialization of the selection outline layer, inside the scene.onPointerPick function.

Yes, in multi-views mode we do this:

    if (view.customResize) {
        view.customResize(canvas);
    } else {
        // Set sizes
        const width = Math.floor(canvas.clientWidth / this._hardwareScalingLevel);
        const height = Math.floor(canvas.clientHeight / this._hardwareScalingLevel);

        const dimsChanged = width !== canvas.width || parent.width !== canvas.width || height !== canvas.height || parent.height !== canvas.height;
        if (canvas.clientWidth && canvas.clientHeight && dimsChanged) {
            canvas.width = width;
            canvas.height = height;
            this.setSize(width, height);
        }
    }

It rescales the parent canvas (the canvas you pass when you create the engine) to the same dimensions than than the view canvas (this.setSize does that).

If it’s a problem, you can try to use your own resize strategy by passing a customResize function when you register the view.

1 Like

That explains, Thanks! What about the HighlightLayer blinking at the very fisrt render step?

It’s the same reason: because the highlight layer is created with the default 400x400 dimensions, the first time the layer must render, it recreates a number of resources (texture, post-processes), which generates this blinking.

As above, to fix the problem, you can create the highlight layer in scene.onPointerPick the first time a mesh is picked.

Continuing the discussion from SelectionOutlineLayer rendering abnormal in multi views:

What about this? I think depth renderer may not process the mesh visibility with zero value right?

@Evgeni_Popov Is tha on purpose? You can see the outline get dark when it’s in front of other meshes which should be dealed with depth render forceWriteTransparentMeshesDepth.