如何在Three.JS中创建方向性光影?

eqi*_*roo 23 javascript three.js

是否有可能从DirectionalLight?创建阴影?

如果我使用SpotLight然后我看到一个阴影,但如果我使用DirectionalLight它不起作用.

Dre*_*kes 50

请注意,阴影贴图与比例相关.我正在研究一个单位距离代表一米的场景,我的物体大约0.4米.根据Three.js标准,这是非常小的.如果您也遇到这种情况,那么您可以采取以下几个重要步骤:

  • 根据场景的尺寸,确保阴影相机的近/远平面合理.
  • 确保阴影相机的上/左/下/右值不会太大,否则每个阴影'像素'可能会很大,甚至不会注意到场景中的阴影.

我们来看看如何做到这一点.

调试

请务必通过以下方式打开每个灯光的调试渲染CameraHelper:

scene.add(new THREE.CameraHelper(camera)) 
Run Code Online (Sandbox Code Playgroud)

或者在旧版本的Three.js中:

light.shadowCameraVisible = true;
Run Code Online (Sandbox Code Playgroud)

这将显示计算阴影的音量.以下是可能的示例:

注意近处和远处的平面(带有黑色十字架),以及阴影摄像机的顶部/左侧/底部/右侧(黄色框的外墙).您希望此框紧紧围绕您将要使用的任何物体.阴影 - 可能比我在这里展示的还要紧.

以下是一些可能有用的代码片段.

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);
Run Code Online (Sandbox Code Playgroud)

确保一些对象投射阴影:

object.castShadow = true;
Run Code Online (Sandbox Code Playgroud)

确保一些对象接收阴影:

object.receiveShadow = true;
Run Code Online (Sandbox Code Playgroud)

最后,配置一些值WebGLRenderer:

renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(canvasWidth, canvasHeight);
renderer.shadowMapEnabled = true;
renderer.shadowMapSoft = true;
Run Code Online (Sandbox Code Playgroud)

  • 是否有一个技巧使`light.shadowCameraVisible = true`工作?它似乎没有在这个分叉的例子中做任何事情(来自上面接受的答案):http://jsfiddle.net/Q4uqE/566/ (2认同)

Cor*_*oss 36

是的,你绝对可以使用定向灯来投射阴影.您需要确保不使用,MeshBasicMaterial因为它们不支持阴影.使用MeshLambertMaterialMeshPhongMaterial代替.

您需要为渲染器启用阴影,其中包含以下内容:

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;
Run Code Online (Sandbox Code Playgroud)

然后你必须为每个对象和每个光启用阴影投射和阴影接收,这样你就可以拥有

dirLight.castShadow = true;
object.castShadow = true;
otherObject.receiveShadow = true;
Run Code Online (Sandbox Code Playgroud)

然后,如果光和物体放置在适当的位置.dirLight会导致阴影object被投射otherObject.

[编辑]:这是一个工作演示,适合任何想要做类似事情的人.

  • 是的,在您的小提琴中,您的定向灯位于您的立方体内.这是与光线向上移动并从立方体中移出的相同的小提琴.http://jsfiddle.net/Q4uqE/5/ (2认同)