【问题标题】:Three.js: how to combine several indices & vector arrays to oneThree.js:如何将多个索引和向量数组合并为一个
【发布时间】:2021-12-15 02:37:50
【问题描述】:

我正在尝试在 Three.js 中可视化一个大战略(EU4、CK3、HOI),例如地图。我开始为每个单元创建网格。结果很好(截图 1 和 2)。

分离网格方法 - 简单的土地/水区分:

分离网格方法 - 随机单元格颜色:

但是,如果有很多单元,性能就会成为问题(我在 10k 单元的情况下获得 15fps)。 为了提高性能,我想将所有这些单独的索引和顶点数组组合成 2 个大数组,然后将它们用于创建单个网格。

我正在遍历我的所有单元格,以将它们的索引、顶点和颜色推送到大数组中,如下所示:

 addCellGeometryToMapGeometry(cell) {

    let startIndex = this.mapVertices.length;
    let cellIndices = cell.indices.length;
    let cellVertices = cell.vertices.length;

    let color = new THREE.Color( Math.random(), Math.random(), Math.random() );

    for (let i = 0; i < cellIndices; i++) {
        this.mapIndices.push(startIndex + cell.indices[i]);
    }
    for (let i = 0; i < cellVertices; i++) {
        this.mapVertices.push(cell.vertices[i]);
        this.mapColors.push (color);
    }

}

然后我生成组合网格:

 generateMapMesh() {
    let geometry = new THREE.BufferGeometry();
    const material = new THREE.MeshPhongMaterial( {
        side: THREE.DoubleSide,
        flatShading: true,
        vertexColors: true,
        shininess: 0
    } );

    geometry.setIndex( this.mapIndices );
    geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.mapVertices, 3 ) );
    geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( new Float32Array(this.mapColors.length), 3 ) );

    for ( let i = 0; i < this.mapColors.length; i ++ ) {
        geometry.attributes.color.setXYZ(i,  this.mapColors[i].r,  this.mapColors[i].g,  this.mapColors[i].b);
    }

    return new THREE.Mesh( geometry, material );
}

不幸的是,结果令人失望: 虽然组合数组中的数据看起来不错,但只有每三个单元格被渲染一次。在某些情况下,这些指标似乎也会混淆。

组合方法 - 随机单元格颜色:

在其他类似主题中,建议合并现有网格。但是,我认为我的方法应该让我能够更好地了解实际发生的情况并可能节省性能。

我的代码有我看不到的明显缺陷吗?
还是我通常走错了路,如果是这样,应该怎么做?

【问题讨论】:

    标签: three.js mesh indices vertices


    【解决方案1】:

    我实际上在我的代码中发现了问题。错误:

    let startIndex = this.mapVertices.length;
    

    这里的问题是索引数组中的值总是引用一个顶点(它由顶点数组中的 3 个连续的数组条目组成)。正确:

    let startIndex = this.mapVertices.length / 3;
    

    此外,我应该只为每个顶点推送一种颜色,而不是每个顶点数组条目一种(= 每个坐标 1 个),但要确保 geometry.color 属性的 arraylength 保持不变。

    通过这 2 项更改,组合网格的结果看起来与为每个单元创建单独的网格时完全相同。性能提升令人印象深刻。

    单独的网格:

    • 渲染一帧需要 60 - 65 毫秒
    • 144 mb 分配内存

    组合网格:

    • 渲染一帧需要 0 - 1 毫秒
    • 58 mb 分配内存

    这里是固定的sn-ps:

     addCellGeometryToMapGeometry(cell) {
    
        let startIndex = this.mapVertices.length / 3;
        let cellIndices = cell.indices.length;
        let cellVertices = cell.vertices.length;
    
        console.log('Vertex-- maplength: ' + startIndex + ' celllength: ' + cellVertices);
        console.log('Indices -- maplength: ' + this.mapIndices.length + ' celllength: ' + cellIndices);
        console.log({cell});
    
        let color = new THREE.Color( Math.random(), Math.random(), Math.random() );
    
        for (let i = 0; i < cellIndices; i++) {
            this.mapIndices.push(startIndex + cell.indices[i]);
        }
        for (let i = 0; i < cellVertices; i++) {
            this.mapVertices.push(cell.vertices[i]);
            if (i % 3 === 0) { this.mapColors.push (color); }
        }
    
    }
    
    
     generateMapMesh() {
        let geometry = new THREE.BufferGeometry();
        const material = new THREE.MeshPhongMaterial( {
            side: THREE.DoubleSide,
            flatShading: true,
            vertexColors: true,
            shininess: 0
        } );
    
        geometry.setIndex( this.mapIndices );
        geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( this.mapVertices, 3 ) );
        geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( new Float32Array(this.mapVertices.length), 3 ) );
    
        for ( let i = 0; i < this.mapColors.length; i ++ ) {
            geometry.attributes.color.setXYZ(i,  this.mapColors[i].r,  this.mapColors[i].g,  this.mapColors[i].b);
        }
    
        return new THREE.Mesh( geometry, material );
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-15
      • 2015-06-30
      • 2017-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      相关资源
      最近更新 更多