linkWithMesh method slows down FPS on Safari and Firefox

Hello,
i’m creating around 25 2d targets and linking them with 3d meshes to position them following the 3d coordinates.
I’m using AdvancedDynamicTexture with a Button added to its control and i’ve linked the button to the corresponding mesh using the method “linkWithMesh()”
On chrome it works great, but it drastically lowers the FPS with Safari and Firefox (it drops around 5-10 FPS, while without calling that method it’s over 200 FPS).

Did someone encounter this problem using linkWithMesh method?
Do you know by any chance what could higher the FPS without removing it or using an alternative way?

I tried insert some optimization to the scene →
this.scene.blockMaterialDirtyMechanism = true;
this.scene.autoClear = false;
this.scene.autoClearDepthAndStencil = false;
this.engine.setHardwareScalingLevel(1);
but they don’t affect the performance, only removing linkwithmesh it starts reacting in the correct way.

Thank you

DO you mind creating a repro (simple) in the PG. I will work on finding what is the bottleneck

Hello @Deltakosh, thank you for your answer.

I was creating the playground, but as i was finishing it, i found what could have caused the problem of reducing FPS in Safari and Firefox.

This is the playground → https://playground.babylonjs.com/#DQKYG5#1

I need to bring outside of the for cycle (in my original case, a Class) line 180 and 181 (AdvancedDynamicTexture), cause otherwise it will create 23 (number of targets) layers of UI, is that correct?

I misunderstood the functionality of that element and thought it was necessary to associate a new one to every buttons.

If you have any other suggestion or consideration, feel free to share them with me :slight_smile:

Haha see? This is exactly why we ask for repro in the PG :slight_smile:
YOu are totally right: you only need one ADT (it is responsible for the optimizations and cache)

good job buddy!

You’re absolutely right, it does tank performance on Firefox and significantly reduces performance on other browsers.
I’ve recorded a video with the playground you posted, but I’ve modified it (the ADT is outside the for loop). This is the playground I was using for the recording: https://playground.babylonjs.com/#DQKYG5#2

In the video I ran the playground on both Firefox and Chrome. Both with and without linkWithMesh commented. In my current freelance project I’m experiencing the same issue, but due to the complexity of my scene fps on Firefox tanks to 10fps, while Chrome is a stable 40fps.

Because I’m using a gaming laptop (Windows 10) for this recording I’m looking into the absolute FPS in the inspector. The results are as follows:

  • Firefox_linkToMeshEnabled - 80-83 absolute fps (bottom right corner states 35-45fps)
  • Firefox_linkToMeshDisabled - 1151 absolute fps (stable 60)
  • Chrome_linkToMeshEnabled - 255 absolute fps (stable 60)
  • Chrome_linkToMeshDisabled - 1k absolute fps (stable 60)

This is the video recording: https://youtu.be/WSi0y8nKnYI

There’s another thread with a similar discussion (this link opens in the same window on the forum, so ctrl+click it): https://forum.babylonjs.com/t/does-linkwithmesh-have-serious-performance-issues-on-mobile-devices/4692

In that thread @Deltakosh concludes it’s a Firefox bug and @ManuelRauber implements his own solution to convert 3D position to 2D GUI position.

It turns out it’s quite trivial to implement custom projection from 3D to GUI: https://playground.babylonjs.com/#XCPP9Y#5757

let guiPos;
let targetPosition = sphere.position;
let identity = BABYLON.Matrix.Identity();
let sceneMatrix = scene.getTransformMatrix();
let camViewport = camera.viewport;

scene.registerBeforeRender(function() { 
    guiPos = BABYLON.Vector3.Project(
            targetPosition, 
            identity, 
            sceneMatrix , 
            camViewport ;
    rect1.top = (guiPos.y * 100) + "%"
    rect1.left = (guiPos.x * 100) + "%"
});