为什么three.js与gouraud插值不一致?

时间:2019-06-15 23:12:24

标签: three.js shader normals gouraud

我想使用简单的THREE.BoxBufferGeometryTHREE.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,那古罗就在场。

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

但是,如果我使用PolyhedronBufferGeometry制作一个立方体,除非 我将详细信息设置为0以外的其他东西,否则不会出现Gouraud底纹。

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着色:

correct shading

但是上面的代码改为生成此代码:

incorrect shading

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

那么这是怎么回事?我能想到的唯一解释是Box实际上由24个顶点组成,三个顶点在立方体的每个角上,并且它们形成面,使得每个顶点的计算法线是最多两个指向的面的平均值朝着同一方向。但是我找不到在任何地方写下来的内容,并且对于在代码中明确指定了顶点和面的Polyhedron来说,这种解释也行不通。

0 个答案:

没有答案