烘焙预计算
- 前文:
- 续_直接和间接光照这一篇小结:
- Unity烘焙预计算
- 烘焙前的场景设置
- Progressive (CPU和GPU) Lightmapper
- 2.1.1.Lighting面板Scene的设置
- 2.2.Lightmapping Settings
- 2.3.1.Lightmapping Settings Lightmapper
- 2.3.2.Progressive (CPU和GPU) Lightmapper采用的是路径追踪算法:
- 2.3.3.Enlighten采用的是辐射度(Radiance)算法
- 2.4.Lightmapping Settings
- 2.4.1.重要性采样(Importance sampling)
- 2.5.1.Direct Samples
- 2.6.1.Indirect Samples
- 2.7.1.Environment Samples
- 2.8.1.Light Probe Sample Multiplier
- 2.8.1.LightProbeGroup
- 2.9.1.Bounces
- 2.10.1.Filtering
- Enlighten Lightmapper和Progressive (CPU和GPU) 共有的参数设置
前文:
想深入了解烘焙,但发现网上关于Unity引擎烘焙的资料较少。因此,我整理了一份以Unity Light面板设置为基础的文档。尽管有些地方可能跳跃,但本文旨在逐项梳理设置和选项,背后涉及了丰富的原理。为避免冗长,我选择着重介绍个别内容,而将相同渲染逻辑整合并一并说明。
注:网上有很多已经写的非常棒的文章,大部分我会放上链接分享。
续_直接和间接光照这一篇小结:
续这一篇:【全局光照GI系统剖析_直接和间接光照_案例分享(附带场景下载链接)_场景】
Unity烘焙预计算
- 间接光照计算起来特别复杂,想要实时搞定它几乎是不可能的任务。所以,我们得提前算好这些光照数据,常用的方法有LightMap、Light Probe和Reflection Probe,也就是IBL。这些技术其实就是提前搞定那些实时算不来的光照信息。
- 我们说的“烘焙”(预计算),主要是为了处理那些间接光造成的漫反射效果,比如处理一些特殊的自发光物体或者特定光源的漫反射数据。
- 在Unity里做烘焙,其实就是在编辑器里计算全局光照。这包括了间接光照、反射和阴影等等,都是全局光照的一部分。
- 烘焙过程就像是在后台启动了一个专门的渲染程序,它会离线计算全局光照。这意味着它需要重建整个游戏场景和所有的光源数据。
简单来说,就是需要提前做好光照的计算工作,这样在游戏运行的时候,画面看起来就会更加真实,而且不会因为实时计算光照而卡顿。
烘培相关文章链接:
【《Real-Time Rendering 3rd》 提炼总结】(八) 第九章 · 全局光照:光线追踪、路径追踪与GI技术进化编年史
烘焙前的场景设置
- 点击Lighting Scene 面板下的Generate Lighting 前的场景设置。
- 在场景中区分静态物体和动态物体,一般静态物体必须参与GI的LightMap、Light Probe和Refletion Probe(IBL) 计算。
1.2.Contribute GI
- 只有在场景中勾选面板上的Static栏里的Contribute GI和面板上的Contribute GI的物体才会参与到烘焙或预计算的过程中去。
- 勾选后成为静态物体,在运行中这类物体是不能移动的。
如下图:物体的Static和面板上的Contribute GI
- 下图中红框标记就是场景中,物体的Static设置和勾选面板上的Contribute GI
Lightmap的UV
- 模型需要提供一套不重叠的UV,是用来保存光照纹理专用的UV(LightMapUV)
模型自带Lightmap的UV
- 静态物体可以设置成接受LightMap,但需要提供LightMap专用的UV,UV不可重叠。如下图物体的第二层UV平铺的样式。
- 通常烘培 Lightmap 需要用到 UV2 通道作为采样 Lightmap 的坐标,如果没有 UV2,且没有勾选Generate Lightmap UVs,则将使用 UV1。
Unity 自动展Lightmap的UV
- 选择需要烘焙的模型,勾选在Model栏下面的 Generate Lightmap UVs,这可使得 Unity 生成 Lightmap 所需的 UV2。
- Unity自动展UV有一些参数可以根据需求设置。
- 静态物体也可以设置成接受Light Probe的Contribute GI。
如下图中的对应选择项:
1.3.Meta Pass
- 后台GI程序会调用此Pass来给场景物体着色,因为计算间接光照弹射,要考虑物体的固有色信息(Albedo)。
- 如果物体是自发光材质, 要额外标记和开启Emissive选项。
- 在没有MetaPass的情况,Albedo默认为中灰色,无自发光。可以没有Meta Pass,只是最后烘焙信息可能会不准确。
Meta Pass代码如下:
Shader "Meta Pass"
{
SubShader
{
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags
{
"LightMode" = "Meta"
}
// -------------------------------------
// Render State Commands
Cull Off
HLSLPROGRAM
#pragma target 2.0
// -------------------------------------
// Shader Stages
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaLit
// -------------------------------------
// Material Keywords
#pragma shader_feature_local_fragment _SPECULAR_SETUP
#pragma shader_feature_local_fragment _EMISSION
#pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP
#pragma shader_feature_local_fragment _ALPHATEST_ON
#pragma shader_feature_local_fragment _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
#pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED
#pragma shader_feature_local_fragment _SPECGLOSSMAP
#pragma shader_feature EDITOR_VISUALIZATION
// -------------------------------------
// Includes
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
ENDHLSL
}
}
}
1.4.Light Mode模式
- Baked(开启烘焙系统后可选)
- Mixed(开启烘焙系统后可选)
- Realtime模式下的光源不会参与Unity烘焙系统。
Progressive (CPU和GPU) Lightmapper
2.1.1.Lighting面板Scene的设置
- 在Window菜单下Rendering栏里的Lighting面板
2.2.Lightmapping Settings
- 如下图
2.3.1.Lightmapping Settings Lightmapper
- Progressive (CPU和GPU) Lightmapper采用的是路径追踪算法
Unity手册渐进 CPU 光照贴图 (Progressive (CPU和GPU) Lightmapper)
- Enlighten使用的是辐射度算法。
- 在Unity早期在Unity4.X版本使用的是AutoDesk 的 Beast 技术
- 在Unity5之后的版本使用Enlighten引擎
在Unity中的截图如下:
2.3.2.Progressive (CPU和GPU) Lightmapper采用的是路径追踪算法:
正如Unity手册渐进 CPU 光照贴图 (Progressive (CPU和GPU) Lightmapper)开头提到的。
1.路径追踪就是用计算机模拟光线在现实世界中的行为,以此来决定每个像素应该显示什么颜色。
2.从视线(或者说相机的镜头)就像是发射出去的一束光。路径追踪就是从相机开始,沿着你看的方向发射一束光线。
3.当这束光线遇到场景中的某个物体时,它会找到最接近的那个点。这个点会有很多信息,比如它在物体表面上的位置、物体表面的样子(凹凸不平还是光滑),以及物体的材质是什么样的。
4.接下来,要计算光线是怎么在这个物体表面反射的。这包括了两种情况:一种是光线像在镜子上一样反射(称之为镜面反射),另一种是光线被物体表面以各种方向散射出去(称之为漫反射)。
5.通过递归调用路径追踪算法,从刚刚找到的相交点出发,继续追踪光线的路径。这个过程会重复进行,就像是光线在不断地反弹一样。
6.但是,这个过程不会无休止地进行下去。而是会设定一个条件,比如达到一定的深度或者光线的亮度低于某个值,这时候就停止追踪。
7.蒙特卡洛采样的方法。这个方法可以模拟光线的自然分布,通过对颜色进行平均处理,减少图像中的噪点。
简单总结
路径追踪就是用计算机模拟光线如何在场景中反射和散射。
如下图:
2.3.3.Enlighten采用的是辐射度(Radiance)算法
- 辐射度相关物理量定义示意图
其中
- 辐射能量(Radiant energy) Q ,表示的是空间中所有光子能量总和
- 辐射束(Radiant flux) Φ ,表示辐射能量通过空间中特定区域的速率
- 辐射照度(Irradiance) E ,表示的是单位面积入射的辐射束能量
- 辐射出射照度(Exitance) M ,表示的是单位面积出射的辐射束能量
- 辐射强度(Radiant intensity) I ,表示的是单位立体角(Solid angle)的辐射束能量
辐射度(Radiance):用来描述从点 x 以方向 dw 出射的光线强度。辐射度 L 的定义为:
L
(
x
,
w
⃗
)
=
d
2
Φ
c
o
s
θ
d
A
d
w
⃗
\large L(x,\vec{w}) = \cfrac{d^2 \varPhi } {cos \theta d A d\vec{w}}
L(x,w)=cosθdAdwd2Φ
如果一个辐射区域 A 各处的辐射度 L 均已知,那么我们就可以积分求出通过该区域的辐射束 Φ :
Φ
=
∫
A
∫
Ω
L
(
x
,
w
⃗
)
(
w
⃗
,
n
⃗
)
d
w
⃗
d
x
\large {\varPhi} = \int_A \int_\Omega L(x,\vec{w}) (\vec{w},\vec{n}) d\vec{w}dx
Φ=∫A∫ΩL(x,w)(w,n)dwdx
2.3.4.辐射度(Radiance):
辐射度(Radiance) 将场景分割为多个面片( Cluster/Patch ),以面片为基本单位进行计算。最终的目标是预计算每个面片的 辐射度(Radiance)
A面片的辐射度 等于 A面片的自身光照发射率 加上 其他面片(B+C+D…)对A面片的入射光反射率的 总和 。
B对A面片的入射光反射率计算为B面片的辐射度乘以AB面片的 形状系数(form factors) 。
形状系数可以理解为两个面片之间的可见度,其取决于面片之间的距离和相对朝向。
为了 求出场景所有面片两两之间的可见度 ,这个计算量巨大,因为计算复杂度为次方指数增加的。现有技术是在每个面片的预计算可见度可以存储为贴图,从而在预计算阶段结束时提高效率。
在运行时,首先计算场景中所有光源的直接光,为场景中的面片提供初始照明。然后,根据每个面片的预计算辐射度,计算间接光照,生成Dynamic LightMap和Light Probe,实现动态全局光照。
这些操作也可以选择在离线阶段进行计算,并保存为静态的LightMap和Light Probe。
- 辐射度(Radiance):
- 定义: 辐射度是单位立体角、单位表面积、单位光谱范围内的光通量,即指定方向上的辐射通量密度。通常用符号 L 表示。
- 单位: 辐射度的单位是瓦特每平方米每立体弧度(W/(m²·sr))。
- 方向: 辐射度关注的是特定方向上的光线通量,描述了光线的方向性。
2.3.4.辐照度(Irradiance):
- 辐照度(Irradiance):
- 定义: 辐照度是单位表面积上接收到的光能量,即单位面积上的光通量。通常用符号 (E) 表示。
- 单位: 辐照度的单位是瓦特每平方米(W/m²)。
- 方向: 辐照度关注的是光线从所有方向上撞击表面后的总能量。
- 辐照度公式:
E ( x ) = π ∫ Ω L ( x , w ) c o s θ d w ⃗ \large E(x) = π\int_Ω\ L(x,w) cos \theta d \vec{w} E(x)=π∫Ω L(x,w)cosθdw
-
其中
(E) 是辐照度
L(w) 是辐射度
Ω (Omega) 是半球体的立体角
cosθ (theta) 是光线与法线之间的夹角
dw 代表立体角元素对立体角的微小增量。
这个公式表示辐射度在所有方向上的积分,得到了表面上的辐照度。 -
总的来说它们的不同在于它们关注的方向不同。辐照度描述了在单位表面积上接收到的光能量。辐射度描述了特定方向上的光线通量密度。
-
用一个很经典的图,示意辐照度(Irradiance,左边)和辐射度(Radiance,右边)的关系:
- Ω 是半球体的立体角,n表示的是法线向量,θ 是光线与法线之间的夹角(辐射度才有夹角一说)。
2.3.5.相关科普文章:
辐射度相关科普文章:渲染方程Rendering equation
基于物理着色:BRDF
2.4.Lightmapping Settings
- 如下图
2.4.1.重要性采样(Importance sampling)
- 启用此选项以在采样环境时使用多重重要性采样。通常,在生成光照贴图时,这会导致更快的融合,但在某些低频条件下可能导致结果更加嘈杂。
- 默认情况下是关闭的,一般保持勾选既可。
注意 :
- 重要性采样 采用的技术是 蒙特卡洛积分,也就是通过算法计算出一定的权重或分散特征的策略采样
- 在有限的数据基础上来增加准确度,一般保持勾选既可。
2.4.2.重要性采样蒙特卡洛积分相关科普文章链接:
2.5.1.Direct Samples
- 每个LightMap Texel的计算直接光照时发射的Samples数量。
- 增加该值可以提高光照贴图的质量,但会增加烘焙时间。
- 考虑到自发光和区域光,一般32已经很足够了。
2.6.1.Indirect Samples
- 每个LightMap Texel的计算间接光照时每次弹射时发射的Samples数量。
- 此数值比较影响烘焙时间。
- 一般在户外场景为100足够,某些室内场景对间接光要求较高的,可以提升到256以上。
2.7.1.Environment Samples
- 定义光照贴图器用于环境光照计算的样本数量。较高的值可以提高光照贴图的质量,但会增加完成烘焙所需的时间。
- 默认设置为 500。
2.8.1.Light Probe Sample Multiplier
- 控制用于光照探头的样本数量,作为上述Direct Samples、Indirect Samples、Environment Samples样本值的乘数。
- 较高的值可提高光照探头的质量,但烘焙时间会更长。
- 要启用此功能,请转到项目设置 > 编辑器,并禁用使用传统的光照探头样本计数。默认值为 4。”
2.8.1.LightProbeGroup
2.9.1.Bounces
- 间接反弹次数,很影响烘焙时间,对于大多数场景,两次反弹就足够了。对于某些室内场景,可以适当提高
Min Bounces
- 在间接光照计算中的最小反弹次数。建议值:2
- 为了提高烘焙过程中的性能,Lightmapper 使用一种称为俄罗斯轮盘赌的技术来终止对场景外观影响不大的光路。
Max Bounces
- 在间接光照计算中的最大反弹次数。建议值:2-10
2.10.1.Filtering
- Gaussian:对LightMap使用高斯滤波进行模糊。这会模糊光照贴图并减少可见噪声。
- A-Trous:对LightMap使用 A-Trous滤波。A-Trous 过滤器在消除光照贴图中的可见噪点的同时最大限度地减少了模糊量。
Enlighten Lightmapper和Progressive (CPU和GPU) 共有的参数设置
LightMap 分辨率的查看
LightMap Resolution 分辨率的查看,在场景绘制模式栏的 Baked Lightmap选项中查看。
2.12.1.LightMap Resolution(Enlighten)
- Dynamic LightMap的分辨率、每单位(米)面积内有多少个Light Map Texel。
- 也是决定了计算辐射度过程中Cluster的数量。该数值极大影响烘焙时间
2.12.1.LightMap Resolution
- 全局的Baked Light Map分辨率控制,决定了每单位(米)面积内有多少个Light Map Texel。在Progressive Lightmapper渲染器中,是以Texel为单位发射Sample的。
- 也可以单独针对每个物体调整Light Map分辨率
- 要按需分配Texel,不多不少刚刚好
2.13.1.LightMap Padding
- 每个物体Light Map UV 间隔像素
2.14.1.Max LightMap Size
- 单张LightMap的最大尺寸,此数值要设置合理。
- 设置小了,可能导致LightMap数量过多,会影响合批。设置过大也有带宽问题。一般保持在1024-2048
2.15.1.LightMap Compression
- LightMap贴图的压缩格式(Compression)设置。
- LightMap保存的是HDR数据,要注意采用不同的格式对LightMap编码的影响。
编码格式(Encoding)中,RGBM在各平台上是最通用的,效果上可能会又一定的损失,效果最好的还是HDR编码格式。
Unity官方手册Lightmaps: Technical information
2.16.1.Ambient Occlusion
- 开启此选项,会在烘焙的过程先烘焙一张AO贴图,最后与LightMap合成在一起
- Max Distance:AO的检测射线的最大行进距离,理论上数值越大,产生的AO会更真实,范围更大。数值为0是表示无穷远
- Indiretc Contribution:间接光对AO的贡献
- Direct Contribution:直接光照对AO的贡献,默认为0
2.17.1.Directional Mode
- 开启后,会额外烘焙一张Direction Map,记录着每个Texel的入射光方向,单个Texel最多储存一个灯光的方向信息,所以哪个灯光对该Texel影响最大就存哪个
- 在Shader中还原入射光信息,结合法线贴图, 计算一个简单的Half Lambert可以让LightMap体现法线贴图的效果
L = directionMap.rgb * 2 - 1;
halfLambert = dot(N, L) * 0.5 + 0.5;
bakeGI = lightmap * halfLambert / max(1e-4, direction.w);
2.18.1.Albedo Boost
- 整体控制后台GI程序中场景物体的Albedo亮度
2.19.1.Indirect Intensity
- 整体控制生成的LightMap和LightProbe的亮度
2.20.1.LightMap Parameters
- 上面所有参数都是全局的控制参数,而LightMap Parameters提供了一组更细节的GI参数调整,可以创建不同的LightMap Parameters资源,针对不同的物体、不同的场景做出调整