THREE.BoxBufferGeometry
シンプルな を使用してをシェーディングしたいTHREE.MeshLambertMaterial
。マテリアルは、ランバート イルミネーション モデルを使用して各頂点の色を選択し (実際にそうします)、グーロー シェーディングを使用して各面に滑らかなグラデーションを生成することになっています。
グーロー部分は起きていません。代わりに、立方体の面はそれぞれ 1 つの単色でシェーディングされます。
他のさまざまな を試しBufferGeometry
ましたが、一貫性のない結果が得られました。
たとえば、代わりに を作成するIcosahedronBufferGeometry
と、同じ問題が発生します。各面は 1 つの単色になります。
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
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()
。法線は、各面と頂点の色をそれぞれ決定するために使用されるため、ここでは非常に重要です。しかし、それらは に役立ちますが、存在するか、1 つだけ存在するか、または両方が両方の可能な順序で存在するかに関係なく、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);
面 (実際の三角形の面) がグラデーションでシェーディングされた立方体を取得する必要があります。最初に面の法線を計算し、次にそれらによって形成された面の法線を平均化して頂点の法線を計算する必要があります。以下は、正しいグーロー シェーディングが適用されている三角両錐です。
しかし、上記のコードは代わりにこれを生成します:
three.js がエラーや警告をコンソールに記録することは決してありません。
それで、ここで何が起こっているのですか?私が考えることができる唯一の説明は、Box
実際には立方体の各コーナーに 3 つずつある 24 の頂点で構成され、各頂点の計算された法線が同じ方向を向いている最大 2 つの面の平均になるように面を形成するということです。しかし、それがどこにも書かれていないことがわかりません。その説明はPolyhedron
、頂点と面がコードで明示的に指定されている場所には当てはまりません。