经纬志
首页 / three.js / API 文档

DirectionalLight

先看结论

平行光,光线方向全部相同,用来模拟太阳这类距离极远的光源。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-28 · 引用本文
new THREE.DirectionalLight(color, intensity) → DirectionalLight

构造参数

参数默认说明
color0xffffff光色,暖白偏黄,冷白偏蓝
intensity1强度。渲染器默认采用物理光照单位,太阳光常取 2 到 4

属性

属性默认说明
position(0, 1, 0)与 target 连线决定光照方向,距离本身不衰减
target位于原点的 Object3D光照指向的对象,改了它的位置要加入场景才会生效
castShadowfalse开启后物体才会投下阴影
shadow.mapSize(512, 512)阴影贴图分辨率,越大越清晰,显存占用按面积增长
shadow.camera正交相机,±5 / 0.5–500阴影覆盖的立方体范围,必须包住投影物体
shadow.bias0深度偏移,用来移开阴影粉刺
shadow.normalBias0沿法线偏移,比 bias 更少产生漏光
shadow.radius1仅 PCF 系列软阴影有效,模糊半径
isDirectionalLighttrue只读标记

方法

方法说明
dispose()释放阴影贴图等 GPU 资源,移除灯后调用
copy(source)复制属性,阴影设置一并带入
lookAt(x, y, z)改写灯光朝向,但阴影相机仍以 target 为准

基本用法

const sun = new THREE.DirectionalLight(0xfff1d6, 2.6);
sun.position.set(-30, 45, 20);   // 高、偏西、偏南
scene.add(sun);

// target 默认在原点;若要把光投向别处,必须把它加入场景
sun.target.position.set(0, 0, 0);
scene.add(sun.target);

位置只表达方向:把 position 从 (-30, 45, 20) 改成 (-60, 90, 40), 光照方向与强度完全不变。这也意味着平行光不存在距离衰减。

配置阴影

sun.castShadow = true;
sun.shadow.mapSize.set(2048, 2048);

// 阴影相机是正交相机,覆盖范围要包住整个场景
const sc = sun.shadow.camera;
sc.left = -60;
sc.right = 60;
sc.top = 60;
sc.bottom = -60;
sc.near = 1;
sc.far = 160;
sc.updateProjectionMatrix();

sun.shadow.bias = -0.0005;
sun.shadow.normalBias = 0.04;

renderer.shadowMap.enabled = true;

阴影相机范围越大,同样分辨率下每个像素覆盖的地面越宽,阴影边缘越糊。 城市级场景通常把范围收紧到当前视口附近,而不是一次包住整块区域。

阴影异常的两类原因

表面出现条纹状的「阴影粉刺」,是阴影贴图精度与几何面深度过于接近造成的, 优先调大 normalBias,其次再动 bias。 物体边缘出现与本体脱离的暗环,则是 bias 过大导致的漏光, 需要往回收。

地形这类起伏大、跨度大的几何体,用单一平行光的阴影贴图很难兼顾远近, 可以按视口动态移动 sun.position 与 target, 让阴影相机始终跟随观察中心。

方向不是经纬度。平行光的方向由场景坐标系决定, 和太阳高度角、方位角没有自动换算关系。three.js 不提供日照计算, 需要按地理坐标自行推导方向向量,再写入 position。

引用本文

经纬志(2026)。《DirectionalLight》。https://www.jingweizhi.com/three/api/directional-light.html(访问日期 2026-11-03)。