Here is a movie and the code example that produced it. You can clearly see the normal defects on the bottom box. The top box uses the same geometry but not indexed.
let camera, scene, renderer, controls;
let material, mesh;
let vertices, indices;
let unindexed, indexed;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 15;
scene.add(camera);
scene.add(new THREE.AmbientLight(0xffffff, 0.2));
scene.add(light(0.2, 30, 0, 0));
scene.add(light(0.2, -30, 0, 0));
scene.add(light(0.2, 0, 30, 0));
scene.add(light(0.2, 0, -30, 0));
scene.add(light(0.2, 0, 0, 30));
scene.add(light(0.2, 0, 0, -30));
vertices = Float32Array.from([
-2, -2, -2,
-2, 2, -2,
2, 2, -2,
2, -2, -2,
-2, -2, 2,
-2, 2, 2,
2, 2, 2,
2, -2, 2,
]);
indices = Uint32Array.from([
0, 1, 2, // bottom
0, 2, 3,
6, 5, 4, // top
7, 6, 4,
0, 4, 1, // side 1
1, 4, 5,
2, 6, 3, // side 2
3, 6, 7
]);
// generate full vertices list (non-indexed)
let vertall = [];
for (let i of indices) {
vertall = vertall.concat([...vertices].slice(i*3,i*3+3));
}
vertall = Float32Array.from(vertall);
material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
shininess: 100,
specular: 0x404040,
transparent: false,
color: 0xffff00,
opacity: 0.5
});
// non-indexed geometry
unindexed = new THREE.BufferGeometry()
.setAttribute('position', new THREE.BufferAttribute(vertall, 3));
unindexed.computeVertexNormals();
// mesh with non-indexed geometry
let meshU = new THREE.Mesh(unindexed, material);
meshU.add(new THREE.Mesh(
unindexed.clone(), new THREE.MeshBasicMaterial({
wireframe: true,
color: 0xffff00
})
));
scene.add(meshU);
meshU.position.y = 2.5;
// indexed geometry
indexed = new THREE.BufferGeometry()
.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
.setIndex(new THREE.BufferAttribute(indices, 1));
indexed.computeVertexNormals();
// mesh with indexed geometry
let meshI = new THREE.Mesh(indexed, material);
meshI.add(new THREE.Mesh(
indexed.clone(), new THREE.MeshBasicMaterial({
wireframe: true,
color: 0xffff00
})
));
scene.add(meshI);
meshI.position.y = -2.5;
renderer = new THREE.WebGLRenderer({
antialias: true,
preserveDrawingBuffer: true,
logarithmicDepthBuffer: true
});
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.update();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
animate();
}
function light(i, x, y, z) {
let l = new THREE.PointLight(0xffffff, i);
l.position.set(x,y,z);
return l;
}