【问题标题】:Lights with materials in three.js not working properlyThree.js 中的材质灯无法正常工作
【发布时间】:2026-02-21 14:55:02
【问题描述】:

最后,我需要一个正常的阴影。但是使用带有 Lambert / Phong 材料的 Spot / Directional 灯我没有得到正确的结果:

picture with examples

当我使用带有 Lambert 材质的聚光灯时,这种材质不会对光做出反应(图 1、2)。 当我使用 Phong 材质的 Spot Light 时,我得到阴影,像图案一样,不光滑(图 3、4)。 当我将定向光与 Lambert / Phong 材料一起使用时,我得到了平滑,但阴影不合适(图 5 - 8)。

我将这个偏好用于阴影:

renderer.shadowMap.enabled = 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;

这对于灯光来说:

var ambientLight =new THREE.AmbientLight( 0x555555 );
scene.add(ambientLight);

var spotLight = new THREE.SpotLight( 0xffffff);
spotLight.position.set( 12, 22, -25 );
spotLight.castShadow = true;
scene.add(spotLight );

var directionalLight=new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set( 12, 22, -25 );
directionalLight.castShadow = true;
scene.add(directionalLight);

此外,我对所有这些示例都使用相同的 castShadowreceiveShadow 属性。

如果需要,其他代码可以作为本页源代码观看:

Spot Light, Lambert Material

对于我的所有示例,此代码都相同,不包括光 - 材料组合。

【问题讨论】:

  • 现在我在另一台机器上检查了我的示例,发现使用 Spot Light / Lambert 材质的示例与 Spot Light / Phong 材质的工作方式相同。这可能取决于视频卡吗?但其他问题仍然相同:使用 Spot Light 的阴影不平滑,使用 Directional Light 的两种材质的组合阴影效果不佳。 new example
  • THIS 问题可能相关
  • 是的。 @2pha,谢谢。它解决了我最近的问题,但我有一个新问题。所有未点亮的面都没有颜色:example。如果我应该创建一个新问题,或者扩展这个问题?

标签: javascript three.js


【解决方案1】:

Three.js 中的实时阴影通常很棘手。以下是改进示例的一些基础知识。

限制shadow.camera-frustum:

spotLight.shadow.camera.near = 25;
spotLight.shadow.camera.far = 50;
spotLight.shadow.camera.fov = 30;

增加shadow.mapSize:

spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;

使用shadowBias 减少伪影:

spotLight.shadowBias = -0.003;

结果并不完美,因为现在房间内出现了轻微的接缝。它需要更多的调整和权衡,但也许它足以满足您的需求: https://jsfiddle.net/wbrj8uak/8/


在这里留下评论,关于 2pha 的更新示例以及我为什么要恢复它:

设置相机位置会导致房间内的阴影消失。对于想要在里面有阴影的发布者来说,这肯定会让他们感到困惑,这就是为什么我只是按照他提供的方式留下了他的代码。

【讨论】:

  • 谢谢,很有帮助。但是你还能再回答一个问题吗?为什么在这个example 中只有被照亮的面有颜色,为什么材质是半透明的?
  • 您在没有被聚光/定向光照射的面上看到的灰色只是反射环境光 (#555555)。半透明是指墙壁阴影侧的明亮三角形点?我不知道这是从哪里来的......
  • 感谢您对环境光的解释。那么,如何制作逼真的面部颜色,而不是转向定向光呢?是否需要添加更多不同方向的定向光源?明亮的三角形是来自窗户的光。它穿过墙壁和地板:picture。该亮点周围的黑暗区域是天花板和其他墙壁的阴影。因此,我说这种材料是半透明的(或半透明的?),如果它透射光的话。你知道如何将材质设置为零透明度吗?
  • 我首先编辑小提琴的主要原因是 OrbitControls 没有正确加载并导致错误使小提琴只显示黑屏,至少它在 Chrome 中对我有用。新的小提琴(第 7 版)也这样做。
  • @2pha,这正是我从一开始就想要的https://jsfiddle.net/alisa23a/b3Lquwuw/7/。除了光线穿过材料并从另一侧可见:picture。在我的示例中,如何关闭此问题以设置新的关于材料透明度的问题?