【问题标题】:Babylon.js: rendering order of instancesBabylon.js:实例的渲染顺序
【发布时间】:2019-10-28 20:26:04
【问题描述】:

目前我正在尝试 Babylon.js,因为到目前为止我只使用过 Threejs,而且 Babylon.js 已经多次推荐给我。

我开发了一款回合制策略游戏,其中玩家的游戏区域由不同材料(白色、黑色、棕色)的各个区域组成。

使用 Threejs,我将具有相同材质的不同字段合并到一个对象中,以将绘制调用减少到 3。我在 Babylon.js 文档中读到,使用实例非常简单。这就是我以这种方式实现游戏场的原因:

  1. 加载使用 gltf/glb 格式的 Blender 导出的场网格。克隆 3 次以应用 3 种不同的材料
import { SceneLoader, StandardMaterial, Color3, Vector3 } from 'babylonjs';
import 'babylonjs-loaders';

...

SceneLoader.ImportMesh('', 'models/', 'field.glb, scene, group => {
    group.forEach((mesh, i) => {
        if (mesh.name !== '__root__') {
            let brown = mesh.clone('FIELD_BROWN');
            let brownMaterial = new StandardMaterial("brownField", scene);
            brownMaterial.diffuseColor = new Color3.FromHexString("#824529");
            brown.material = brownMaterial;
            brown.isVisible = false;

            let black = mesh.clone('FIELD_BLACK');
            let blackMaterial = new StandardMaterial("blackField", scene);
            blackMaterial.diffuseColor = new Color3.FromHexString("#3E211B");
            black.material = blackMaterial;
            black.isVisible = false;

            mesh.name = 'FIELD_WHITE';
            let whiteMaterial = new StandardMaterial("whiteField", scene);
            whiteMaterial.diffuseColor = new Color3.FromHexString("#F8DBAF");
            mesh.material = whiteMaterial;
            mesh.isVisible = false;
        } else {
            mesh.isVisible = false;
        }
    });
});
  1. 在另一个函数中构建游戏场
import { Vector3, Color3 } from 'babylonjs';

...

playerField.grid.forEach((cell, i) => {
    let pivot;            

    if (cell.type === BoardCellTypes.BROWN) {
        pivot = this.scene.getMeshByName('FIELD_BROWN');
    } else if (cell.type === BoardCellTypes.BLACK) {
        pivot = this.scene.getMeshByName('FIELD_BLACK');
    } else {
        pivot = this.scene.getMeshByName('FIELD_WHITE');
    }

    let field = pivot.createInstance(cell.row + ':' + cell.col);
    field.position = fieldPosition.add(new Vector3(cell.row * this.fieldSize, 3, cell.col * this.fieldSize));
});

生成的场景如下所示:

当我调整窗口大小时,所有棕色和黑色字段都会消失。

我还在控制台中看到此警告(256 次):

[.WebGL-0x7fe20b9b3400]GL 错误:GL_INVALID_OPERATION:glDrawElementsInstancedANGLE:尝试访问属性 4 中超出范围的顶点

我是否使用了错误的概念,或者我对使用 Babylon.js 的工作方式有错误的心智模型?我认为这可能是渲染的问题,但我对警告和消失的字段感到非常困惑。感谢您的任何帮助!

【问题讨论】:

    标签: javascript babylonjs gltf


    【解决方案1】:

    我已经通过删除clone 方法并多次导入网格解决了这个问题:

    SceneLoader.ImportMesh('', 'models/', 'field.glb, scene, group => {
        group.forEach((mesh, i) => {
            if (mesh.name !== '__root__') {
                mesh.name = 'FIELD_BROWN';
                let brownMaterial = new StandardMaterial("brownField", scene);
                brownMaterial.diffuseColor = new Color3.FromHexString("#824529");
                mesh.material = brownMaterial;
                mesh.isVisible = false;
            }
    });
    
    SceneLoader.ImportMesh('', 'models/', 'field.glb, scene, group => {
        group.forEach((mesh, i) => {
            if (mesh.name !== '__root__') {
                mesh.name = 'FIELD_BLACK';
                let blackMaterial = new StandardMaterial("blackField", scene);
                blackMaterial.diffuseColor = new Color3.FromHexString("#3E211B");
                mesh.material = blackMaterial;
                mesh.isVisible = false;
            }
    });
    
    ...
    

    这对我有用,它消除了警告和奇怪的行为。但我不明白为什么。因此,我将接受解释了使用 Babylon.js 进行克隆的副作用的答案

    【讨论】:

      【解决方案2】:

      事实上,在调整大小后,只有最后一个网格是可见的。 似乎您需要在克隆的网格上调用 makeGeometryUnique 。此方法会为网格创建非共享的特定几何图形。

      类似问题 - https://forum.babylonjs.com/t/creating-instances-of-clones-of-a-mesh/536

      游乐场链接 - https://playground.babylonjs.com/#QXZ4KH#3

      【讨论】:

        猜你喜欢
        • 2018-10-18
        • 2019-02-24
        • 1970-01-01
        • 1970-01-01
        • 2013-07-05
        • 2016-08-08
        • 1970-01-01
        • 1970-01-01
        • 2021-02-18
        相关资源
        最近更新 更多