Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何计算three.js中闭合形状的法线?_Javascript_Three.js_Normals - Fatal编程技术网

Javascript 如何计算three.js中闭合形状的法线?

Javascript 如何计算three.js中闭合形状的法线?,javascript,three.js,normals,Javascript,Three.js,Normals,我正在尝试为自己的文件格式编写自己的网格导入程序。在我的文件格式中没有正常的数据。所以我试图计算一个闭合形状的法线,并将这些法线应用于网格 我的解决方案是为几何体的每个面计算一个法向量,并从这些面的中间沿法向量的方向创建一个光线投射。如果光线投射击中某个物体(另一个平面),则表示该方向在内部。在这种情况下,我翻转法线,如果它没有击中什么东西,我就让它这样 虽然我用这种逻辑编写了一个函数,但法线一点也不改变 function calculateNormals(object){

我正在尝试为自己的文件格式编写自己的网格导入程序。在我的文件格式中没有正常的数据。所以我试图计算一个闭合形状的法线,并将这些法线应用于网格

我的解决方案是为几何体的每个面计算一个法向量,并从这些面的中间沿法向量的方向创建一个光线投射。如果光线投射击中某个物体(另一个平面),则表示该方向在内部。在这种情况下,我翻转法线,如果它没有击中什么东西,我就让它这样

虽然我用这种逻辑编写了一个函数,但法线一点也不改变

        function calculateNormals(object){

            for (var i = 0; i < object.geometry.faces.length; i++) {
                var vertices= object.geometry.vertices;
                var face=object.geometry.faces[i];



                var a=vertices[face.a];
                var b=vertices[face.b];
                var c=vertices[face.c];

                console.log(face.a+" "+face.b+" "+face.c+" "+face.normal.z);
                console.log(face);
                console.log(face[4]);

                var edge0=new THREE.Vector3(0,0,0);
                edge0.subVectors(a,b);

                var edge1=new THREE.Vector3(0,0,0);
                edge1.subVectors(b,c);

                var planeNormal=new THREE.Vector3(0,0,0)
                planeNormal.crossVectors(edge0,edge1);

                // console.log(planeNormal);

                //Raycast from middle point towards plane nrmal direction
                //If it hits anything it means normal direction is wrong
                var midPoint=calculateMiddlePoint([a,b,c]);
                var raycaster = new THREE.Raycaster(midPoint,planeNormal);

                var intersects = raycaster.intersectObjects([object]);
                if(intersects.length==0){
                    console.log("Normal is true");
                    face.normal=planeNormal;
                }else{
                    console.log("Normal is wrong, you should flip normal direction, length: "+intersects.length);

                    console.log("Old face");
                    console.log(face.normal);

                    var newNormal=new THREE.Vector3(-1*planeNormal.x,-1*planeNormal.y,-1*planeNormal.z);
                    console.log(newNormal);
                    face.normal=newNormal;



                    console.log("new face");
                    console.log(face.normal);
                    console.log(face);
                }

                object.geometry.faces[i]=face;


                // console.log(object.geometry.faces);

            };


            return object;


        }
函数计算器数值(对象){
对于(变量i=0;i
Matey提出了一个很好的观点。缠绕顺序决定面法线,即哪一侧被视为“正面”。顶点法线用于着色(例如,使用
MeshPhongMaterial
)。如果顶点法线指向与面法线相反的方向,则最终会产生意外结果(从糟糕的着色到完全黑色的面)

总之,
Geometry
具有用于计算法线的辅助函数

(基于缠绕顺序)

(将顶点法线设置为与关联的面法线相同)

(将顶点法线设置为其周围面法线的平均值)


一旦你计算了法线,你可以第二次尝试修正它们,或者重新排序顶点(修正面法线),或者自己重新计算顶点法线。

你检查过这个答案吗:?谢谢,你的帖子让我了解了three.js如何计算法线