基于 BufferGeometry 的 Three.js 网格没有出现 [英] Three.js mesh based on BufferGeometry not appearing

查看:39
本文介绍了基于 BufferGeometry 的 Three.js 网格没有出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Three.js & 开发 WebGL 游戏我决定从我的(工作)常规 THREE.Geometry 解决方案切换到 THREE.BufferGeometry 实现.我搞砸了,因为网格没有绘制.我在下面给出了我的代码的相关部分.如果我切换到常规几何图形,则一切正常.

I'm working on a WebGL game using Three.js & I've decided to switch to a THREE.BufferGeometry implementation from my (working) regular THREE.Geometry solution. I'm messing something up, because the mesh does not draw. I've given the relevant parts of my code below. If I switch to a regular geometry, everything works fine.

这是一个基于体素的游戏,我已经预先创建了每个立方体的每个面作为常规的THREE.Geometry.positionVertices 函数从每个面几何中获取顶点和面,将它们定位到对应于体素,并为 THREE.BufferGeometry 生成缓冲区数据.没有错误或警告,最终的网格没有出现.我怀疑我的问题与 Three.js 关系不大,更多是因为我对 3D 图形编程的理解有限.我现在最好的猜测是它与索引不正确有关.如果我删除索引,对象就会出现,但一半三角形的法线方向相反.

It's a voxel based game and I've pre-created each face of each cube as a regular THREE.Geometry. The positionVertices function takes the vertices and faces from each face geometry, positions them so that they correspond to the voxel, and generates the buffer data for the THREE.BufferGeometry. There are no errors or warnings, the final mesh just doesn't appear. I suspect my problem has less to do with Three.js and more with my limited understanding of 3D graphics programming. My best guess right now is that it has something to do with the indexes not being correct. If I remove the indexes, the object appears, but half of the triangles have their normals in the opposite direction.

Chunk.prototype.positionVertices = function( position, vertices, faces, vertexBuffer, indexBuffer, normalBuffer, colorBuffer ) {
    var vertexOffset = vertexBuffer.length / 3;
    for( var i = 0; i < faces.length; ++i ) {
        indexBuffer.push( faces[i].a + vertexOffset );
        indexBuffer.push( faces[i].b + vertexOffset );
        indexBuffer.push( faces[i].c + vertexOffset );

        normalBuffer.push( faces[i].vertexNormals[0].x );
        normalBuffer.push( faces[i].vertexNormals[0].y );
        normalBuffer.push( faces[i].vertexNormals[0].z );

        normalBuffer.push( faces[i].vertexNormals[1].x );
        normalBuffer.push( faces[i].vertexNormals[1].y );
        normalBuffer.push( faces[i].vertexNormals[1].z );

        normalBuffer.push( faces[i].vertexNormals[2].x );
        normalBuffer.push( faces[i].vertexNormals[2].y );
        normalBuffer.push( faces[i].vertexNormals[2].z );
    }

    var color = new THREE.Color();
    color.setRGB( 0, 0, 1 );
    for( var i = 0; i < vertices.length; ++i ) {
        vertexBuffer.push( vertices[i].x + position.x );
        vertexBuffer.push( vertices[i].y + position.y );
        vertexBuffer.push( vertices[i].z + position.z );

        colorBuffer.push( color.r );
        colorBuffer.push( color.g );
        colorBuffer.push( color.b );
    }
};

// This will need to change when more than one type of block exists.
Chunk.prototype.buildMesh = function() {

    var cube = new THREE.Mesh();
    var vertexBuffer = []; // [0] = v.x, [1] = v.y, etc
    var faceBuffer = [];
    var normalBuffer = [];
    var colorBuffer = [];
    for( var k = 0; k < this.size; ++k )
    for( var j = 0; j < this.size; ++j )
    for( var i = 0; i < this.size; ++i ) {
        // Iterates over all of the voxels in this chunk and calls
        // positionVertices( position, vertices, faces, vertexBuffer, indexBuffer, normalBuffer, colorBuffer ) for each face in the chunk
    }

    var bGeo = new THREE.BufferGeometry();

    bGeo.attributes = {

        index: {
            itemSize: 1,
            array: new Uint16Array( faceBuffer ),
            numItems: faceBuffer.length
        },
        position: {
            itemSize: 3,
            array: new Float32Array( vertexBuffer ),
            numItems: vertexBuffer.length
        },
        normal: {
            itemSize: 3,
            array: new Float32Array( normalBuffer ),
            numItems: normalBuffer.length
        },
        color: {
            itemSize: 3,
            array: new Float32Array( colorBuffer ),
            numItems: colorBuffer.length
        }
    }


    var mesh = new THREE.Mesh( bGeo, VOXEL_MATERIALS["ROCK"]);

    return mesh;
}

推荐答案

我需要在几何上设置单个偏移量.

I needed to set a single offset on the geometry.

    bGeo.offsets = [
        {
            start: 0,
            index: 0,
            count: faceBuffer.length
        }
    ];

修复了它.三角形仍然显示错误,所以我猜人脸搞砸了,但我可以很容易地弄清楚这一点.

Fixed it. The triangles are still displaying wrong, so I guess the faces are messed up, but I can figure that out easily enough.

这篇关于基于 BufferGeometry 的 Three.js 网格没有出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆