three.js-使用mergeVertices()平滑法线;

three.js-使用mergeVertices()平滑法线;,three.js,Three.js,我正在尝试平滑使用THREE.OBJLoader加载的网格 正如您在这张原始图像中看到的,所有多边形都是面状的。我尝试过其他加载程序/格式,但得到了相同的结果。在深入研究之后,我发现一个可能的解决方案是在计算法线之前合并顶点。当我尝试此操作时,我在控制台中得到“TypeError:geometry.mergeVertices不是函数”。下面是代码,突出显示了我插入mergeVertices()函数的位置 var loader = new THREE.OBJLoader();

我正在尝试平滑使用THREE.OBJLoader加载的网格

正如您在这张原始图像中看到的,所有多边形都是面状的。我尝试过其他加载程序/格式,但得到了相同的结果。在深入研究之后,我发现一个可能的解决方案是在计算法线之前合并顶点。当我尝试此操作时,我在控制台中得到“TypeError:geometry.mergeVertices不是函数”。下面是代码,突出显示了我插入mergeVertices()函数的位置

        var loader = new THREE.OBJLoader();
        loader.load('../assets/models/nos2.obj', function (nos) {
        var material = new THREE.MeshLambertMaterial({color: 0xffffff, side:THREE.DoubleSide});

        nos.children.forEach(function (child) {
            child.material = material;
            child.geometry.mergeVertices(); /* ADDED MERGE WHICH GIVES ERROR */
            child.geometry.computeFaceNormals();
            child.geometry.computeVertexNormals();
        });

        nos.scale.set(300, 300, 300);
        nos.rotation.x = -0.3;
        scene.add(nos);}
我做错了什么?

函数.OBJLoader()创建一个BufferGeometry对象,而不是一个Geometry对象

函数.mergeVertices()对于BufferGeometry对象不可用-因此出现错误

至于解决在加载对象上实现平滑着色的问题,我自己仍在努力解决这个问题:-(

您可以探索的一种可能性是从BufferGeometry对象创建一个几何体对象;然后将mergeVertices()函数应用于该几何体,然后在最终网格中使用该几何体或(从几何体)创建一个新的BufferGeometry并在最终网格中使用它。请查看有关几何体和缓冲区几何体的文档

更新

用户SPACORUM发布了一个有用的(STL源文件)解决方案,该解决方案同样适用于OBJ源文件。代码需要通过删除/禁用以下三行进行更正:-

Sobject.computeBoundingBox();
Sobject.computeVertexNormals();
Sobject.center();
并将下一行修改为:-

var attrib = Sobject.geometry.getAttribute('position');

加载obj文件时发生此问题。如果您有3dsmax之类的3d软件:

打开obj文件, 转到多边形选择模式并选择所有多边形。 在“曲面属性”面板下,单击“自动平滑”按钮。 将模型导出回obj格式


现在,您不必调用函数geometry.mergeVertices()和geometry.computeVertexNormals();。只需加载对象并添加到场景中,网格就会平滑。

转换为常规几何体,应用所需内容并转换回缓冲区几何体。我使用的是ES6模块加载程序,因此没有三个。前缀

const tempGeo = new Geometry().fromBufferGeometry(child.geometry);

tempGeo.mergeVertices();

// after only mergeVertices my textrues were turning black so this fixed normals issues
tempGeo.computeVertexNormals();
tempGeo.computeFaceNormals();

child.geometry = new BufferGeometry().fromGeometry(tempGeo);