I have a three.js (REVISION: '68') issue with the lighting of THREE.Geometry objects:
I'm using the THREE.Geometry class to build up objects using vertices and faces, then I computeFaceNormals() and computeVertexNormals() before adding it to the scene.
The lighting is obviously not calculating correctly, and it looks like the light calculates before the object is moved into position (or some other issue causing all objects to have identical lighting regardless of position).
My light code is:
hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
hemiLight.color.setHSL( 0.6, 1, 0.6 );
hemiLight.groundColor.setHSL( 0.095, 1, 0.75 );
hemiLight.position.set( 0, 50, 0 );
app.scene.add( hemiLight );
dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.color.setHSL( 0.1, 1, 0.95 );
dirLight.position.set( -1, 1.75, 1 );
dirLight.position.multiplyScalar( 50 );
app.scene.add( dirLight );
Note I also tried the documentation's sample-code for the Spotlight the issue persisted.
I am using a comparison of THREE.Geometry objects: the first with a single material for the at mesh creation, and the second with faces individually assigned a material, and passed to the mesh with THREE.MeshFaceMaterial(..) Note that I tried both single material Geometries and multi-material Geometries side-by-side and there is no difference.
Note I changed the color of one of my test cubes from blue to green compared to the header image.
The issue does not appear to be related to the multi-material code.
I understand that the Three.Geometry class behaves differently compared to BoxGeometry, etc. (For example, computeFaceNormals() and computeVertexNormals() needs to be explicitly called for Three.Geometry, but not for BoxGeometry). I think I may be missing some other difference around flagging the material/lighting/geometry for update.
My code to create my two plain test cubes is:
var testGeo = new THREE.Geometry();
testGeo.vertices.push(new THREE.Vector3(0,0,0));
testGeo.vertices.push(new THREE.Vector3(0,20,0));
testGeo.vertices.push(new THREE.Vector3(20,20,0));
testGeo.vertices.push(new THREE.Vector3(20,0,0));
testGeo.vertices.push(new THREE.Vector3(0,0,20));
testGeo.vertices.push(new THREE.Vector3(0,20,20));
testGeo.vertices.push(new THREE.Vector3(20,20,20));
testGeo.vertices.push(new THREE.Vector3(20,0,20));
testGeo.faces.push(new THREE.Face3(0,1,2));
testGeo.faces.push(new THREE.Face3(2,3,0));
testGeo.faces.push(new THREE.Face3(2,3,7));
testGeo.faces.push(new THREE.Face3(7,6,2));
testGeo.faces.push(new THREE.Face3(0,1,5));
testGeo.faces.push(new THREE.Face3(5,4,0));
testGeo.faces.push(new THREE.Face3(0,3,4));
testGeo.faces.push(new THREE.Face3(4,7,3));
testGeo.faces.push(new THREE.Face3(1,2,6));
testGeo.faces.push(new THREE.Face3(6,5,1));
testGeo.faces.push(new THREE.Face3(4,5,6));
testGeo.faces.push(new THREE.Face3(6,7,4));
testGeo.computeFaceNormals();
testGeo.computeVertexNormals();
var solidMatA = new THREE.MeshLambertMaterial({
color: 'blue'
})
solidMatA.side = THREE.DoubleSide;
var cubeA = new THREE.Mesh( testGeo, solidMatA );
cubeA.position.x = -40;
cubeA.position.y = -30;
cubeA.position.z = -30;
app.scene.add(cubeA);
var testMaterialsListB = [];
var testGeo2 = new THREE.Geometry();
testGeo2.vertices.push(new THREE.Vector3(0,0,0));
testGeo2.vertices.push(new THREE.Vector3(0,20,0));
testGeo2.vertices.push(new THREE.Vector3(20,20,0));
testGeo2.vertices.push(new THREE.Vector3(20,0,0));
testGeo2.vertices.push(new THREE.Vector3(0,0,20));
testGeo2.vertices.push(new THREE.Vector3(0,20,20));
testGeo2.vertices.push(new THREE.Vector3(20,20,20));
testGeo2.vertices.push(new THREE.Vector3(20,0,20));
testGeo2.faces.push(new THREE.Face3(0,1,2));
testGeo2.faces.push(new THREE.Face3(2,3,0));
testGeo2.faces.push(new THREE.Face3(2,3,7));
testGeo2.faces.push(new THREE.Face3(7,6,2));
testGeo2.faces.push(new THREE.Face3(0,1,5));
testGeo2.faces.push(new THREE.Face3(5,4,0));
testGeo2.faces.push(new THREE.Face3(0,3,4));
testGeo2.faces.push(new THREE.Face3(4,7,3));
testGeo2.faces.push(new THREE.Face3(1,2,6));
testGeo2.faces.push(new THREE.Face3(6,5,1));
testGeo2.faces.push(new THREE.Face3(4,5,6));
testGeo2.faces.push(new THREE.Face3(6,7,4));
for (var i = 0; i < testGeo2.faces.length; i++)
{
var matB = new THREE.MeshLambertMaterial( {color: 'green'} );
matB.side = THREE.DoubleSide;
testMaterialsListB.push(matB);
}
testGeo2.computeFaceNormals();
testGeo2.computeVertexNormals();
var cubeB = new THREE.Mesh( testGeo2, new THREE.MeshFaceMaterial( testMaterialsListB) );
cubeB.position.x = -60;
cubeB.position.y = -30;
cubeB.position.z = -30;
app.scene.add(cubeB);
Thanks!