欢迎光临
我们一直在努力

Babylon.js 8.x 中文文档整理——Light篇

Part 1 Light介绍

1. Light概述

现实中,物体通常不会主动发出光线,而是通过接收光源照射,例如太阳光、月光,对光线进行反射、吸收等物理过程,最终形成我们看到的效果。

在三维渲染中,Light光照系统就是用于简化模拟现实世界中的光线效果,通过计算光线与物体表面的交互关系,生成最终画面上的像素颜色。

需要注意的是,三维场景中的可见性并不完全依赖Light,如果物体材质存在自发光Emissive可以不依靠外部官员直接产生颜色表现,但对于大多数情况而言,光照仍是影响视觉效果不可或缺的一部分。

在 Babylon 中,Light 光照是场景中的一种基础对象,用于向材质计算提供光照信息。它本身不会直接改变 Mesh 的几何结构,而是在渲染过程中影响物体材质Material的表现。

通常一个完整的三维渲染结果通常由多个因素共同决定:

最终画面
=
Mesh(几何结构) //描述物体的形状和空间结构;
+
Material(材质属性) //描述物体表面的颜色、粗糙度、金属度等;
+
Light(光照信息) //提供光照方向、光源颜色、光照强度等
+
Camera(观察角度) //决定最终观察的位置和角度等

因此,Light 并不是简单地增加场景亮度,而是参与三维场景中光线计算的重要组成部分。

不同类型的 Light与不同的光照配置,以及不同的材质,会直接影响最终渲染效果。

2. Light的作用

一个光源通常包含多个基本属性,例如位置、方向、颜色以及强度等,这些属性共同决定了光线如何作用于场景中的物体。

光源位置Position,确定光源产生的位置,但不同类型的Light对位置的依赖程度不同,例如PointLight、SpotLight具有明确的位置概念。

光源方向Direction,表示光线传播方向,DirectionalLight就是通过方向来模拟太阳光的平行光效果。

光源颜色Color,决定光线本身的颜色,它会参与颜色计算但不代表最终颜色,例如蓝色环境光会让整个场景产生冷色调。

光源强度Intensity,表示光照能量的大小,会影响场景的明暗程度,但不是绝对的,需要合理的材质参数、后处理效果等配合最终效果呈现。

Light
|
| 位置
| 方向
| 颜色
| 强度

光照计算

Normal + Material

Mesh最终表现

物体本身材质也会直接影响光照效果,例如材质的金属感、粗糙度、透明度,以及材质自身的漫反射、高光等。

物体的法线Normal是很重要的概念,简单来说它表示物体表面某个点朝向的方向。

在进行光照计算时,需要比较光线方向、物体法线方向,当它们接近一致时说明光线正面照射物体,该区域会更亮。

反之,当光线方向与法线夹角较大时,受到的光照会减弱。

3. 小结
概念描述的内容
position 光源位置,确定光照产生的位置
direction 光照方向,影响哪些物体表面可以接收到光照
diffuse 光源颜色,会参与物体最终颜色计算
intensity 光照强度,会影响场景整体明亮效果

Part 2 Light基类与子类

1. Light抽象基类

在 Babylon 中,所有光源类型都继承自 Light 抽象基类。

Light基类定义了所有光源共有的基础能力,例如是否启用、光源颜色、光照强度等。

Light不能直接被实例化,它本身只是所有光源的抽象定义,实际使用需要创建它的子类。

const light = new BABYLON.Light(
   name: string, //必填项
   scene?: Sene //非必填
);

2. ShadowLight抽象类

ShadowLight 是 Babylon 中支持阴影计算的抽象类,它继承自Light基类。

它在Light基础上增加了光源方向、阴影投射能力与相关计算能力。

ShadowLight不能直接实例化,它主要承担阴影光源的公共能力抽象,实际使用需要创建它的子类。

3. HemisphericLight类

HemisphericLight是Babylon中一种特殊的光源类型,用于模拟环境光效果,它继承自Light基类。

与其他光源不同,它模拟现实环境中来自天空和地面的散射光,它不继承ShadowLight。

const light = new BABYLON.HemisphericLight(
   name: string, //必填项
   direction: Vector3, //必填项,光照方向
   scene?: Scene //非必填
);

  • HemisphericLight没有产生阴影的能力,更适合作为场景基础补光;

  • HemisphericLight可以通过 diffuse 设置天空方向光颜色,通过 groundColor 设置地面反射光颜色;

  • direction 用于控制上下两个半球光照方向,通常设置为 (0,1,0) 表示来自天空方向的环境光。

4. DirectionalLight类

DirectionalLight是Babylon最常用的光源之一,用于模拟类似太阳光的平行光,它继承自ShadowLight类。

它光照效果主要由光线方向决定,而不是由光源位置决定,简单地说,我们只需要定义光线传播方向,而无需关心光源位置。

const light = new BABYLON.DirectionalLight(
   name: string, //必填项
   direction: Vector3, //必填项,光照方向
   scene?: Scene //非必填
);

  • DirectionalLight不存在距离衰减,理论上它可以照亮整个Scene,适用于大范围场景以及室外环境;

  • DirectionalLight的Position主要对阴影计算产生影响,不会影响其光照范围;

5. PointLight类

PointLight用于模拟点光源,例如灯泡、蜡烛等,它继承自ShadowLight类。

PointLight 的光线从一个固定空间位置向四周发散,因此光照效果主要受到光源位置和距离影响。

const light = new BABYLON.PointLight(
   name: string,        // 必填项
   position: Vector3,   // 必填项,光源位置
   scene?: Scene        // 非必填
);

  • PointLight会随着距离增加产生光照衰减,适用于室内灯光等局部照明场景;

6. SpotLight类

SpotLight是用于模拟聚光灯效果的光源类型,例如手电筒、舞台灯等,它继承自ShadowLight类。

它同时具备位置和方向两个属性,通过限制光照范围形成锥形照射区域。

const light = new BABYLON.SpotLight(
   name: string, // 必填项
   position: Vector3, // 必填项,光源位置
   direction: Vector3, // 必填项,光照方向
   angle: number, //必填项,聚光范围
   exponent: number, //必填项,光照集中程度
   scene?: Scene // 非必填
);

7. AreaLight抽象类

AreaLight 是 Babylon 中用于表示区域光源的抽象类,它继承自Light基类。

它在Light基础上定义了区域光源共有的基础能力。

AreaLight不能直接实例化,它主要承担区域光源的公共能力抽象,实际使用需要创建它的子类。

8. RectAreaLight类

RectAreaLight是 Babylon 中用于模拟矩形区域光源的光源类型,它继承自 AreaLight类。

与点光源不同,RectAreaLight的发光源是一个具有宽度和高度的矩形区域。

const light = new BABYLON.RectAreaLight(
   name: string,        // 必填项
   position: Vector3,   // 必填项,光源位置
   width: number,       // 必填项,光源宽度
   height: number,      // 必填项,光源高度
   scene?: Scene        // 非必填
);

  • RectAreaLight 通过 width 和 height 控制光源区域大小,更适合模拟真实室内照明效果;

9. 小结

抽象类(不能直接实例化):

类型继承关系作用
Light extends Node 所有光源的基础定义
ShadowLight extends Light 在Light基础上增加阴影相关能力
AreaLight extends Light 在Light基础上定义区域光源基础能力

子类:

类型继承关系特点及适用场景
HemisphericLight extends Light 模拟天空与地面产生的环境光,不依赖光源位置,不支持阴影,适合作为场景基础补光
DirectionalLight extends ShadowLight 模拟平行光,不存在距离衰减,光照效果主要由方向决定,支持阴影,适合作为室外场景主光源
PointLight extends ShadowLight 模拟点光源,受距离影响产生衰减,光照效果主要由位置决定,支持阴影,适合作为室内局部照明
SpotLight extends ShadowLight 模拟聚光灯,通过位置、方向、角度形成锥形光照区域,支持阴影,适合作为重点区域照明
RectAreaLight extends AreaLight 模拟矩形区域光,通过一定面积发射光线,不支持阴影,照明效果更柔和,适合作为室内灯光

Part 3 Light实例成员

1. Light基类成员

name、id、uniqueId、parent、metadata等来自于Node类,这里不再汇总。

属性/方法名称参数值/返回值类型说明
diffuse Color3 光源颜色,用于定义光线本身的颜色
specular Color3 光源高光颜色,用于影响物体表面的高光效果
falloffType number 光照衰减计算类型,用于控制光照随距离变化的计算方式
intensity number 光照强度,用于控制光源的亮度
range number 光照影响范围,用于限制光源能够影响的空间距离
intensityMode number 光照强度计算模式,用于指定强度的计算方式
radius number 光源半径,用于部分光源类型模拟光源尺寸
shadowEnabled boolean 是否启用该光源的阴影计算
includedOnlyMeshes AbstractMesh[] 指定该光源仅影响的 Mesh 列表
excludedMeshes AbstractMesh[] 指定该光源排除影响的 Mesh 列表
excludeWithLayerMask number 根据 LayerMask 排除受该光源影响的对象
includeOnlyWithLayerMask number 根据 LayerMask 指定受该光源影响的对象
lightmapMode number 光照贴图计算模式,用于控制 Light 与 Lightmap 的结合方式
getViewMatrix(_faceIndex?: number) Nullable<Matrix> 获取光源视图矩阵,主要用于光照空间转换和阴影计算
getProjectionMatrix(_viewMatrix?: Matrix, _renderList?: Array<AbstractMesh>) Nullable<Matrix> 获取光源投影矩阵,主要用于阴影投影计算
transferTexturesToEffect(effect: Effect, lightIndex: string) Light 将光源相关数据传递给 Shader Effect,用于渲染计算
getClassName() string 获取当前 Light 类型名称
toString(fullDetails?: boolean) string 返回 Light 的字符串描述信息
setEnabled(value: boolean) void 设置光源是否启用
getShadowGenerator(camera?: Nullable<Camera>) IShadowGenerator | null 获取当前光源关联的阴影生成器
getShadowGenerators() Map<Camera | null, IShadowGenerator> | null 获取当前光源关联的所有阴影生成器
getAbsolutePosition() Vector3 获取光源在世界空间中的绝对位置
canAffectMesh(mesh: AbstractMesh) boolean 判断当前光源是否会影响指定 Mesh
dispose(doNotRecurse?: boolean, disposeMaterialAndTextures?: boolean) void 释放 Light 占用的资源
getTypeID() number 获取当前 Light 类型 ID
getScaledIntensity() number 获取经过强度模式计算后的实际光照强度
clone(name: string, newParent?: Nullable<Node>) Light | null 克隆当前 Light,并可以指定新的名称和父节点
serialize() any 将 Light 序列化为可保存的数据结构
2. ShadowLight类成员

ShadowLight继承自Light基类,所以它拥有Light基类的所有成员。

属性/方法名称参数值/返回值类型说明
position Vector3 光源在世界空间中的位置,用于确定光源空间位置以及阴影计算
direction Vector3 光线传播方向,用于确定光照方向以及阴影投射方向
shadowMinZ number 阴影投影近裁剪距离,用于控制阴影摄像机的近裁剪范围
shadowMaxZ number 阴影投影远裁剪距离,用于控制阴影摄像机的远裁剪范围
customProjectionMatrixBuilder (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) 自定义阴影投影矩阵计算函数,用于覆盖默认的投影矩阵计算逻辑
transformedPosition Vector3 经过变换后的光源位置,用于光照计算
transformedDirection Vector3 经过变换后的光照方向,用于光照计算
computeTransformedInformation() boolean 计算光源变换后的位置信息和方向信息
getDepthScale() number 获取阴影深度缩放比例,用于阴影深度计算
getShadowDirection(faceIndex?: number) Vector3 获取指定面的阴影投射方向,主要用于阴影计算
getAbsolutePosition() Vector3 获取光源在世界空间中的绝对位置
setDirectionToTarget(target: Vector3) Vector3 根据目标位置设置光照方向
getRotation() Vector3 获取光源当前旋转角度
needCube() boolean 判断当前光源是否需要使用立方体阴影贴图,主要用于点光源
needProjectionMatrixCompute() boolean 判断是否需要重新计算阴影投影矩阵
forceProjectionMatrixCompute() void 强制下一次渲染时重新计算投影矩阵
computeWorldMatrix(force?: boolean) Matrix 计算并获取光源世界矩阵
getDepthMinZ(activeCamera: Nullable<Camera>) number 根据当前摄像机获取阴影深度计算的最小范围
getDepthMaxZ(activeCamera: Nullable<Camera>) number 根据当前摄像机获取阴影深度计算的最大范围
setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>) IShadowLight 设置阴影投影矩阵,用于自定义阴影空间计算
getViewMatrix(faceIndex?: number) Matrix | null 获取光源视图矩阵,将世界空间转换到光源观察空间,用于阴影计算
getProjectionMatrix(viewMatrix?: Matrix, renderList?: Array<AbstractMesh>) Matrix | null 获取光源投影矩阵,将光源空间映射到裁剪空间,用于生成 ShadowMap
3. HemisphericLight类成员

HemisphericLight继承自Light基类,所以它拥有Light基类的所有成员。

属性/方法名称参数值/返回值类型说明
groundColor Color3 地面方向光照颜色,用于模拟来自地面的环境反射光
direction Vector3 光照方向,用于确定天空方向的光照来源
getClassName() string 获取当前 Light 类型名称
setDirectionToTarget(target: Vector3) Vector3 根据目标位置设置光照方向
getShadowGenerator() IShadowGenerator | null 获取阴影生成器,由于 HemisphericLight 不支持阴影,通常返回 null
transferToEffect(_effect: Effect, lightIndex: string) HemisphericLight 将当前光源数据传递到 Shader Effect,用于渲染计算
transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) HemisphericLight 将当前光源数据传递给 Node Material 使用的 Shader Effect
computeWorldMatrix() Matrix 计算并获取光源世界矩阵
getTypeID() number 获取当前 Light 类型 ID
prepareLightSpecificDefines(defines: any, lightIndex: number) void 准备当前光源类型对应的 Shader 宏定义,用于渲染时区分光源类型
4. DirectionalLight类成员

DirectionalLight继承自ShadowLight类,所以它拥有ShadowLight类的所有成员。

属性/方法名称参数值/返回值类型说明
shadowFrustumSize number 阴影视锥体大小,用于控制方向光阴影覆盖范围
shadowOrthoScale number 正交阴影投影缩放比例,用于调整阴影投影范围
autoUpdateExtends boolean 是否根据受影响 Mesh 自动更新阴影投影范围
autoCalcShadowZBounds boolean 是否自动计算阴影深度范围,用于优化阴影裁剪区域
orthoLeft number 阴影正交投影区域左侧边界
orthoRight number 阴影正交投影区域右侧边界
orthoTop number 阴影正交投影区域顶部边界
orthoBottom number 阴影正交投影区域底部边界
getClassName() string 获取当前 Light 类型名称
getTypeID() number 获取当前 Light 类型 ID
transferToEffect(effect: Effect, lightIndex: string) DirectionalLight 将当前方向光数据传递给 Shader Effect,用于渲染计算
transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) Light 将当前方向光数据传递给 Node Material 使用的 Shader Effect
prepareLightSpecificDefines(defines: any, lightIndex: number) void 准备方向光对应的 Shader 宏定义,用于渲染时区分光源类型
5. PointLight类成员

PointLight继承自ShadowLight类,所以它拥有ShadowLight类的所有成员。

属性/方法名称参数值/返回值类型说明
shadowAngle number 阴影投射角度,用于控制点光源阴影计算范围
direction Vector3 光照方向,用于部分光照计算场景下的方向控制
getClassName() string 获取当前 Light 类型名称
getTypeID() number 获取当前 Light 类型 ID
needCube() boolean 判断当前光源是否需要使用立方体阴影贴图,点光源由于向四周发射光线,返回 true
getShadowDirection(faceIndex?: number) Vector3 获取指定阴影面对应的光照方向,用于点光源六面体阴影计算
transferToEffect(effect: Effect, lightIndex: string) PointLight 将当前点光源数据传递给 Shader Effect,用于渲染计算
transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) PointLight 将当前点光源数据传递给 Node Material 使用的 Shader Effect
prepareLightSpecificDefines(defines: any, lightIndex: number) void 准备点光源对应的 Shader 宏定义,用于渲染时区分光源类型
6. SpotLight类成员

SpotLight继承自ShadowLight类,所以它拥有ShadowLight类的所有成员。

属性/方法名称参数值/返回值类型说明
iesProfileTexture BaseTexture | null IES 光照分布纹理,用于加载真实灯具的光照分布数据
angle number 聚光灯照射角度,用于控制光锥范围大小
innerAngle number 聚光灯内部照射角度,用于控制中心区域的光照范围
shadowAngleScale number 阴影角度缩放比例,用于调整阴影投射范围
exponent number 光照衰减指数,用于控制光线从中心向边缘的集中程度
projectionTextureMatrix Matrix 投影纹理矩阵,用于计算投影纹理坐标
projectionTextureLightNear number 投影纹理光源近裁剪距离
projectionTextureLightFar number 投影纹理光源远裁剪距离
projectionTextureUpDirection Vector3 投影纹理计算时使用的向上方向
projectionTexture BaseTexture | null 投影纹理,用于将纹理投射到受光物体上
projectionTextureProjectionLightMatrix Matrix 投影纹理对应的光源投影矩阵
getClassName() string 获取当前 Light 类型名称
getTypeID() number 获取当前 Light 类型 ID
transferToEffect(effect: Effect, lightIndex: string) SpotLight 将当前聚光灯数据传递给 Shader Effect,用于渲染计算
transferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) SpotLight 将当前聚光灯数据传递给 Node Material 使用的 Shader Effect
dispose() void 释放 SpotLight 占用的资源
prepareLightSpecificDefines(defines: any, lightIndex: number void 准备聚光灯对应的 Shader 宏定义,用于渲染时区分光源类型
7. AreaLight类成员

AreaLight继承自Light基类,所以它拥有Light基类的所有成员。

属性/方法名称参数值/返回值类型说明
position Vector3 区域光源在世界空间中的位置,用于确定光源所在空间位置
transferTexturesToEffect(effect: Effect) Light 将区域光源相关纹理数据传递给 Shader Effect,用于渲染计算
prepareLightSpecificDefines(defines: any, lightIndex: number) void 准备区域光源对应的 Shader 宏定义,用于渲染时区分光源类型
8. RectAreaLight类成员

RectAreaLight继承自AreaLight类,所以它拥有RectAreaLight类的所有成员。

属性/方法名称参数值/返回值类型说明
width number 矩形区域光源的宽度
height number 矩形区域光源的高度
getClassName() string 获取当前 Light 类型名称
getTypeID() number 获取当前 Light 类型 ID
transferToEffect(effect: Effect, lightIndex: string) RectAreaLight 将当前区域光源数据传递给 Shader Effect,用于渲染计算
ransferToNodeMaterialEffect(effect: Effect, lightDataUniformName: string) RectAreaLight 将当前区域光源数据传递给 Node Material 使用的 Shader Effect

Part 4 Shadow系统

1. Shadow概述

阴影Shadow用于模拟光线被物体遮挡后产生的暗部区域。

在Babylon中Shadow 并不是由Light单独完成的,而是通过Light、ShadowGenerator 以及ShadowMap共同实现。

支持阴影的光源均继承自ShadowLight抽象类:

Light
|
+– ShadowLight
      |
      +– DirectionalLight
      +– PointLight
      +– SpotLight

2. ShadowGenerator类

阴影生成器ShadowGenerator是 Babylon 中负责管理阴影的核心对象,它不负责光源,而是生成阴影的管理器。

ShadowGenerator通过绑定支持Shadow的Light对象,根据Light的光源位置Position、光源方向Direction、光照范围Range等信息,判断哪些位置该生成阴影。

同时,ShadowGenerator还负责管理哪些Mesh可以产生阴影并配置阴影效果,生成深度纹理ShadowMap,将数据传递给接收阴影的物体,使其参与最终颜色效果的计算。

new ShadowGenerator(
mapSize: number, //必填项,阴影贴图的分辨率
   light: IShadowLight, //必填项,用于生成阴影的光源对象
   usefullFloatFirst?: boolean, //可选,是否优先使用完整浮点纹理存储 ShadowMap 数,可提高阴影深度精度
   camera?: Nullable<Camera>, //可选,指定使用的 Camera
   useRedTextureType?: boolean, //可选,是否使用单通道红色纹理格式存储 ShadowMap 数据,控制ShadowMap 的纹理格式
   forceGLSL?: boolean //可选,是否强制使用 GLSL Shader,主要用于兼容性控制
)

ShadowGenerator的阴影管理,主要对阴影产生物体ShadowCaster进行管理,它表示能够遮挡光线并产生阴影的 Mesh。

Mesh需开启receiveShadows能力使自身成为阴影接收物体ShadowReceiver。

阴影效果的呈现以上两者缺一不可,如果没有产生阴影的物体,即时配置接收阴影的物体也没有效果;如果没有接收阴影的物体,即时全部物体可以产生阴影也不会有效果。

3. ShadowGenerator类成员
属性/方法名称参数值/返回值类型说明
id string 唯一标识名称
customShaderOptions ICustomShaderOptions 自定义阴影 Shader 配置项,用于扩展阴影渲染逻辑
customAllowRendering (subMesh: SubMesh) => boolean 自定义判断 SubMesh 是否参与阴影渲染的函数
bias number 阴影偏移量,用于减少 ShadowMap 深度比较误差导致的阴影痤疮问题
normalBias number 基于物体法线方向的阴影偏移,用于进一步改善阴影边缘错误
blurBoxOffset number 阴影模糊采样范围偏移,用于控制模糊效果
blurScale number 阴影模糊缩放比例,用于调整模糊范围
blurKernel number 阴影模糊采样核大小,用于控制阴影柔化程度
useKernelBlur boolean 是否启用 Kernel Blur 模糊算法
depthScale number 深度计算缩放比例,用于调整阴影深度精度
filter number 阴影过滤方式,用于选择不同 ShadowMap 采样算法
usePoissonSampling boolean 是否使用 Poisson 采样优化阴影边缘效果
useExponentialShadowMap boolean 是否启用指数阴影贴图ESM算法
useBlurExponentialShadowMap boolean 是否启用带模糊处理的指数阴影贴图
useCloseExponentialShadowMap boolean 是否启用近距离优化的指数阴影贴图
useBlurCloseExponentialShadowMap boolean 是否启用带模糊处理的近距离指数阴影贴图
usePercentageCloserFiltering boolean 是否启用 PCF阴影过滤,使阴影边缘更加平滑
filteringQuality number 阴影过滤质量级别,用于控制 PCF 等过滤效果质量
useContactHardeningShadow boolean 是否启用接触硬化阴影,使阴影根据距离产生软硬变化
contactHardeningLightSizeUVRatio number 接触硬化阴影中光源尺寸与 UV 比例,用于控制软阴影范围
darkness number 阴影黑暗程度,控制阴影区域的暗度
transparencyShadow boolean 是否支持透明物体产生透明阴影
enableSoftTransparentShadow boolean 是否启用透明物体的柔和阴影效果
useOpacityTextureForTransparentShadow boolean 是否使用透明贴图参与透明阴影计算
frustumEdgeFalloff number 阴影视锥边缘衰减范围,用于减少阴影边缘突然消失的问题
forceBackFacesOnly boolean 是否强制仅使用 Mesh 背面生成阴影,用于减少阴影偏差问题
mapSize number ShadowMap尺寸大小,决定阴影贴图分辨率和阴影精度
getDarkness() number 获取当前阴影黑暗程度
setDarkness(darkness: number) ShadowGenerator 设置阴影黑暗程度
setTransparencyShadow(transparent: boolean) ShadowGenerator 设置是否启用透明阴影
getShadowMap() RenderTargetTexture | null 获取用于保存阴影信息的 ShadowMap 纹理
getShadowMapForRendering() RenderTargetTexture | null 获取当前用于渲染流程中的 ShadowMap
getClassName() string 获取当前对象类型名称
addShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean) ShadowGenerator 添加产生阴影的 Mesh
removeShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean) ShadowGenerator 移除产生阴影的 Mesh
getLight() IShadowLight 获取当前绑定的光源
forceCompilation(onCompiled?: (generator: IShadowGenerator) => void, options?: Partial<{ useInstances: boolean; }>) void 强制编译阴影相关 Shader
forceCompilationAsync(options?: Partial<{ useInstances: boolean; }>) Promise<void> 异步编译阴影 Shader
isReady(subMesh: SubMesh, useInstances: boolean, isTransparent: boolean) boolean 判断指定 SubMesh 是否已经准备好进行阴影渲染
prepareDefines(defines: any, lightIndex: number) void 准备阴影相关 Shader 宏定义
bindShadowLight(lightIndex: string, effect: Effect) void 将阴影光源数据绑定到 Shader Effect
viewMatrix() Matrix 获取阴影计算使用的光源视图矩阵
projectionMatrix() Matrix 获取阴影计算使用的光源投影矩阵
getTransformMatrix() Matrix 获取阴影变换矩阵,用于将世界坐标转换到 ShadowMap 空间
recreateShadowMap() void 重新创建 ShadowMap
dispose() void 释放 ShadowGenerator 相关资源
serialize() any 将 ShadowGenerator 序列化为可保存的数据结构

ICustomShaderOptions的配置内容包括:

参数名称参数值类型参数作用
shaderName string Shader 名称,用于标识当前自定义 Shader,Babylon 会根据该名称查找对应的 Vertex Shader 与 Fragment Shader 源码
attributes string[] | undefined 定义 Vertex Shader 使用的顶点属性名称,用于声明需要从 Geometry 顶点缓冲区读取的数据
uniforms string[] | undefined 定义 Shader 使用的全局变量名称,用于传递 CPU 侧数据到 GPU
samplers string[] | undefined 定义 Shader 使用的纹理采样器名称,用于声明需要绑定到 Shader 中的纹理资源
defines string[] | undefined 定义 Shader 编译时的宏条件,用于控制 Shader 编译逻辑,实现不同功能分支或优化
4. 从三维世界到屏幕的过程

在Camera篇中讲到,一个物体最终呈现在屏幕的位置,由物体的世界坐标通过视图矩阵Camera View Matrix再到投影矩阵Camera Projection Matrix转换而来。

简单的说,一个物体最终在屏幕中的位置,由Camera的矩阵变换决定。

那么物体最终在屏幕上的呈现效果呢?

物体最终的视觉效果由Light光照计算、Material材质计算、Shadow阴影计算、PostProcess后处理效果共同决定,其中:

  • Light 决定物体受到的光照强弱以及明暗关系;

  • Material 决定物体表面的颜色、金属度、粗糙度、纹理等材质表现;

  • Shadow 根据光源遮挡关系计算阴影区域,对光照结果进行衰减;

  • PostProcess 对最终渲染结果进行屏幕后处理;

这里我们不对Material材质计算与PostProcess后处理效果进行深入说明,后续单独篇章中会讲到。

Light 光照计算通过光源参数与物体表面法线的关系,计算物体表面受到的光照贡献,从而决定物体的明暗和光照效果。

光照计算是计算光源颜色、光照强度以及物体法线与光照方向的过程,它决定的是物体表面的明暗效果。

简单来讲,它只负责描述物体表面哪部分更亮,哪部分更暗。

Shadow阴影计算则稍微复杂,在较大的场景中也会带来明显的性能开销。

首先ShadowGenerator基于它所绑定的Light,通过光源视图矩阵Light View Matrix和光源投影矩阵Light Projection Matrix建立光源空间。

光源视图矩阵Light View Matrix负责将世界空间中的物体转换到 Light 的观察空间。

光源投影矩阵Light Projection Matrix将光源观察空间中的坐标转换到 ShadowMap 使用的二维空间。

建立光源空间后ShadowGenerator会生成对应的ShadowMap,它本质上是一张特殊的深度纹理,不保存颜色信息,而是从光源角度记录每个位置距离光源的关系。

Shader计算时,会根据ShadowMap的深度信息,对Light光照计算结果进行衰减,综合Material材质计算与PostProcess后处理效果计算最终的呈现效果。

Part 5 Light常用功能

1. HemisphericLight场景基础补光

HemisphericLight不依赖光源位置,通常作为作为场景环境补光。

常用配置项包括:

配置项参数类型作用描述
direction Vector3 决定天空光照射方向,通常(0, 1, 0)表示从上方向下照射
diffuse Color3 设置天空光颜色
groundColor Color3 设置地面反射光颜色
intensity number 设置光照强度
  • HemisphericLight无法产生阴影,不能作为ShadowGenerator的阴影光源;

  • intensity通常作为基础环境光,不建议设置过强;

2. DirectionalLight场景主光源

DirectionalLight光线方向固定且不会随着距离产生衰减,通常作为场景中的主光源。

常用配置项包括:

配置项参数类型作用描述
direction Vector3 设置光照方向,决定光线从哪个方向照射场景
position Vector3 设置光源位置,由于它不会随距离产生衰减,因此主要用于阴影计算
diffuse Color3 设置直射光颜色
specular Color3 设置地高光反射颜色
intensity number 设置光照强度
  • DirectionalLight支持ShadowGenerator生成阴影,是三维场景中最常用的阴影光源类型;

  • intensity避免过高导致场景过曝,实际使用中建议配合HemisphericLight进行调整;

3. ShadowGenerator生成阴影

ShadowGenerator用于根据光源与场景物体之间的遮挡关系生成阴影效果,在较大场景中一般是主要的性能瓶颈之一。

常用配置包括:

配置项参数类型作用描述
mapSize number 设置阴影贴图分辨率,越高越清晰
bias number 设置阴影偏移量,用于解决阴影自遮挡产生的阴影痤疮
normalBias number 根据表面法线方向调整阴影偏移,减少斜面阴影异常问题
filter number 设置阴影过滤方式,用于优化阴影边缘效果
usePercentageCloserFiltering boolean 开启PCF阴影过滤,使阴影边缘更加平滑
darkness number 设置阴影黑暗程度,控制阴影区域的透明效果
blurScale number 设置阴影模糊强度,用于改善硬阴影边缘效果
addShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean) ShadowGenerator 添加产生阴影的 Mesh
removeShadowCaster(mesh: AbstractMesh, includeDescendants?: boolean) ShadowGenerator 移除产生阴影的 Mesh
  • 要开启阴影效果,首先依赖于支持阴影的光照Light及其合理配置,HemisphericLight与RectAreaLight不支持阴影;

  • 生成阴影首先要创建ShadowGenerator实例,并通过addShadowCaster设置产生阴影的Mesh;

  • 需要有开启了receiveShadows的Mesh作为阴影接收者,才能看见阴影效果;

    总之,要实现阴影效果,ShadowLight光照、ShadowCaster阴影生成者、ShadowReceiver阴影接收者三者的配置缺一不可;

  • mapSize过高会增加GPU压力,在大型三维场景中需要平衡性能与效果;

  • 开启阴影会增加额外渲染开销,需要避免将大量Mesh加入ShadowCaster中;

Part 6 踩坑记录

1. 阴影配置不生效
  • 首先检查是否正确创建支持阴影的光源,且是否在正确的Scene中;

  • 检查全局配置scene.lightsEnabled与scene.shadowsEnabled是否为开启状态;

  • 检查是否在对应的Scene场景中创建ShadowGenerator,并添加addShadowCaster列表是否正确添加Mesh或是否为空;

  • 检查是否对需要接收阴影的Mesh配置了receiveShadows = true;

  • 检查光照的方向、强度是否合理,避免光照未覆盖目标区域导致无法观察阴影;

  • 检查接收阴影的Mesh是否在阴影投射范围;

2. 阴影边缘出现条纹、闪烁或黑色噪点
  • 首先确认问题是否由 ShadowGenerator 引起,可以临时关闭阴影进行对比;

  • 检查 ShadowGenerator.bias 是否过小,导致模型自身深度比较产生误判;

  • 检查 normalBias 是否需要调整,尤其是建筑、地面等大面积倾斜模型;

  • 检查 ShadowMap 的mapSize分辨率是否过低,低分辨率可能导致阴影精度不足:

3. Light与Shadow性能调优
  • 首先场景中的Light数量不宜过多,尤其避免大量PointLight、SpotLight参与实时光照计算;

  • 检查ShadowGenerator的mapSize是否合理,过大的ShadowMap会增加GPU显存占用和渲染压力;

  • 检查ShadowGenerator中添加的ShadowCaster数量是否过多,避免将所有Mesh加入阴影计算;

  • 检查ShadowGenerator的阴影过滤方式,例如usePercentageCloserFiltering、useContactHardeningShadow等,高质量过滤会增加额外计算成本;

  • 检查ShadowGenerator的bias、normalBias设置,避免为了修复阴影痤疮问题过度增加偏移导致阴影质量下降;

  • 检查ShadowGenerator的filter类型选择,根据场景需求选择PCF、PCF Soft、ESM等阴影算法;

  • 检查阴影范围是否合理,避免Shadow Camera覆盖过大的无效区域导致阴影精度下降;

  • 检查是否存在大量透明模型参与阴影计算,避免产生额外Shadow Pass开销;

总结

Light 是 Babylon 中负责模拟真实世界光照效果的核心模块,它决定了场景中物体如何受到光线影响,是连接三维空间、材质表现以及最终视觉效果的重要组成部分。虽然Light本身的API结构相对简单,但其背后涉及光照计算、法线、材质响应、阴影生成以及GPU渲染流程等多个三维核心概念,在实际项目中也是最容易影响场景表现和性能的模块之一。

本文主要整理了 Light 的基础概念、不同类型光源、光照计算流程、常用配置、ShadowGenerator 阴影机制以及实际开发过程中遇到的常见问题与性能调优方案。希望通过 API 梳理与项目实践结合的方式,帮助开发者不仅了解不同光源的使用方式,也能够理解 Light 与 Shadow 在最终渲染效果中的作用关系,以及遇到光照异常时的排查思路。

在实际三维项目中,Light 并不是简单的“增加亮度”,而是需要根据场景规模、模型数量以及展示需求合理组合使用。通常通过环境补光、主光源以及必要的阴影效果共同构建场景光照,同时结合性能优化避免过多光源和阴影计算带来的额外开销。

后续会继续整理 Babylon.js 8.x 其他核心模块。

赞(0)
未经允许不得转载:171主机测评 » Babylon.js 8.x 中文文档整理——Light篇
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址