是否可以从DirectionalLight
创建阴影?
如果我使用SpotLight
,那么我会看到一个阴影,但如果我使用DirectionalLight
则无效。
答案 0 :(得分:49)
请注意,阴影贴图与比例相关。我正在研究一个单位距离代表一米的场景,我的物体大约0.4米。根据Three.js标准,这是非常小的。如果您也遇到这种情况,那么您可以采取以下几个重要步骤:
让我们来看看如何做到这一点。
请务必通过CameraHelper
启用每个灯光的调试渲染:
scene.add(new THREE.CameraHelper(camera))
或旧版本的Three.js:
light.shadowCameraVisible = true;
这将显示计算阴影的音量。以下是可能的示例:
注意近处和远处的平面(带有黑色十字架),以及阴影摄像机的顶部/左侧/底部/右侧(黄色框的外墙)。您希望这个框紧紧围绕您要去的任何物体在阴影中 - 可能比我在这里显示的更紧。
以下是一些可能有用的代码片段。
var light = new THREE.DirectionalLight(0xffffff);
light.position.set(0, 2, 2);
light.target.position.set(0, 0, 0);
light.castShadow = true;
light.shadowDarkness = 0.5;
light.shadowCameraVisible = true; // only for debugging
// these six values define the boundaries of the yellow box seen above
light.shadowCameraNear = 2;
light.shadowCameraFar = 5;
light.shadowCameraLeft = -0.5;
light.shadowCameraRight = 0.5;
light.shadowCameraTop = 0.5;
light.shadowCameraBottom = -0.5;
scene.add(light);
确保某些物体投下阴影:
object.castShadow = true;
确保某些物体接收阴影:
object.receiveShadow = true;
最后,在WebGLRenderer
上配置一些值:
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(canvasWidth, canvasHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
答案 1 :(得分:35)
是的,你肯定可以使用定向灯来投射阴影。您需要确保不使用MeshBasicMaterial
,因为它们不支持阴影。请改用MeshLambertMaterial
或MeshPhongMaterial
。
您需要为渲染器启用阴影,其中包含以下内容:
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;
renderer.shadowMapBias = 0.0039;
renderer.shadowMapDarkness = 0.5;
renderer.shadowMapWidth = 1024;
renderer.shadowMapHeight = 1024;
然后你必须为每个物体和每个灯启用阴影投射和阴影接收,这样你才能拥有
dirLight.castShadow = true;
object.castShadow = true;
otherObject.receiveShadow = true;
然后,如果光线和物体放置在适当的位置。 dirLight
会导致object
投射otherObject
。
[编辑]:对于想要做类似事情的人来说,这是一个 working demo 。