Three.js THREEJS:单独的几何体着色

Three.js THREEJS:单独的几何体着色,three.js,shadow,Three.js,Shadow,我使用three.js geometry使用faces构建了非常特殊的几何体。几何体表示相框的顶部。我的问题是,几何体只对地板上的一些面进行着色。对于平面或立方体,我没有这个问题 在图像上你会看到两个黑色的东西,这两个不同大小的相框有自己复杂的vertice+face结构,只投下部分阴影。尤其是里面的面没有投下阴影,所以阴影里面是空的。我在给MeshPhongMaterials着色时遇到了一些问题,但这不应该是这个问题的一部分。即使这里的图片不清晰,因为几何体是黑色的,但我确信这些面会关闭整个几

我使用three.js geometry使用faces构建了非常特殊的几何体。几何体表示相框的顶部。我的问题是,几何体只对地板上的一些面进行着色。对于平面或立方体,我没有这个问题

在图像上你会看到两个黑色的东西,这两个不同大小的相框有自己复杂的vertice+face结构,只投下部分阴影。尤其是里面的面没有投下阴影,所以阴影里面是空的。我在给MeshPhongMaterials着色时遇到了一些问题,但这不应该是这个问题的一部分。即使这里的图片不清晰,因为几何体是黑色的,但我确信这些面会关闭整个几何体

以下是线框的相同场景:

代码如下所示:

// Lights
var spotLight = new THREE.SpotLight( 0xFFD073, 3, 2000, Math.PI/3, 10 );        // hex, intensity, distance, angle, exponent
spotLight.position.set( 100, 1700, 100 );

spotLight.shadowCameraVisible = true;
spotLight.castShadow = true;

spotLight.shadowMapWidth = 2048;
spotLight.shadowMapHeight = 2048;
spotLight.shadowCameraNear = 25;
spotLight.shadowCameraFar = 4000;
spotLight.shadowCameraFov = 50;

spotLight.shadowDarkness = 0.5;
spotLight.shadowBias = -0.0002;

scene.add( spotLight );


// build geometry from vertices and faces
function buildGeometry(vertices, faces) {
    var geo = new THREE.Geometry();

    //vertices
    for(var i = 0; i < vertices.length; i++) {
        geo.vertices.push( new THREE.Vector3( vertices[i][0], vertices[i][1], vertices[i][2] ) );
    }

    //faces
    for(var j = 0; j < faces.length; j++) {
        if(faces[j].length == 3) {
            geo.faces.push( new THREE.Face3( faces[j][0], faces[j][1], faces[j][2] ) );
        } else if(faces[j].length == 4) {
            geo.faces.push( new THREE.Face4( faces[j][0], faces[j][1], faces[j][2], faces[j][3] ) );
        } else {
            console.error(j + " face has " + faces[j].length + ", but needs 3 or 4 faces vertices");
        }
        geo.faces[j].color.setHex(Math.random() * 0xFFFFFF);
    }

    return geo;
}


// create the frame side
this.___frame_top = new THREE.Object3D();

// Note: position and rotation is done somewhere else...

// frame side 1
var geo_frame_side = buildGeometry(side_vertices, side_faces);
this.___frame_top.___frame_side = new THREE.Mesh( geo_frame_side, new THREE.MeshPhongMaterial({vertexColors: 0x439812, wireframe: wireframe}) );
this.___frame_top.___frame_side.material.side = THREE.DoubleSide;

// frame edge 1
var geo_edge_1 = buildGeometry(edge_vertices, edge_faces);
this.___frame_top.___frame_edge_1 = new THREE.Mesh( geo_edge_1, new THREE.MeshPhongMaterial({colors: 0x439812, wireframe: wireframe}) );
this.___frame_top.___frame_edge_1.material.side = THREE.DoubleSide;

// frame edge 2
var geo_edge_2 = buildGeometry(edge_vertices, edge_faces);
this.___frame_top.___frame_edge_2 = new THREE.Mesh( geo_edge_2, new THREE.MeshPhongMaterial({colors: 0x439812, wireframe: wireframe}) );
this.___frame_top.___frame_edge_2.material.side = THREE.DoubleSide;
this.___frame_top.___frame_edge_2.rotation.y = Math.PI;

// shadow
this.___frame_top.castShadow = true;
this.___frame_top.receiveShadow = true;
this.___frame_top.___frame_side.receiveShadow = true;
this.___frame_top.___frame_side.castShadow = true;
this.___frame_top.___frame_edge_1.receiveShadow = true;
this.___frame_top.___frame_edge_1.castShadow = true;
this.___frame_top.___frame_edge_2.receiveShadow = true;
this.___frame_top.___frame_edge_2.castShadow = true;

// put all together
this.___frame_top.add(this.___frame_top.___frame_side);
this.___frame_top.add(this.___frame_top.___frame_edge_1);
this.___frame_top.add(this.___frame_top.___frame_edge_2);

scene.add(this.___frame_top);
什么会导致这种阴影问题?我想这不是threejs中的一个bug,也许我错过了一些代码和着色器的深层机制


非常感谢您的帮助

经过更多的研究,我开始怀疑这个问题是由法线指向几何体内部的面引起的。当我使用material.side=3.DoubleSide时;我原以为这也可以解决着色问题,但似乎双面效果只是为了避免背面消隐。我会删除三个。双面,并按不同的顺序推动面。您正在按Face3 0,1,2,所以将其更改为Face3 0,2,1,并将Face4更改为Face4 0,3,2,1。@gaitat:有趣的是,这改变了法线!我想知道订单背后的逻辑是什么。。。需要更多的研究:顶点顺时针或逆时针排序指定了法线方向。是的,这也是我发现的。谢谢盖拉特,你让我下定决心了!不幸的是,我的面部定义很混乱,因为它是手写的。因此,在构建人脸时简单地改变顺序是行不通的。我必须手工定购。无论如何谢谢你!