添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Hi guys!

I was experiencing very low FPS (5-10) when using Vue instead of steady 60 FPS on the same scene using a plain HTML page. I was passing the engine object to the parent component to get the fps, that was the issue.

The solution is not to Ref and/or emit the BabylonJS engine and/or scene object. (in other words, do not make them reactive)

I didn’t dig deeper, but I think it causes multiple calls of the renderLoop or something similar.

EDIT: repo demonstrating the issue: GitHub - RolandCsibrei/quasar-vue-bjs-low-fps: Demonstrates low FPS in Quasar combined with BabylonJS.

EDIT2: Official BabylonJS + Vue documentation

You have to disconnect BJS from the VUE state and not let Vue touch any of the BJS objects or it will chain and try to make everything reactive every frame.

You have to make a communication bus that separates the BJS data from the react elements.

Just output the BJS object after you pass a param to make something on it reactive and look at the listeners its binding, you will see its toxic AF and its doing that every frame.

Hello,
my post is an advice for others, as you can read, I already solved the issue by not making the BJS Engine object reactive.

Thank you!

Hi there!
Yes, I did exactly the same. The GUI is based on Quasar/Vue2 and I introduced a Puppeteer class which serves as an interface between BJS and Quasar and simply translates method calls from the GUI to messages sent/received to/from the BJS part of the application. The GUI doesn’t know anything about BJS, and BJS doesn’t know anything about the GUI part, the Puppeteer is the bridge. The cool thing about this is, that I could move the BJS scene into a web worker.

Thanks for your response!

How can I understand this (you must disconnect BJS from Vue state, and Vue is not allowed to touch any BJS object). Now I define all BJS objects in methods. I use Vue, and I don’t bind any this, but FPS is still very low. I can keep FPS stable at 60 with H5. Can you give me some guidance.
This is my code, from initialization to rendering are completed in this method, without binding any this
inittest () {
let canvas = document.getElementById(‘renderCanvas’)
let engine = new BABYLON.Engine(canvas, true, {
preserveDrawingBuffer: true,
stencil: true,
disableWebGL2Support: false

  let target = new BABYLON.Vector3.Zero()
  let position = new BABYLON.Vector3(0, 260, 300)
  let scene1 = new BABYLON.Scene(engine)
  scene1.useRightHandedSystem = true
  // This creates and positions a free camera1 (non-mesh)
  let arcCamera1 = new BABYLON.ArcRotateCamera('arcCamera1', 0, 2, 10, target, scene1)
  // This positions the camera1
  arcCamera1.setPosition(position)
  // This targets the camera1 to scene1 origin
  // arcCamera1.setTarget(BABYLON.Vector3.Zero());
  // This attaches the camera1 to the canvas
  arcCamera1.attachControl(canvas, true)
  arcCamera1.allowUpsideDown = false
  // arcCamera1.upperRadiusLimit = 400
  // arcCamera1.lowerRadiusLimit = 5
  // arcCamera1.maxCameraSpeed = 10
  arcCamera1.panningSensibility = 50 
  arcCamera1.panningInertia = 0 
  // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
  let light1 = new BABYLON.HemisphericLight('light', new BABYLON.Vector3(0, 1, 0), scene1)
  // let light2 = new BABYLON.HemisphericLight('hemi', new BABYLON.Vector3(0, 1, 0), _that.scene2);
  // Default intensity is 1. Let's dim the light a small amount
  // light1.intensity = 0.7;
  let importMeshs = []
  let gltfArr = [
    'https://models.babylonjs.com/seagulf.glb'
  // _that.createCameraSprite()
  gltfArr.forEach(item => {
    importMeshs.push(
      BABYLON.SceneLoader.ImportMeshAsync(null, item, '', scene1).then(res => {
          item.freezeWorldMatrix()
  Promise.all(importMeshs).then(res => {
    scene1.freezeActiveMeshes()
  scene1.debugLayer.show({
    embedMode: true
  const spriteManagerTrees = new BABYLON.SpriteManager('camerasManager', '/static/gltf/image/camera.png', 100, {
    width: 1024,
    height: 1024
  }, scene1)
  spriteManagerTrees.isPickable = true
  for (let i = 0; i < 20; i++) {
    // Mutliple trees
    const myCamera = new BABYLON.Sprite('cameras', spriteManagerTrees)
    myCamera.isPickable = true
    myCamera.useAlphaForPicking = true
    myCamera.position.x = i
    myCamera.position.y = 0
    myCamera.position.z = i
    myCamera.actionManager = new BABYLON.ActionManager(scene1)
  engine.runRenderLoop(function (res) {
      scene1.render()
1623721035(1)1664×918 98.8 KB

When I added the sprites, the number of times I drew kept rising
1623721219(1)1296×915 136 KB

Hello, the problem is not VUE, but your code:

Comment out line 99, 100 amd 101 and you will en up with 3 draw calls.

      // Promise.all(importMeshs).then(res => {
      //   scene1.freezeActiveMeshes();
      // });

You can freeze the mesh when iterating the loaded meshes, add this at line 80:
item.freezeWorldMatrix()

I didn’t dig deep, but you have a cyclic condition somewhere.

It doesn’t seem to be the problem
// Promise.all(importMeshs).then(res => {
// scene1.freezeActiveMeshes();
// });
I have created 300 new spheres, and the number of drawing times does not increase all the time. The number of frames remains at about 50. I don’t know if it’s the problem of sprites, but it’s not very similar. Because I draw 200000 sprites alone, and the number of frames can reach 60. As long as the sprites and the imported gltf are used together, the number of drawing times will increase all the time, and the number of frames will drop slowly, Until 0 to 1 frames per second
1623726834(1)1222×908 124 KB

I don’t know how to upload the model, and it’s very big. I found someone else’s model. You see, the genie is rendering all the time. If you don’t add scene. Freezeactivemeshes(), it won’t render all the time
https://playground.babylonjs.com/#IQJ1BZ#1

First of all, I import the gltf file. I have to use scene. Freezeactivemeshes() to increase my frame count. Then I use sprites. However, when using gltf and sprites together, the rendering times keep increasing, and then the frames will drop slowly. I can’t find a better way to improve my frame count except through scene. Freezeactivemeshes()
image1812×769 70.2 KB

You can optimize you scene (as far as I know) tweaking these:

Screenshot_17873×427 31.2 KB

If you a have a lot of meshes, you can use Instances or ThinInstances to juice more out of your GPU. Just check out the BJS documentation.