DirectionalLight为何照亮后方物体?Three.js光照异常咨询
问题原因及解决思路
核心误解:DirectionalLight的工作逻辑
Three.js里的DirectionalLight是平行光,它的光线是平行的,且默认覆盖整个场景,没有“照射范围”的限制——你设置的position属性并不是光源的实际位置,而是用来计算光线照射方向的参考点(默认光线方向是从light.position指向light.target.position,target默认是原点)。
所以你场景里的两个立方体,只要它们的表面法线朝向光线方向,就会被同等照亮,和它们的位置无关,这就是为什么(3,3,3)的立方体也亮了。
解决方法(按你的预期实现“仅照亮特定区域内的物体”)
如果想让光源只影响特定区域的物体,有两种常用方案:
- 改用PointLight/SpotLight:这两种光源有明确的位置和照射范围(通过
distance或angle参数控制),适合模拟有边界的光照。比如用PointLight,设置position(2,2,1),调整distance参数让光照范围刚好覆盖(0,0,0)的立方体,而够不到(3,3,3)的。 - 给DirectionalLight添加光照范围限制:平行光本身没有范围,但可以通过以下方式实现:
- 用Layers:给(0,0,0)的立方体分配特定层,让DirectionalLight只照亮该层,(3,3,3)的立方体放在其他层。
// 立方体1加入层1 cube1.layers.set(1); // 灯光只照亮层1 directionalLight.layers.set(1); // 相机也要开启层1的可见性 camera.layers.enable(1); - 用阴影相机限制(仅阴影生效,光照本身还是全局):如果你只是想让(3,3,3)的立方体不产生阴影,可以调整
directionalLight.shadow.camera的视锥体参数,把(3,3,3)排除在阴影相机的视锥体外,但这不会影响物体本身的光照亮度。
- 用Layers:给(0,0,0)的立方体分配特定层,让DirectionalLight只照亮该层,(3,3,3)的立方体放在其他层。
验证DirectionalLight方向的小技巧
你已经用了DirectionalLightHelper,可以清楚看到光线的方向箭头。如果想改变光线方向,直接修改light.target.position即可,不过这还是会让两个立方体的朝向光线的面被照亮,除非用上面的范围限制方法。
内容的提问来源于stack exchange,提问作者Omer Kamran
相关产品推荐
相关产品推荐

