Я хочу закрасить THREE.BoxBufferGeometry
с помощью простого THREE.MeshLambertMaterial
. Предполагается, что материал будет использовать модель освещения Ламберта, чтобы выбрать цвета для каждой вершины (и это так), а затем использовать затенение Гуро для получения плавных градиентов на каждой грани.
Часть Гуро не происходит. Вместо этого лица куба закрашены одним сплошным цветом.
Я пробовал другие 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
.
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);
Я должен получить куб, грани которого (реальные, треугольные) заштрихованы. Сначала должны быть вычислены нормали граней, а затем нормали вершин путем усреднения нормалей образованных ими граней. Вот треугольная бипирамида, на которой применяется правильное затенение Гуро:
Но приведенный выше код производит это вместо:
Three.js ни при каких условиях не регистрирует ошибки и предупреждения на консоли.
Так что же здесь происходит? Единственное объяснение, которое я могу придумать, состоит в том, что Box
на самом деле состоит из 24 вершин, по три в каждом углу куба, и что они образуют грани так, что вычисленная нормаль каждой вершины представляет собой среднее значение максимум двух граней, указывающих на в том же направлении. Но я нигде не могу найти это записанное, и это объяснение не подходит для Polyhedron
, где вершины и грани были явно указаны в коде.