Javascript 如何在 Three.JS 中创建定向光影?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10742149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create directional light shadow in Three.JS?
提问by eqiproo
Is it possible to create shadows from a DirectionalLight
?
是否可以从 a 创建阴影DirectionalLight
?
If I use SpotLight
then I see a shadow, but if I use DirectionalLight
it doesn't work.
如果我使用SpotLight
然后我看到一个阴影,但如果我使用DirectionalLight
它不起作用。
回答by Drew Noakes
Be aware that shadow maps are scale dependent. I'm working on a scene where the unit distance represents one metre, and my objects are around 0.4 metres large. This is quite small by Three.js standards. If you have this situation too, then you can take a few important steps:
请注意,阴影贴图与比例有关。我正在处理一个单位距离代表一米的场景,我的物体大约有 0.4 米大。按照 Three.js 标准,这相当小。如果您也有这种情况,那么您可以采取几个重要步骤:
- Ensure the shadow camera's near/far planes are reasonable given your scene's dimensions.
- Ensure the shadow camera top/left/bottom/right values are not too large, otherwise each shadow 'pixel' may be so large that you don't even notice the shadow in your scene.
- 考虑到场景的尺寸,确保阴影相机的近/远平面是合理的。
- 确保阴影相机的顶部/左侧/底部/右侧值不会太大,否则每个阴影“像素”可能太大以至于您甚至不会注意到场景中的阴影。
Let's look at how to do this.
让我们看看如何做到这一点。
Debugging
调试
Be sure to turn on the debug rendering per light via CameraHelper
:
请务必通过以下方式打开每盏灯的调试渲染CameraHelper
:
scene.add(new THREE.CameraHelper(camera))
Or in older versions of the Three.js:
或者在 Three.js 的旧版本中:
light.shadowCameraVisible = true;
This will show you the volume over which the shadow is being calculated. Here is an example of what that might look like:
这将显示正在计算阴影的体积。下面是一个示例:
Notice the near and far planes (with black crosses), and the top/left/bottom/right of the shadow camera (outer walls of the yellow box.) You want this box to be tight around whatever objects you are going to have in shadow — possibly even tighter than I'm showing here.
注意近平面和远平面(带有黑色十字)以及阴影摄像机的顶部/左侧/底部/右侧(黄色框的外壁)。您希望这个框紧紧围绕着您将要放置的任何物体阴影——可能比我在这里展示的更紧。
Code
代码
Here are some snippets of code that might be useful.
以下是一些可能有用的代码片段。
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);
Make sure some object(s) cast shadows:
确保某些对象投射阴影:
object.castShadow = true;
Make sure some object(s) receive shadows:
确保某些对象收到阴影:
object.receiveShadow = true;
Finally, configure some values on the WebGLRenderer
:
最后,在 上配置一些值WebGLRenderer
:
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(canvasWidth, canvasHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
回答by Cory Gross
Yes, you most definitely canuse directional lights to cast shadows. You need to make sure you are not using MeshBasicMaterial
as they don't support shadows. Use MeshLambertMaterial
or MeshPhongMaterial
instead.
是的,您绝对可以使用定向光来投射阴影。您需要确保您没有使用MeshBasicMaterial
它们,因为它们不支持阴影。使用MeshLambertMaterial
或MeshPhongMaterial
代替。
You need to enable shadows for the renderer with something along these lines:
您需要使用以下内容为渲染器启用阴影:
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;
And then you must enable shadow casting and shadow receiving per object and per light so you would have
然后您必须启用每个对象和每个灯光的阴影投射和阴影接收,以便您拥有
dirLight.castShadow = true;
object.castShadow = true;
otherObject.receiveShadow = true;
Then, ifthe light and objects are placed at appropriate positions. dirLight
will cause the shadow of object
to be cast against otherObject
.
然后,如果将灯光和物体放置在适当的位置。dirLight
会造成object
被投下的阴影otherObject
。
[EDIT]:Here is a working demofor anyone looking to do something similar.
[编辑]:这是一个工作演示,适用于希望做类似事情的任何人。