间接光没有办法实现实时计算,所以需要一套GI系统去处理间接光。
unity的GI系统,本质上就是在后台开启一个离线渲染程序执行GI计算。最早的unity的离线渲染器也是调用的第三方的,所以,如果实力允许,我们也可以独立实现相应的功能。
unity的离线渲染器更新:Beast->Enlighten->Enlighten + Progressive Lightmapper
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags { "LightMode" = "Meta" }
Cull Off
HLSLPROGRAM
#pragma exclude_renderers gles gles3 glcore
#pragma target 4.5
#pragma vertex UniversalVertexMeta
#pragma fragment UniversalFragmentMetaLit
#pragma shader_feature EDITOR_VISUALIZATION
#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
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
#include "Packages/com.unity.render-pipelines.universal/Shaders/LitMetaPass.hlsl"
ENDHLSL
}
如果没有相关pass,也可以实现渲染,但是Albedo默认中灰色,无自发光Emission。
3. 需要有光源设置为Baked(已烘焙) 或者 Mixed(混合模式),需要设置开启了烘焙系统后才可以选择。
接下来,可以在光照的配置项下面设置相关配置,在参与烘焙的物体上面设置,也会影响最终烘焙结果。
Enlighten是基于辐射度实现的一种光线追踪。
原理:
在场景里面,我们也可以直接看到烘焙好的Light Map,如果你转动主光源,会发现LightMap也会实时更新。
在场景里,动态GI只对实时光产生作用,你需要将光的属性设置为Realtime,自发光的属性也要设置为Realtime。
图上为unity内置的lit携带的设置(2021版本)
我们也可以在Contributors/Receivers里面查看哪些贡献烘焙光照,以及从哪里获取环境漫反射。
上图显示什么颜色使用和接收的方式。
在场景里面,可以选择Clustering来查看分块情况。
我们看到只开启实时烘焙光照以后,下面的设置项能够影响它的就那几项,Indirect Resolution 就是设置每个单位有几块Clustering的。还有Lightmap Parameters 也会影响它,现在使用的是默认的选项。
它们会相乘得到最终在场景中使用的值,比如默认的是0.5 我们设置也是0.5,那么一个单位平面中的Clustering的面是0.25.
如果动态GI和静态GI都开启的情况下,我们可以选择天光使用哪种方式去烘焙。默认就是动态GI去烘焙,也就是实时烘焙。
我们也可以开启静态烘焙,使用Enlighten进行静态烘焙
上面的两种是其它的烘焙方式,其实是采用的路径追踪的方式去实现的。开启后是以下的样子,下面就是Enlighten烘焙GI的控制项。
Enlighten的静态烘焙GI相对于动态GI,还会额外的制作一些流程。
这是后来又增加一套新的烘焙系统,主要解决Enlighten烘焙速度慢的问题。
光照贴图烘焙器的前两个都是用的这套新系统,GPU是使用显卡运算的,速度快,精度不高(因为显卡不适合做逻辑运算),默认使用的是CPU,速度慢一些,但是计算的结果比较精确,所以我们使用的结果都是先使用GPU计算。
在路径追踪算法中,我们要计算某个点的GI,就要收集它上半球上所有可能方向的所有光线,那就需要发射无数根光线去拾取,所以我们需要进行积分,但是很难实现。
当一个积分很难通过解析的方式得到答案时候,可以通过蒙特卡洛的方式近似得到积分的结果。
蒙特卡洛积分方法近似的效果好坏主要取决于采样的样本数量。Samples(平面上的采样点,也可以代表采样用的一根射线)次数越多,获取的结果也就越接近实际结果,相应的也会增加计算时间。
重要性采样,在有限的Samples数量基础上增加准确度。
路径追踪算法在确定好Samples数量以及Bounces(弹射)次数。
根据设定的LightMap Texel(光照贴图像素)的数量,对每个像素进行Path Tracing,烘焙LightMap。
先烘焙直接光照(直接怼直接光源进行采样),烘焙间接光,最后是环境采样。
对LightMap降噪
对Light Probe进行Path Tracing,烘焙Light Probe
现在路径追踪只能用于烘焙GI
渐进更新:配合自动生成可以修改静态模型自动更新。如果不需要自动生成,则此项不需要开启。
多重重要性采样:就是上面提到的重要性采样,有的时候会造成采样的不准确。保持勾选即可。
直接样本:每个LightMap Texel的计算直接光照是发射的Samples数量,默认即可。
间接示例:每个LightMap Texel的计算间接光照时每次弹射时发射的Samples数量。此数值比较影响烘焙时间。一般在户外场景为100足够,某些室内场景对间接光要求较高的,可以提升到256以上。
环境样本:计算环境光所用的Samples总数,Samples的数量分配由LightMap Texel和Light Probe Position的分布情况决定。默认数值是500,如果用了HDR Skybox可以适当提高此数值,来达到更好的效果
光照探测器样本乘数:这个是一个倍数,Light Probe采样时,会通过
反弹次数:间接反弹次数,影响烘焙时间,对于大多数场景2即可,室内场景可以适当提高。
最小反弹次数:在间接光照计算值最小反弹次数,建议2。为了提高烘焙性能,Lightmapper会根据情况减少采样。
最大反弹次数:最大反弹次数,建议2-10之间,输出的时候可以增加高些,调试就低一些。
过滤:对LightMap进行降噪处理,默认是使用高斯模糊。高级是使用A-Trous,降噪的同时最大限度减少模糊。
间接分辨率:Enlighten用的,每个单位多少的Enlighten的面片,也会影响Dynamic LightMap的分辨率,光线追踪用不到。
光照贴图分辨率:每个单位有多少的像素
可以通过场景查看,每个格子代表一个像素。
光照贴图分辨率:每单位有多少光照贴图的像素,也可以对单个物体进行分辨率调节。Lightmapper根据像素进行光线追踪。
光照贴图填充:每个物体在光照贴图上面的像素间隔。
最大光照贴图大小:每个光照贴图的最大尺寸,数值设置推荐合理一些,小了影响合批,大了有带宽问题。一般在1k-2k
Lightmap Compression:光照贴图的压缩设置。光照贴图保存的是HDR数据,注意格式对光照贴图的影响。
无:相当于无损压缩。
低质量:使用双低动态范围 (dLDR) 编码。只需直接将 [0, 2] 范围映射到 [0, 1],即可在移动平台上使用 dLDR 编码。值高于 2 的烘焙光源强度将被钳制。编码值的计算方法是:光照贴图纹理的值乘以 2(如果使用伽马空间),或乘以 4.59482(22.2)(如果使用线性空间)。某些平台将光照贴图存储为 dLDR,这是因为在使用 RGBM 时,这些平台的硬件压缩会产生外观不佳的瑕疵。
法线质量:normal quality 默认的质量 使用RGBM编码,推荐。
高质量:使用
https://docs.unity3d.com/cn/current/Manual/Lightmaps-TechnicalInformation.html 环境光遮蔽:是否开启AO,开启AO会烘焙一张AO贴图,最后在合并到光照贴图上。
最大距离:AO射线检测的最大距离,理论上数值越大,产生的AO会更真实,也更大。有要求10就很好了。
间接贡献:间接光对AO的贡献。
直接贡献:直接光对AO的贡献,默认为0.定向模式:开启定向模式后,会额外烘焙一张定向贴图,记录每个像素的入射光方向,但是只能记录一个,最重要的那个。后续就是我们可以在渲染shader中获取到入射光朝向,让漫反射体现法向贴图的效果。
可以找到入射光的方向,实时GI和烘焙GI分别有。
登录后复制
L = directionMap.rgb * 2 - 1; //贴图转方向,获取光源朝向
halfLambert = dot(N, L) * 0.5 + 0.5;
bakeGI = lightmap * halfLambert / max(1e-4, directionMap.w); // 权重因子
强化反射率:整体控制后台GI程序中场景物体的Albedo亮度
间接密度:整体控制生成光照贴图和Light Probe的亮度
光照贴图参数:最后一项是光照贴图参数unity分了四个级别,默认中等
图上是在模型上面指定使用某种光照贴图参数。
光照贴图参数 Lightmap Parameters 是一个全局的参数,可以在场景中选择使用哪个配置去实现,这样可以实现光照参数一致的情况下,使用光照贴图参数去调整一些影响性能的配置,方便性能分级。
说一下主要的,
分辨率:整体分辨率的调整,可以影响到Lightmap分布和Clustering的大小
群集分辨率:这个也是控制Clustering分块的,光照配置中的值会乘以这个获得最终值。
推开:PushOff 这个值增加会减少阴影的范围,有阴影偏移的功效。
烘焙标记:Baked Tag 如果使用了不一样的光照贴图参数文件或者设置的烘焙标记不一样,将无法合并到一张LightMap中。
背面容差:Backface Tolerance 这个主要是无效像素的问题,比如我们立起一个面片,背面不渲染,那烘焙的时候,底部的面将获取不到背面的颜色,我们可以设置Texel Validity 去检测当前场景有哪些像素无效。
需要我们尽量避免这种情况,如果无法避免,我们可以将此值减少。这个值越大,射线拾取越严苛,相当于一个百分比的值,如果值为1,那么必须发出的射线百分比都要通过测试才能够不会设置为无效像素,如果设置0.5,如果射线检测通过数量不低于一半,那就是有效像素。这个看情况去设置,但是你不设置的话,有的区域会变黑,基本上是这个原因造成的。
我们还有一种方式,就是,在材质上设置一下:
开启双面全局照明,也能够解决这个问题。
还有一些可以直接在MeshRenderer设置影响光照烘焙的。
贡献全局光照:设置了以后,可以参与烘焙,直接烘焙出阴影。
有一些小的物体,比如树叶,草啊什么的,他们烘焙LightMap比较耗,我们可以把接收全局照明修改成Light Probes。
如果你把动态GI打开,还会出现额外的调节参数。动态GI用了一套额外的UV,能调整的地方,也就在meshRenderer身上。
灯的模式分为三种:
https://docs.unity3d.com/cn/current/Manual/lighting-mode.html 有能力的可以去看官方文档。
照明模式分为三种:
shadowMask模式需要生成一张额外的贴图,拥有四个通道,所以光照贴图上的一个像素最多可以存储四盏Mix灯的阴影,超出的灯会将阴影烘焙到光照贴图上。
如果一个像素上同时包含四盏以上的mix灯的阴影,将有回退,以上是在Light Overlap下查看,哪几盏灯被认成了Baked模式,无法贡献实时阴影。
缺点:烘焙的内存占用会增加一倍,因为需要一套额外的贴图。
直接光
直接光阴影
间接光漫反射
前面的说过了,列一下Baked Global Illumination
Baked Lightmap: 烘焙的光照贴图显示
Directionality: 光的朝向
Shadowmask: 烘焙shadowMask模式下可以查看阴影遮挡情况
Albedo:基础反射颜色
Emissive:烘焙自发光颜色
UV Charts:光照贴图UV映射检查
Texel Validity:像素无效化检测,前面讲了
UV OVerlap:检查光照贴图UV是否重叠的问题
Lightmap Indices:光照贴图的索引查看
Light Overlap:上面说了,查看mix光源被回退到baked的光源情况
#注意事项
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删