【ue4】【使用】光照系统_阴影

前言

UE4 的光源类型有: 平行光 点光源 聚光源 天光(环境光)

也是比较典型的光源类型, 关于这些光源类型的介绍和相关参数, 可参考此篇

【cg】【原理】光照模型 中的预备知识第二条 光源类型

ue 现在还多了个 矩形光源, 个人感觉然并卵

每一种光源都可以设置它的 Transform 信息 和 移动性类型

【Tips】位置信息对于平行光来说是无效的

移动性 Mobility

【话外音_Begin】在写这篇博客之前, 我纠结了很久, 到底是先写移动性、还是先写光源类型、还是说先介绍一下Lightmass, 感觉这三者的依赖关系太复杂了, 像三角恋一样。

【话外音_End】

光源的移动性决定其影响物体所使用的方式, 而物体本身也有三种移动性属性可以选择(烦)

静态光源 static light

在运行时不会以任何方式改变或移动

光的位置 -- 不能变

光的颜色 -- 不能变

光的强度 -- 不能变

光的其他属性 -- 也不能变

静态光源只在光照贴图中进行计算, 即预处理 (烘焙) 出所有的光照和阴影

直接光照 -- 光照贴图

间接光照 -- 光照贴图

直接阴影 -- 光照贴图

间接阴影 -- 没得

静态光源产生的阴影叫做__区域 (接触) 阴影__

而这个区域阴影的柔和程度是受 光源半径 (Light Source Radius)光照贴图分辨率 (Lightmap Resolution) 影响的

下面是分别设置光源半径为 50 和 400 的区别, 可以看到 400 的比 50 的要温柔多了

至于光照贴图分辨率, 顾名思义一下也知道是用来控制烘焙出的光照信息的细节程度的

我们可以在 SM 的 Override Lightmap Res 选项来设置, 数值越大分辨率越高

我们也可以在 BSP表面属性的 Lightmap Resolution 属性来设置, 此处数值越大分辨率越低 (密度属性)

固定光源 stationary light

在运行时位置保持固定, 但其他方面的属性如亮度和颜色可以修改

但是在运行时对亮度进行修改, 只会影响直接光照 -- 间接光照是烘焙出来的, 所以不会变

光的位置 -- 不能变

光的颜色 -- 能变

光的强度 -- 能变

光的其他属性 -- 能变

固定光源的直接光照使用延迟着色直接渲染 -- 这也是运行时可以改光颜色和亮度的原因

其直接阴影被存储在阴影贴图 (shadowmap) 中

而其所有的间接光照和阴影都存储在光照贴图中

直接光照 -- 延迟着色直接渲染

间接光照 -- 光照贴图

直接阴影 -- 阴影贴图 -- 静态 和 动态 都是

间接阴影 -- 光照贴图 ? (不是很清楚)

由于固定光源是后面介绍的 Lightmass 所能利用的最好的光源 (个人理解), 所以固定光源的阴影也比较复杂, 不仅动态和静态的不一样, 静态的还得区分半透明物体, 同时定向固定光源还有自身特殊的阴影方案, 这个在后面再作详细展开。

动态光源 movable light

动态光源的任何属性 (包括位置) 都可以在运行时改变

动态光源不会烘焙到光照贴图中去, 它产生完全动态的光照和阴影

在 Lightmass 的方案中, 动态光源不会产生间接光照 (hehe)

直接光照 -- 动态渲染

间接光照 -- 无

直接阴影 -- 全场景动态阴影

间接阴影 -- 无

动态光源的阴影采用全场景动态阴影, 性能开销比较大

但是对于动态的点光源或聚光源, 又可以使用 阴影贴图缓存 (shadowmap cache) 来优化全场景动态阴影

最后用一张表总结一下以上三种的差异

移动性可变性质量性能消耗用途
静态光源低功率的移动平台
固定光源中高端的移动平台
动态光源高端移动和PC平台

【Tips】 这里说动态光源质量低是在 Lightmass (静态GI) 方案下

ue4 的光源类型

【cg】【原理】光照模型

定向 (平行) 光源

静态 -- 光照贴图

固定 -- 直接光是动态的, 间接光和阴影是光照贴图

可移动 -- 完全动态的, 无间接光, 全场景动态阴影

属性

平行光的属性大致分为 5 种

光照

绿色的选项都是与阴影相关的 (还挺多的)

英文中文解释
Intensity强度光照的整体强度
Light Color光的颜色光照的颜色
Source Angle角直径人眼看到的光源的直径 (默认为太阳的 0.5357 度)
Affects World影响世界完全禁用光源 (不能在运行时设置) (要想在运行过程中禁用光源的效果, 可以改变它的 Visibility 属性
Indirect Lighting Intensity间接光照强度缩放来自光源的间接光照的量
Atmosphere / Fog Sun Light用作大气中的日光是否使用这个定向光源来定义太阳在天空中的位置
Dynamic Indirect Lighting是否要将该光照注入 LPV (Light Propagation Volume) (动态GI)
Affect Translucent Lighting影响半透明物体的光照该光源是否影响半透明物体
Transmission透射是否开启透射 (需要将光源设置为 movable)

下面是和阴影有关的选项

英文中文解释
Casts Shadows投射阴影光源是否投射阴影
Cast Static Shadows投射静态阴影该光源是否投射静态阴影
Cast Dynamic Shadows投射动态阴影该光源是否投射动态阴影
Cast Translucent Shadows投射半透明阴影该光源是否可以透过半透明物体投射动态阴影
Casts Modulated Shadows投射调制阴影是否投射调制阴影 (只限移动端平台)
Casts Volumetric Shadow投射体积雾阴影是否投射体积雾阴影 (禁用可节约GPU性能)
Shadow Bias阴影偏差控制来自来自这个光源的阴影的精确度
Shadow Filter Sharpen阴影滤镜锐化阴影滤镜锐化该光源的程度
光束

关于光束的概念后面会提到, 现在可以想像一下, 在一个美好的清晨, 一道美丽的曙光照亮了你俊俏的脸庞, 那就是光束了。

英文中文解释
Light Shaft Occlusion启用光束遮挡同屏幕空间之间发生散射的雾和大气是否遮挡该光照
Occlusion Mask Darkness遮挡蒙板的黑度遮挡蒙板的黑度,值为 1 则不会变黑
Occlusion Depth Range遮挡深度范围和相机之间的距离小于这个值的任何物体都将会遮挡光束
Light Shaft Bloom启用光束的光溢出是否渲染这个光源的光束的光溢出效果
Bloom Scale光溢出缩放缩放叠加的光溢出颜色
Bloom Threshold光溢出阈值场景颜色必须大于这个值才能在光束中产生光溢出
Bloom Tint光溢出色调给光束发出的光溢出效果着色所使用的颜色
Light Shaft Override Direction光束方向覆盖可以使得光束从另一个地方发出,而不是从该光源的实际方向发出
Lightmass

英文中文解释
Light Source Angle ?光源角度定向光源的发光表面相对于一个接收者伸展的度数,它可以影响半影大小
Indirect Lighting Saturation间接光照饱和度0 -- 完全去饱和; 1 -- 保持不变
Shadow Exponent阴影指数控制阴影半影的衰减
Use Area Shadows for Stationary Light为固定光源使用区域阴影为固定光源使用区域阴影
光照函数

关于光照函数的事情也会在后面提到

在 ue4 里, 我们同样可以对一个光源使用材质, 来改变它本身的一些特性, 从而产生一些有趣的现象

英文中文解释
Light Function Material光照函数材质应用到这个光源上的光照函数材质
Light Function Scale光照函数缩放比例缩放光照函数投射
Light Function Fade Distance光照函数衰减距离光照函数在该距离处会完全衰减为 Disabled Brightness (禁用的亮度) 中所设置的值
Disabled Brightness禁用的亮度当指定了光照函数但却将其禁用了时,光源应用的亮度因数,参照上面的属性: Light Function Fade Distance
级联阴影贴图 cascade shadow map

前面我们讲固定光源的时候也提到了, 固定光源的阴影方案比较多样且复杂

而级联阴影贴图则是针对于__定向固定光源__ 的一种全景阴影方案

我们也会在后面讲到阴影的时候提到

英文中文解释
Dynamic Shadow Distance MovableLight可移动光源的动态阴影距离从摄像机位置算起,对于可移动灯光而言,级联阴影贴图 生成阴影的距离
Dynamic Shadow Distance StationaryLight固定光源的动态阴影距离从摄像机位置算起,对于可移动灯光而言,级联阴影贴图 生成阴影的距离
Num Dynamic Shadow Cascades为整个场景动态阴影划分视图视锥的级联数量越多阴影分辨率越高, 性能消耗越多
Distribution Exponent分布指数控制级联分布是靠近摄像机(较小的指数),或者离 Camera 较远(较大的指数)
Transition Fraction级联间淡化区域比例级联之间过渡的比例
Distance Fadeout Fraction远处淡化区域的大小控制动态阴影淡出区域的大小
Inset Shadows for Movable Objects可移动对象插入阴影(仅静态光源)即便是级联阴影贴图启用时,是否要使可移动组件逐对象插入阴影

点光源

类似于灯泡, 不过简化为从空间一点朝各个方向均匀地发光了

ue4 中的点光源除了位置信息之外, 还提供了半径和长度

属性

光照

英文中文解释
Attenuation Radius衰减半径越大性能消耗越大
Source Radius光源半径设置光源的半径,以决定静态阴影的柔和度和反射表面上的光照的外观
Light Falloff Exponent光源衰减指数控制光照的径向衰减
Source Length光源长度设置光源的长度 (光源的形状是个两段端具有半球的圆柱体: 在虚幻引擎4中称之为 Sphyl ) 来决定静态阴影的柔和度和反射表面上光照的外观
Use Inverse Squared Falloff平方反比衰减该光源是否使用平方反比衰减
光源概述文件 IES

英文中文解释
IES TextureIES贴图光源概述文件所使用的"贴图"
Use IES Brightness使用IES亮度如果该项为false,它将会使用光源的 亮度 来决定要产生多少光照。如果该项为true,它将会使用IES文件的亮度(一般比虚幻引擎中光源的默认值大很多),以流明为单位
IES Brightness ScaleIES亮度缩放比例IES亮度影响量的缩放比例,因为它们可能会使整个场景变黑

【Tips】 IES文件是ASCII码文件,尽管虚幻引擎将其呈现为贴图,但它们不是图片文件

聚光源

类似于手电筒或聚光灯

ue4 的聚光源与一般的聚光源没有什么区别, 也是通过内切角和外切角来控制衰减

属性

光源

英文中文解释
Inner Cone Angle内锥角设置聚光源的内锥角,以度数为单位
Outer Cone Angle外锥角设置聚光源的外锥角,以度数为单位

天光

天空光照会获取 SkyDistanceThreshold 以外的一切物体作为光照

SkyDistanceThreshold 称为天空距离阈

这些物体可以包括__大气层、云层、远处的群山、cubemap__等

天光捕获场景的时机

静态天光 -- 构建光照时会自动捕获

固定或动态天光 -- 加载时捕获 or 调用 Recapture Scene 时捕获

【Tips】天光会比环境光照 (Ambient Cubemap) 更加真实 -- 支持局部阴影

静态天光

只会捕获静态或固定的物体, 并将光照烘焙到光照贴图中

【Tips】移动平台只支持静态天光

【Tips】静态天光采用__过滤的立方体贴图?__来优化其方向性

固定天光

与固定的光照相同, 直接光可以在运行时修改 (延迟着色直接渲染)

而间接光则会烘焙到光照贴图中去

动态天光

动态天光实时地进行光照计算, 性能消耗比较大

【Tips】动态天光可使用__距离场环境遮挡__优化

属性

英文中文解释
Source Type源类型SLS捕捉场景 -- 从捕获的场景 (Sky Distance Threshold以外的一切) 构造天光; SLS指定的Cubemap -- 从指定的立方体贴图中构造天光
Cubemap立方体贴图如果 Source Type 设置为 SLS_SpecifiedCubemap 时,定义要为天空光照使用的 Cubemap
Sky Distance Threshold天空距离阈值从 天空光照 位置算的距离,该数值下的任何东西都会被认为是天空的一部分(也会参与反射捕获)。
Lower Hemisphere is Solid Color下半球是纯色是否将来自下半球的光线设置为 0。这对防止下半球的光线溢出是有有用的?
Recapture Scene捕捉场景当 天空光照 Actor 设置为 SLS_CapturedScene 时,用于重新捕捉场景

准备

为了更好地进行光源测试, 我们需要对场景做一些设置

当然这些设置不是必要的, 只是一些个人的强迫症式的做法, 这里列举一下

首先我给场景加了一个 Landscape, 然后增加了一个没有镜面光 (设置 Specular 为 0) 的材质给它, 这样只是个人看起来比较舒服而已-_-

增加了 ppv (后处理体积) 和 liv (Lightmass重要体积)

然后通过后处理 (post process) 对 GI 产生的光照 (间接光) 修改了一下颜色, 以增加对间接光的辨识

去掉了天空盒

静态光源

对静态物体

平行光

静态平行光对静态物体, 会完全使用烘焙出的光照贴图, 没有任何运行时动态的信息, 所以在运行时对性能消耗较小

上图是在场景中放了一个静态的平行光且烘焙了的效果, 可以看到是有间接光的 (背光方向不是全黑)

这是因为在 WorldSetting 的 Lightmass 选项里默认是设置 Num Indirect Lighting Bounces 即间接光反射次数 为 3 的

下面我们将此值设置为 0 看看效果

可以看出这次场景中就只有直接光照了, 跟上面的图片有一个很明显的对比

【Tips_Begin】 这个时候如果我们把在 ppv 里设置的红色的 GI 显示出来, 会发现场景中也都变成红色的了, 难道是静态光源的直接光照也算是 GI ? 这一点我很疑惑-_-

看起来这个直接光难不成也是间接漫反射 ? 希望有大佬能帮我解惑-_-

【Tips_End】

下面我们再来看看此时的阴影

毫无疑问, 此时的阴影为静态阴影, 因为没有什么是动态的

事实上, 此时的静态平行光为__区域光源__, 即它的影响范围有一定的大小

平行光的区域是一个放在当前场景边缘的圆盘

既然说它是区域的, 那么自然就有大小之分了

所以此类平行光的阴影柔和度可由此光源的大小来控制,

除此之外, 阴影到遮光物的距离也是影响其柔和度的因素之一

光源的大小越大, 离遮光物的距离越远, 投射的阴影就越柔和

下面这张图就是调大静态平行光的 Light Source Angle 之后的效果, 都柔和地没有了~~

除此之外, 调节 光照贴图分辨率 也可以获得效果更好的阴影

结论

让我们来总结一下, 静态的平行光 对 静态物体 的影响

首先光照和阴影都是只有静态的 (因为也没有动态的东西出现)

从光照来看

直接光照 -- 静态的, 来自 lightmap, (也属于 GI?)

间接光照 -- 静态的, 来自 lightmap, 属于 GI -- 间接漫反射 > 可从 WorldSetting 设置间接反射次数

从阴影来看

直接阴影 -- 静态的, 来自光照贴图, 属于 区域阴影 > 光源大小越大, 柔和度越高 > 离遮光物越远, 柔和度越高

间接阴影 -- 静态的, 来自光照贴图, 属于 区域阴影

点光源

从光照和阴影的角度来看, 点光源的表现与平行光几乎相同

下面两张分别是有3次间接反射和没有间接反射时的效果

可以看出阴影也很柔和

点光源与平行光不同的是, 点光源可以通过调节 Source Radius 来控制光源的大小, 从而调整阴影的柔和度, 就像上面说到的平行光的 Light Source Angle 一样

图中黄色的即为 Source Radius 的大小 (蓝色为衰减半径)

可以看到, 阴影已经柔和地快没了。。

聚光源

聚光和点光就更像了, 除了可以增加衰减用的内切角和外切角

上图分别为反射3次, 反射0次 和 比较大的光源半径时的阴影效果

天光

天空光源会把远方的静态或固定物体 (距离大于 Sky Distance Threshold) 的光收集过来, 对当前的场景产生__间接漫反射__

呈现出一种全局的环境光 (Ambient) 效果

不过貌似没有阴影。。

只是作为场景中必不可少的部分环境光而已, 要想实现真实的光和影, 还需要其他的光源的配合

其光照也是使用光照贴图进行预计算的

可以通过 WorldSetting 里的 Num Sky Lighting Bounces 来设置其进行间接漫反射的次数

对动态物体

对于动态物体, 静态光源与之没有交集,

所以既没有阴影, 也没有光照

下面三张图上, 分别是平行光、点光和聚光的效果

可以看到都没有产生阴影

但是, 光照哪来的 ?

这里的光照并非是静态光源产生的光照贴图烘焙出来的

而是由 间接光照缓存体积光照贴图 技术生成的, 这个会在后面讲固定光源的时候讲到,

到底是哪一个取决于我们在 WorldSetting 里的设置

对于天光, 也是如此

对固定物体

在静态光源眼里, 固定物体与动态物体都是一样, 都挺不受待见的

总结一下

从上面的分析也可以看出来, 静态光源只对于静态物体有比较好的效果, 所以也是没有办法的时候用于低端机上

静态光源只生成光照贴图, 而没有阴影贴图

静态光源对静态物体

直接光照 -- Lightmap

间接光照 -- Lightmap

直接阴影 -- Lightmap -- 静态阴影 -- 区域阴影

间接阴影 -- Lightmap -- 静态阴影 -- 区域阴影 ?

【Tips】 光源为区域光源 -- 通过光源大小调节阴影柔和度 【Tips】 还可通过光照贴图分辨率调节阴影柔和度

静态光源对动态物体

直接光照 -- 无

间接光照 -- 体积光照贴图 或 间接光照缓存

直接阴影 -- 无

间接阴影 -- 无

静态光源对固定物体

直接光照 -- 无

间接光照 -- 体积光照贴图 或 间接光照缓存

直接阴影 -- 无

间接阴影 -- 无

固定光源

对静态物体

平行光

前面我们提到过, 固定光源的直接光照是直接使用延迟着色渲染的, 并非通过光照贴图预处理出来的, 所以我们可以在运行的时候改变除了位置以外的其他光源信息, 如颜色, 强度等

下图是在运行时改变光源的颜色的效果

如果我们之前在 PPV 里设置的红色间接光打开, 让场景只显示间接光, 会发现只有静态物体上有一些间接光

所以上面的 gif 图片中, 所有变化的颜色都是 直接光照 引起的

下面总结一下

固定光源对静态物体的光照

其直接光照使用延迟着色直接渲染, 所以可在运行时改变除了__位置__以外的其他属性 (颜色, 亮度等)

其间接光照保存在光照贴图中, 使用 lightmass 进行烘焙 -- 预处理

下面我们再来看一下阴影

固定光源为静态物体生成__距离场阴影贴图__, 用来生成直接阴影 -- 这是一种动态阴影

距离场阴影贴图在分辨率非常低的情况下, 也可以提供比较精确的阴影变换

额。。情况不对-_-

此时的

原来ue一开始默认是不打开网格体距离场的, 要想使用距离场阴影贴图,必须先生成 网格体距离场

这是一个项目设置选项, 在 项目设置->引擎->Rendering->Lighting 下的 Geterate Mesh Distance Fields

设置完成后, 还需要设置光源的 Distance Field Shadows (距离场阴影) 选项, 以打开距离场阴影

然后场景中的静态物体的阴影就比较精准了

每一个光源都会分配到阴影贴图的一个通道, 所以最多只能有4个固定光源重叠

我们可以通过 固定光源重叠 (StationaryLightOverlap) 视图来查看当前的重叠测试

导致多于4个光源重叠的光源会显示出红色, 而此固定光源则会使用全景动态阴影,造成很大的性能消耗

而其间接阴影和间接光照一起存储在光照贴图中

总结一下

固定光源对静态物体的阴影

直接阴影使用__距离场阴影贴图__ -- 最多4个重叠光源 -- 动态阴影

间接阴影存储在光照贴图中 -- 静态阴影

【Tips_Begin】 固定光源也可以像静态光源那样使用 区域阴影, 只要在细节面板里设置 Use Area Shadows for Stationary Light 选项即可

【Tips_End】

点光源 & 聚光源

固定 点光源 和 聚光源 对于静态物体的光照表现与平行光源基本相同

但是对于阴影, 官方文档上表示也支持距离场光照贴图, 但是我个人实验好像并非如此

天光

固定的天空光好像设置不了 距离场环境遮蔽 (Distance Field Ambient Occlusion) (只有动态的天空光才可以)

不过我们仍能查看可视化的DFAO视图

除此之外, 固定的天空光会生成 弯曲法线天空遮蔽 (Bent Normal Sky Occlusion) 光照贴图

将以弯曲法线的方式生成直接遮挡

对动态物体

平行光

对于可移动物体, 固定光源的直接光照同样是使用延迟着色直接投射

但是对于可移动物体的间接光照, 就并非使用 lightmass 烘焙光照贴图得到的了

ue 提供了两种方法 -- 间接光照缓存 (indirect lighting cache)体积光照贴图 (volumetric lightmap)

【Tips_Begin】 在4.18之后的ue版本中, 体积光照贴图已经取代间接光照缓存作为默认的可移动物体间接光照方案了 可在 WorldSetting->Lightmass 选项里的 Volume Lighting Method 设置要使用的体积光照方法

但是从官方的态度来说, 体积光照贴图早晚是要取代间接光照缓存技术的

【Tips_End】

这两种方法的工作原理都是一样的, 即在场景空间里预先放置一些点 (采样点), 然后预计算出所有点的光照

然后就可以根据这些预计算出的数据进行插值什么的, 就可以计算出动态物体在运行时的间接光照了

而间接光照缓存与体积光照贴图的本质区别就是采样点的放置方式 (数量位置等)

间接光照缓存

我们必须在场景中放置一个 LightmassImportanceVolume (lightmass重要体积)

然后在这个体积内ue就会自动放置采样点, 它会在静态表面的上方均匀地放置采样点

体积光照贴图

点光源 & 聚光源

天光

对固定物体

固定光源对于固定物体, 这里有些不明白, 按理说其间接光照并没有使用 间接光照缓存, 但是

动态光源

阴影总结

性能

及其他

环境立方体贴图 Ambient Cubemap

环境遮挡 AO

法线贴图

光源概述文件 IES

光照函数

光照通道

-- ## 光束

半透明静态的光照和阴影

关于烘焙 Cook

【Tips】在 ue4 中构建光照的快捷键 Ctrl + Shift + ;

参考

Unreal Engine 4 的 光和影

ue4官方文档 照亮光照

UWA 虚幻引擎学习之路 光照系统