How do you reduce CPU usage using GLB files with animations?

Hi, I have the below code added on shopify,

I have tried to reduce the CPU usage and optimizing the scene but yet the CPU usage is really really high, is there a way to reduce the usage? I am currently hearing my fan go at really high speed.

The objects I’m using are GLB files which are 2MB each, with a HDR Texture environment also 3MB.
The objects pre-rendered animation as well.
Also the reason I have 2 canvases is that one of the object I have added a filter blur css as of the Website project design.

Please Kindly let me know if there is a way to have the CPU run smoothly with no lag.

Thank you

      //object1
      var engine;
      var scene;
      var camera;

      //3D object animation

      var canvas = document.getElementById("renderCanvas");

      var createDefaultEngine = function() {
        return new BABYLON.Engine(canvas, true, {
          preserveDrawingBuffer: true,
          stencil: true
        }, true);
      };


      var createScene = function() {
        scene = new BABYLON.Scene(engine);
        // Parameters : name, position, scene
        var camera = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene);
        // Targets the camera to a particular position. In this case the scene origin
        camera.setTarget(BABYLON.Vector3.Zero());
        //camera.setPosition(new BABYLON.Vector3(-15, 10, 10));

        // Attach the camera to the canvas
        // camera.attachControl(canvas, true);

    // Create a default skybox with an environment.
    //var hdrTexture = new BABYLON.CubeTexture.CreateFromPrefilteredData("https://cdn.shopify.com/s/files/1/0509/5351/9276/t/6/assets/environment.dds", scene);
    var hdrTexture = new BABYLON.HDRCubeTexture("{{ 'studio021.hdr' | asset_url }}", scene, 128, false, true, false, true);
    hdrTexture.gammaSpace = false;
    hdrTexture.anisotropicFilteringLevel = 1;

    scene.environmentTexture = hdrTexture;
    scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);

    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

    // Load model
    var assetsManager = new BABYLON.AssetsManager(scene);
    assetsManager.addMeshTask('', '', "https://cdn.shopify.com/s/files/1/0509/5351/9276/t/6/assets/", "EDEN_Grape-001_Animation006.glb", scene);

    assetsManager.onSuccess = function(task) {
      console.log('sucess');
    };
    assetsManager.onTaskSuccess = function(task) {

      var mesh = task.loadedMeshes[0];

      mesh.doNotSyncBoundingInfo = true;
      mesh.rotationQuaternion = null;
      mesh.rotation.y = -0.45;
      mesh.rotation.z = 0.45;
      mesh.rotation.x = -0.4;
      mesh.position.x = -4.5;
      mesh.position.y = -6;
      mesh.position.z = 7;
      $(window).on('scroll', function() {
        var top = $(window).scrollTop(),
          divBottom = $('.featured-collection').offset().top;
        if (divBottom > top) {
          mesh.rotation.y = -0.45;
          mesh.rotation.z = 0.45;
          mesh.rotation.x = -0.4;
          mesh.position.x = -4.5;
          mesh.position.y = -6;
          mesh.position.z = 7;
        } else {
          mesh.rotation.x = -0.35;
          mesh.rotation.y = 6.5;
          mesh.rotation.z = -0.3;
          mesh.position.x = 4.5;
          mesh.position.y = -4;
          mesh.position.z = 6.5;
        }
      });
    }
    assetsManager.load();
    scene.blockMaterialDirtyMechanism = true;
    scene.freezeActiveMeshes();
    scene.cleanCachedTextureBuffer();
    scene.clearCachedVertexData();
    var options = new BABYLON.SceneOptimizerOptions();
    options.addOptimization(new BABYLON.HardwareScalingOptimization(0, 1));
    // Optimizer
    var optimizer = new BABYLON.SceneOptimizer(scene, options);
    BABYLON.SceneOptimizerOptions.LowDegradationAllowed()
    BABYLON.SceneOptimizerOptions.ModerateDegradationAllowed()
    BABYLON.SceneOptimizerOptions.HighDegradationAllowed()
    scene.getEngine().onResizeObservable.add(() => {
      if (scene.getEngine().getRenderHeight() > scene.getEngine().getRenderWidth()) {
        // camera.fovMode = BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED;
      } else {
        camera.fovMode = BABYLON.Camera.FOVMODE_VERTICAL_FIXED;
      }
    })
    return scene;
  };


      engine = createDefaultEngine();
      if (!engine) throw 'engine should not be null.';
      scene = createScene();

      engine.runRenderLoop(function() {
        if (scene) {
          scene.render();
        }

      });

      // Resize
      window.addEventListener("resize", function() {
        engine.resize();
      });

      //object 2
      var engine2;
      var scene2;
      var camera2;

      //3D object animation

      var canvas2 = document.getElementById("renderCanvas2");

      var createDefaultEngine2 = function() {
        return new BABYLON.Engine(canvas2, true, {
          preserveDrawingBuffer: true,
          stencil: true
        }, true);
      };


      var createScene = function() {
        scene2 = new BABYLON.Scene(engine2);
        // camera2.noRotationConstraint = true;
        // This attaches the camera2 to the canvas2
        // camera2.attachControl(canvas2, true);

        // Parameters : name, position, scene2
        var camera2 = new BABYLON.UniversalCamera("UniversalCamera", new BABYLON.Vector3(0, 0, -10), scene2);
        // Targets the camera2 to a particular position. In this case the scene2 origin
        camera2.setTarget(BABYLON.Vector3.Zero());
        //camera2.setPosition(new BABYLON.Vector3(-15, 10, 10));

        // Attach the camera2 to the canvas2
        // camera2.attachControl(canvas2, true);


        // Create a default skybox with an environment.
        //var hdrTexture = new BABYLON.CubeTexture.CreateFromPrefilteredData("https://cdn.shopify.com/s/files/1/0509/5351/9276/t/6/assets/environment.dds", scene2);
        var hdrTexture = new BABYLON.HDRCubeTexture("{{ 'studio021.hdr' | asset_url }}", scene, 128, false, true, false, true);
        hdrTexture.gammaSpace = false;
        hdrTexture.anisotropicFilteringLevel = 1;

        scene2.environmentTexture = hdrTexture;
        scene2.clearColor = new BABYLON.Color4(0, 0, 0, 0);

        var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene2);
        // Default intensity is 1. Let's dim the light a small amount
        light.intensity = 2
        // Load model
        var assetsManager = new BABYLON.AssetsManager(scene2);
        assetsManager.addMeshTask('', '', "https://cdn.shopify.com/s/files/1/0509/5351/9276/t/6/assets/", "EDEN_Lemon-001_Animation006.glb", scene2);

        assetsManager.onSuccess = function(task) {
          console.log('sucess');
        };
        assetsManager.onTaskSuccess = function(task) {

          var mesh = task.loadedMeshes[0];

          mesh.doNotSyncBoundingInfo = true;
          mesh.rotationQuaternion = null;
          mesh.rotation.x = 0;
          mesh.rotation.y = 0.4;
          mesh.rotation.z = -0.5;
          mesh.position.x = 8;
          mesh.position.y = -6;
          mesh.position.z = 15;
          $(window).on('scroll', function() {
            var top = $(window).scrollTop(),
              divBottom = $('.featured-collection').offset().top;
            if (divBottom > top) {
              mesh.rotation.x = 0;
              mesh.rotation.y = 0.4;
              mesh.rotation.z = -0.5;
              mesh.position.x = 8;
              mesh.position.y = -6;
              mesh.position.z = 15;
            } else {
              mesh.rotation.x = -0.6;
              mesh.rotation.y = 0.1;
              mesh.rotation.z = 0.5;
              mesh.position.x = 5;
              mesh.position.y = 1.75;
              mesh.position.z = 15;
            }
          });
        }
        assetsManager.load();
        scene2.blockMaterialDirtyMechanism = true;
        scene2.freezeActiveMeshes();
        scene2.cleanCachedTextureBuffer();
        scene2.clearCachedVertexData();
        var options = new BABYLON.SceneOptimizerOptions();
        options.addOptimization(new BABYLON.HardwareScalingOptimization(0, 1));
        // Optimizer
        var optimizer = new BABYLON.SceneOptimizer(scene, options);
        BABYLON.SceneOptimizerOptions.LowDegradationAllowed()
        BABYLON.SceneOptimizerOptions.ModerateDegradationAllowed()
        BABYLON.SceneOptimizerOptions.HighDegradationAllowed()
        scene2.getEngine().onResizeObservable.add(() => {

          if (scene2.getEngine().getRenderHeight() > scene2.getEngine().getRenderWidth()) {
            // camera2.fovMode = BABYLON.Camera.FOVMODE_HORIZONTAL_FIXED;
          } else {
            camera2.fovMode = BABYLON.Camera.FOVMODE_VERTICAL_FIXED;
          }
        })

        return scene2;
      };


      engine2 = createDefaultEngine2();
      if (!engine2) throw 'engine2 should not be null.';
      scene2 = createScene();

      engine2.runRenderLoop(function() {
        if (scene2) {
          scene2.render();
        }

      });

      // Resize
      window.addEventListener("resize", function() {
        engine2.resize();
      });

Have you tried to profile your code with the performance tab of Chrome (for eg) to see what takes time?

Also, providing a repro will likely be mandatory as else it will be difficult to dig much further.

Do you mean by this profile?

I am new to the chrome inspect performance and reading the data but I have attached an image below to show if that is what you meant.

Hopefully it helps

Yes, I meant this tab. This doc can help you understand the data from this page: Get Started With Analyzing Runtime Performance  |  Chrome DevTools

Also, as I said, a repro in the playground will definitely be needed for people to help as performance problems are generally not really easy to pinpoint.

here is the repro in playground

https://www.babylonjs-playground.com/#NCYMP8

there are actually 2 different objects but on my actual code i have had to create 2 different canvases as I need to blur out using css. but on the play ground it shows only 1 of the objects.

please let me know where i might be going wrong

thank you

I am not seeing the same behavior at all on the playground:

the cpu is actually pretty low. Is that what you see as well ?

Nah mine is spiking up,

For you I think its because its rendering only one 3d object and not 2 on the playground that’s why its low on the cpu usage

Could you try in the playground to render the other model cause I guess there might be an issue with it in this case ?

I have rendered both the objects, but is it possible for the second object to be a different canvas?

as im required to blur out the second object, and multiple canvas means i think i need to add another engine which might be the cause of high cpu usage?

Yup I am thinking that the high CPU usage might be linked to 2 things:

  1. 2 engines but it should not impact as much
  2. CSS blur creating an overhead in your page

cause with both I am still at:

Maybe you could do it all in one engine using the Blur post process instead ?

The post blur is not working exactly as it should as its blurring the other object as well

Yup you would need to use it on a render target, it is what we use internally for blurring shadows or create the glow layer for instance.