【问题标题】:Three.js memory allocation & workflow question三.js内存分配&工作流问题
【发布时间】:2021-02-02 04:12:59
【问题描述】:

假设我想制作 100 个对象 - 例如汽车,就像您在此处看到的那样:

这辆车目前由 5 个网格组成:一个黄色立方体和四个蓝色球体

我想知道的是,在内存管理/CPU 性能等方面,制造 100 辆或 500 辆此类汽车的最有效/正确的方法是什么。

我目前的做法如下:

  1. 创建一个名为“newCarGroup”的空 THREE.Group -
  2. 为车身创建黄色矩形网格 - 称为“carBodyMesh”
  3. 为轮胎创建四个蓝色球体网格,称为“tire1Mesh”、“tire2Mesh”、“tire3Mesh”和“tire4Mesh”
  4. 将车身和四个轮胎添加到“newCarGroup”
  5. 最后,在FOR 循环中,创建/实例化 100 个“newCarGroup”对象,将每个对象添加到 SCENE 的随机位置

代码如下。

它现在运行良好,但我想知道这是否是“正确”/最好的方法?
考虑一下我可能最终需要 1,000 辆汽车 - 或 5,000 辆汽车。那么这会正确扩展吗?

另外,我需要在汽车上添加更多对象:比如 4 个窗户 - 实际上是 6 个窗户,还包括前后挡风玻璃,然后是四个大灯等。 因此,仅最终的汽车对象就可能最终由 20 个或更多网格组成。

由于我对 THREE.JS 有点陌生,我想确保自己养成良好的习惯,并以正确的方式去做这类事情。

这是我的代码:

        function makeOneCar() {
            var newCarGroup = new THREE.Group();

            // 1. CAR-Body:
            const bodyGeometry = new THREE.BoxGeometry(30, 10, 10);
            const bodyMaterial = new THREE.MeshPhongMaterial({ color: "yellow" } ); 
            const carBodyMesh = new THREE.Mesh(bodyGeometry, bodyMaterial);

            // 2. TIRES:
            const tireGeometry = new THREE.SphereGeometry(2, 16, 16);;
            const tireMaterial = new THREE.MeshPhongMaterial( { color: "blue" } ); 
            const tire1Mesh = new THREE.Mesh(tireGeometry, tireMaterial);
            const tire2Mesh = new THREE.Mesh(tireGeometry, tireMaterial);
            const tire3Mesh = new THREE.Mesh(tireGeometry, tireMaterial);
            const tire4Mesh = new THREE.Mesh(tireGeometry, tireMaterial);

            // TIRE 1 Position:
            tire1Mesh.position.x = carBodyMesh.position.x - 11;
            tire1Mesh.position.y = carBodyMesh.position.y - 4.15;
            tire1Mesh.position.z = carBodyMesh.position.z + 4.5;

            // TIRE 2 Position:
            tire2Mesh.position.x = carBodyMesh.position.x + 11;
            tire2Mesh.position.y = carBodyMesh.position.y - 4.15;
            tire2Mesh.position.z = carBodyMesh.position.z + 4.5;

            // TIRE 3 Position:
            tire3Mesh.position.x = carBodyMesh.position.x - 11;
            tire3Mesh.position.y = carBodyMesh.position.y - 4.15;
            tire3Mesh.position.z = carBodyMesh.position.z - 4.5;

            // TIRE 4 Position:
            tire4Mesh.position.x = carBodyMesh.position.x + 11;
            tire4Mesh.position.y = carBodyMesh.position.y - 4.15;
            tire4Mesh.position.z = carBodyMesh.position.z - 4.5;

            // Putting it all together:
            newCarGroup.add(carBodyMesh);
            newCarGroup.add(tire1Mesh);
            newCarGroup.add(tire2Mesh);
            newCarGroup.add(tire3Mesh);
            newCarGroup.add(tire4Mesh);

            // Setting (x, y, z) Coordinates - RANDOMLY
            let randy = Math.floor(Math.random() * 10);
            let newCarGroupX = randy % 2 == 0 ? Math.random() * 250 : Math.random() * -250;
            let newCarGroupY = 0.0; 
            let newCarGroupZ = randy % 2 == 0 ? Math.random() * 250 : Math.random() * -250;

            newCarGroup.position.set(newCarGroupX, newCarGroupY, newCarGroupZ)

            scene.add(newCarGroup);
        }




        function makeCars() {
            for(var carCount = 0; carCount < 100; carCount ++) {
                makeOneCar();
            }
        }

【问题讨论】:

    标签: memory-management three.js


    【解决方案1】:

    我想知道这是否是“正确”/最好的方法?

    这是主观的。您说该方法非常适合您当前的用例,因此对于该用例来说,它很好。

    那么这会正确扩展吗?

    简单的答案是:不。更复杂的答案是:......不是真的。

    您正在重新使用几何图形和材质,这很好。但是您创建的每个Mesh 周围都有元信息,这会增加您的整体内存占用。

    此外,您添加的每个标准 Mesh 都会引发所谓的“绘图调用”,即 GPU 绘制特定形状。相反,请查看InstancedMesh。这允许 GPU 获得关于如何在整个场景中绘制形状的指令一次。是的,GPU 可以同时绘制所有立方体,而不是单独绘制每个立方体,它们甚至可以有不同的颜色和变换。这个类有一些限制,但它是理解实例化如何工作的一个很好的起点。

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 2011-03-18
      • 2015-02-06
      • 2021-05-04
      • 2021-06-30
      • 2011-05-17
      相关资源
      最近更新 更多