Reputation: 15
I'm building a small representation of my house in ThreeJS, and I have the walls and such sorted and am in the process of adding the lights. I'm using PointLights as they are representing lightbulbs.
The issue I'm having is that with two lights, only the area that they both cover is lit, and the remaining 'half-shadow' is pitch black, when I would expect them to be lit with half of the intensity. Graphical representation below.
In this image, the circles represent the lights, with the beams representing how I expect the light to fall in the smaller room. The area with the 'shading' represents where I expect to have the 'half-shadows'.
It seems to me that the only area that is actually lit in the scene is where BOTH of the two PointLights shine, and when only one would affect an area, the area is pitch black.
The walls are added as BoxGeometries, with the walls around the door as an ExtrudeGeometry of a Shape.
Here is the code for the lights:
scene.add( function() {
var mainLight1 = new THREE.PointLight( 0xFFFFFF, 0.33 );
mainLight1.position.set( -middleFloorDim.width / 5, middleFloorDim.height * 9.75 / 10, -middleFloorDim.depth / 4 );
mainLight1.castShadow = true;
return mainLight1;
}());
scene.add( function() {
var mainLight2 = new THREE.PointLight( 0xFFFFFF, 0.33 );
mainLight2.position.set( -middleFloorDim.width / 5, middleFloorDim.height * 9.75 / 10, middleFloorDim.depth / 4 );
mainLight2.castShadow = true;
return mainLight2;
}());
And here is the code for the renderer:
var renderer = new THREE.WebGLRenderer({ antialias: true, });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
And an example of one of the walls:
scene.add( function() {
var northWall = new THREE.Mesh(
new THREE.BoxGeometry( middleFloorDim.depth, middleFloorDim.height , 0.01 ),
new THREE.MeshLambertMaterial({
color: PALETTE.MIDDLE_FLOOR_WALLS,
})
);
northWall.rotation.y = Math.PI / 2;
northWall.position.set( -middleFloorDim.width / 2, middleFloorDim.height / 2, 0 );
northWall.castShadow = true;
northWall.receiveShadow = true;
return northWall;
}());
Upvotes: 1
Views: 319
Reputation: 104833
You are having problems with shadows when you have multiple light sources and the material receiving the shadow is MeshLambertMaterial
.
This is a limitation of MeshLambertMaterial
due to the fact that it uses Gouraud shading -- the illumination calculation is computed in the vertex shader. Since shadows are computed in the fragment shader, there is no way to identify the light sources at that point.
For proper shadows, use MeshPhongMaterial
or MeshStandardMaterial
, for example.
three.js r.88
Upvotes: 3