Overlapping PointLight Shadows using MeshLambertMaterial

拟墨画扇 提交于 2019-12-02 09:56:13

问题


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.

Graphical Representation

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;
}());

回答1:


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



来源:https://stackoverflow.com/questions/47224535/overlapping-pointlight-shadows-using-meshlambertmaterial

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!