Babylon.js: порядок отображения экземпляров - PullRequest
1 голос
/ 14 июня 2019

В данный момент я пробую Babylon.js, потому что я до сих пор работал только с Threejs, а Babylon.js был рекомендован мне несколько раз.

Я разрабатываю пошаговую стратегическую игру, в которой у игроков есть игровые поля, состоящие из отдельных полей, различающихся по материалу (белый, черный, коричневый).

Используя Threejs, я объединил различные поля с одним и тем же материалом в один объект, чтобы уменьшить количество вызовов отрисовки до 3. Я прочитал в документации Babylon.js, что использовать экземпляры довольно просто. Вот почему я реализовал игровое поле следующим образом:

  1. Загрузка поля поля, экспортированного с помощью blender в формате gltf / glb Клонирование 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));
});

Получившаяся сцена выглядит так:

Maybe wrong rendering order

Когда я изменяю размер окна, все коричневые и черные поля исчезают.

Я также вижу это предупреждение в своей консоли (256 раз):

[. WebGL-0x7fe20b9b3400] ОШИБКА GL: GL_INVALID_OPERATION: glDrawElementsInstancedANGLE: попытка доступа к вершинам вне диапазона в атрибуте 4

Использую ли я неправильную концепцию, или у меня неправильная ментальная модель того, как все работает, используя Babylon.js? Я думаю, что это может быть проблемой рендера oder, но я очень запутался в предупреждениях и исчезающих полях. Спасибо за любую помощь!

1 Ответ

0 голосов
/ 15 июня 2019

Я решил проблему, удалив методы 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

...