0

我想THREE.BoxBufferGeometry用一个简单的THREE.MeshLambertMaterial. 该材质应该使用 Lambert 照明模型来选择每个顶点的颜色(确实如此),然后使用 Gouraud 着色在每个面上产生平滑的渐变。

Gouraud 部分没有发生。相反,立方体的每个面都用一种单一的纯色着色。

我尝试了各种其他BufferGeometry的,并得到不一致的结果。

例如,如果我改为制作IcosahedronBufferGeometry,我会遇到同样的问题:每张脸都是一个单一的纯色。

geometry = new THREE.IcosahedronBufferGeometry(2, 0); // no Gouraud shading.
geometry = new THREE.IcosahedronBufferGeometry(2, 2); // no Gouraud shading.

另一方面,如果我制作SphereBufferGeometry,则 Gouraud 存在。

geometry = new THREE.SphereBufferGeometry(2, 3, 2); // yes Gouraud shading.
geometry = new THREE.SphereBufferGeometry(2, 16, 16); // yes Gouraud shading.

但是,如果我使用 a 制作立方体PolyhedronBufferGeometry,则不会出现 Gouraud 阴影,除非我将细节设置为0.

const verticesOfCube = [
    -1,-1,-1,    1,-1,-1,    1, 1,-1,    -1, 1,-1,
    -1,-1, 1,    1,-1, 1,    1, 1, 1,    -1, 1, 1,
];

const indicesOfFaces = [
    2,1,0,    0,3,2,
    0,4,7,    7,3,0,
    0,1,5,    5,4,0,
    1,2,6,    6,5,1,
    2,3,7,    7,6,2,
    4,5,6,    6,7,4
];

const geometry = new THREE.PolyhedronBufferGeometry(verticesOfCube, indicesOfFaces, 1, 1); // no Gouraud shading
geometry = new THREE.PolyhedronBufferGeometry(verticesOfCube, indicesOfFaces, 1, 1); // yes Gouraud shading

我知道BufferGeometry方法computeFaceNormals()computeVertexNormals(). 法线在这里非常重要,因为它们分别用于确定每个面和顶点的颜色。但是,虽然它们对 有帮助,但Icosahedron它们对 没有影响Box,无论它们是否存在,只有一个存在,或者两者都存在于两个可能的顺序中。

这是我希望工作的代码:

const geometry = new THREE.BoxBufferGeometry(2, 2, 2);
geometry.computeFaceNormals();
geometry.computeVertexNormals();

const material = new THREE.MeshLambertMaterial({
  color: 0xBE6E37
});

const mesh = new THREE.Mesh(geometry, material);

我应该得到一个立方体,其面(真实的三角形)用渐变着色。首先,应该计算面法线,然后通过平均由它们形成的面的法线来计算顶点法线。这是一个三角形双锥,其上应用了正确的 Gouraud 着色:

正确的阴影

但是上面的代码却产生了这个:

不正确的阴影

three.js 绝不会将任何错误或警告记录到控制台。

那么这里发生了什么?我能想到的唯一解释是,Box它实际上由 24 个顶点组成,立方体的每个角有 3 个,并且它们形成的面使得每个顶点的计算法线是最多两个指向同一方向的面的平均值。但是我在任何地方都找不到写下来的内容,并且该解释不适用于Polyhedron代码中明确指定的顶点和面。

4

0 回答 0