--- title: 光照和阴影 description: 学习如何向场景中添加光照和阴影。 author: alvarosabu thumbnail: /recipes/lights-and-shadows.png difficulty: 0 --- # 光照和阴影 本指南将帮助你开始在 TresJS 中使用简单的光照和阴影。 我们将构建一个包含三个网格和一个平面的简单场景,但只有两个网格会有阴影。 ## 设置场景(可选) 我们导入所有需要的模块,为了方便,我们可以使用 cientos 中的轨道控制器,[点击此处了解如何使用](/zh/cookbook/orbit-controls)。 让我们在场景中放置四个对象,一个将是接收阴影的平面,其中两个将投射阴影,最后一个根本不会投射任何阴影。 我将使用 [MeshToonMaterial](https://threejs.org/docs/index.html?q=toon#api/en/materials/MeshToonMaterial)。仅仅是因为我们可以轻松地看到“柔和的阴影”。 ```vue ``` ## 光照(说明) 如你所知,[ThreeJs](https://threejs.org/) 中的每个实例在 **TresJs** 中都是可用的,所有类型的灯光也是如此,我们只需要添加 `Tres` 前缀即可使用它们。 但并非所有灯光都能投射阴影,这个设定直接来自 ThreeJs 并且合乎情理,例如,[ambientLight](https://threejs.org/docs/index.html?q=ambient#api/en/lights/AmbientLight) 的目的是照亮场景的每一面,因此让它投射阴影毫无意义,相反,模仿太阳的 [DirectionalLight](https://threejs.org/docs/index.html?q=light#api/en/helpers/DirectionalLightHelper) 可以且应该投射阴影。 ## 阴影(说明) 阴影也有很多类型,例如,“柔和阴影”会在物体从一侧接收到更多光线时自动生成,但总的来说,需要投射到另一个表面的“ThreeJS 默认阴影”需要由一个网格投射,另一个网格需要接收它。正如我们在示例中看到的,`Plane` 正在接收阴影,但不会投射阴影。请注意,并非所有材质都能投射或接收阴影。 在内部,ThreeJS 会自动生成一个带有 [ShadowMaterial](https://threejs.org/docs/index.html?q=shado#api/en/materials/ShadowMaterial) 的新网格,该网格会在每一帧中更新,这就是为什么如果你应用动画,阴影也会被动画化,但也正是为什么你必须谨慎使用阴影,因为它们可能会降低你的性能。 ::: warning 过度使用阴影可能会降低你的性能。但是,有一些方法可以提高你的性能,有关更多信息,请查看 [此视频](https://youtu.be/WGNvVGrS0kY?si=q7XyL5eABKUh3gbS&t=1256)。 ::: ## 启用阴影 我们可以将此分为三个步骤: ### 在渲染器上激活阴影 ```vue //... ``` ### 设置光线以投射阴影 我们可以简单地放置布尔值 `cast-shadow`,Vue 将其理解为具有 `true` 值的 `prop` _AmbientLight 在这里不会生成任何类型的阴影_ ```vue //... ``` ### 设置对象以投射或接收阴影 与上一步类似,我们使用 `cast-shadow` prop 设置我们要投射阴影的网格(我们的球体),并使用 `receive-shadow` prop 设置要接收阴影的对象(我们的平面)。 ```vue //... ``` 现在,我们已经完成了向场景添加阴影所需的所有必要步骤,如果我们应用我们在 [基本动画](/zh/cookbook/basic-animations) 中学到的知识,并为我们的立方体添加运动,你将看到阴影也会随之动画化 🤩 ```vue ``` _请注意,我特意没有对 `Cone` 应用 `cast-shadow`,因此它不会投射任何阴影_