radiance和irradiance是什么这两个分量有着自己准确的物理定义但我们简单理解radiance是某个方向的光照输入irradiance是某个位置接收的光照radiance积分后得到irradianceirradiance某个方向上求导得到radiance我们最终应用的光照信息都是irradiance的游戏中的GI通常是怎么模拟的如果我们假设所有全局光照都是由天光提供的话那么通常包含直接天光 * 天光可见性 天光多次反弹结果同理我们也可以推导出比如对室内的聚光灯全局光照结果包括直接光 * 阴影 聚光灯多次反弹结果我们可以用上面的公式去计算全局光照也可以离线直接把计算结果存储下来要注意运行时光照计算一定是非常简单的天光是什么天光是天空发出的光来自大气对太阳光的散射这里有一些比较反直觉的事情天光是全局光照里的概念它虽然属于环境光照提供了环境照明但是它却是直接光我们计算天光的时候会考虑它的直接分量和间接分量一个比较典型的例子就是洞口越往内天光的贡献度就越低如果我们能拟合出这个效果就会让人感觉很真实GI为什么可以用球谐函数来存储天光和直接光相比不同的地方是它的方向非常多常规情况下需要用cubemap来存储比较费但考虑部分信息是低频的所以通常用球谐函数来存储比如irradiancevisibility此外虽然radiance本身是高频的但是由于它与传输项相乘后是低频的如果我们只关心最终的光照结果也可以用球谐来存radiance什么信息对GI来说是最重要的遮挡信息重要度远远大于颜色信息主要是让人眼感受到画面的颜色不是纯“平”的全局光的颜色信息简化版本可以完全用IBL来提供如果想做的比较细腻会去考虑多摆放一些采样点接下来就是怎么混合这些结果的问题了为什么我们通常需要提供单独的AO信息传统的path tracing中我们不会去考虑AO只会去计算光线的前进路径AO是为了我们方便计算近似的一个概念每个方向的可见性本身是积分内部的一个系数我们把它作为一个单独的积分提取出来probe因为是空间中摆放的受限于显存占用通常是低频的但是由于我们需要一些比较高频的遮挡信息所以会把AO存到贴图里或者用屏幕空间AO算法作为补充可以把AO直接乘到全局光照计算结果上提供近似的效果怎么去理解光照的不同分量直接天光 * 天光可见性 天光多次反弹结果在这个公式中我们认为天光含可见性是长距离传输光照天光反弹结果是短距离传输光照对于一些实时的全局光照算法后者可以用屏幕空间结合世界空间方法来拟合难点在于可能需要不止一次迭代因为我们不可能一次就能命中光源方向前者的难点在于长距离的传播比较耗时需要依赖于一些加速光线追踪的数据结构我们一般怎么存储GI有两种形式一种是存储最终的irradiance包括直接烘光图或者irradiance volume运行时采一次就可以了前者精度比较高但显存占用高并且大小和场景物件复杂度相关后者精度会比前者低一些但可以作用于动态物件并且可以集成到延迟光照的时候计算还有一种是存储一些中间量比如radiance, visibility, scenedata这些信息在运行时应用一些简单的计算这样可以实现一部分动态的效果比如支持动态光照等我们为什么需要体素、SDF这种东西本质上都是为了对场景进行建模对场景建模是为了能加速光线追踪所以也可以理解为一种遮挡信息比如SDF记录的是最近深度体素通常会结合八叉树那么就可以先以比较大的跨度去做锥形追踪加快查询速度虽然说我们选择对场景做建模相当于拟合了一部分遮挡信息但是最终是否需要SSAO/SSGI算法还是取决于数据的精度和频率这个可以类比到shadow即使有了阴影我们也还是需要contact shadow来补充一些近处可能因为bias导致的漏光或者应对几何复杂度太高常规阴影算法吃不消的case室内与室外要做什么特殊处理室内外最大的差异在于光源来源不一样室外主要由天光、平行光提供距离比较远室内主要由LocalLight提供距离比较近如果针对不同的光照特点选择了不同算法就要做很多区分处理室内也分为两种一种是封闭室内一种是半开放室内前者比较好做隔离后者会同时接收两种类型的光源还有一个问题是室内外墙壁可能产生的漏光这个和probe、体素等精度相关没有什么比较好的通解更多的都是工程上和内容生产制作团队的磨合我们实际上在解决什么问题GI虽然看起来很高级但大部分人都在解决工程上的问题光图的UV和模型缠绕在一起的各种bug各种probe摆放导致的漏光问题各种场景中异常发黑/发亮的问题怎么去做近景、中景、远景的不同处理如果选择全烘焙方案怎么做流送和压缩来减少包体和显存压力如果选择做动态计算怎么做分帧降分辨率和重要度采样等来减少运行时计算压力我对Locallight的看法目前有两种比较常见的做法一个是基于stencil的一个是基于cluster屏幕切分的本质上都是为了省像素计算但是灯光复杂度一上去性能表现其实都不好而且遇到了打光范围比较大的情况基本都束手无策还有一个问题是一般这类实时光照算法只会去计算直接光间接光是不考虑的这样就会导致对比度很高就变成了一个非常吃性能效果还不好的东西所以在我看来如果没能力做好效果反而不如选择烘焙的方案如果考虑到希望对动态角色影响再去考虑probe的形式阴影有哪些划分方式虽然市面上有很多阴影算法但本质上都是Fit to Scene或者Fit to View的在这些基础上会产生很多变体但基本都是为了针对性的解决不同问题出现的Fit to Scene的做法效果上会比较稳定但是划分上可能导致精度偏低比如如果是想解决转镜头更新问题那么可以在相机周围去生成或者多做几级这样阴影精度低、单次更新量大但更新频率低如果是想解决单次更新量大有些人可能会去考虑切成tile来更新但是考虑到阴影剔除的计算方式这样反而会增加总绘制数量在应用中要做仔细考量Fit to View是利用率最高的做法精度也是最好的但是要注意为了避免更新时的阴影轮廓抖动需要保证相机的View是固定的这可能需要我们去用一个球体做包围盒这样得到的利用率就不是最优的了也有一些夹在中间的方案比如上述Fit to View的方案利用率不是最优的但也意味着它多画了不少东西这导致镜头移动的时候物件可能还在阴影图上或者可以不去考虑镜头旋转更新问题但取比视锥体更大一些的包围盒计算比如取角色前方的半矩形来更好地降低更新的频率。怎么做降配有一个不得不去考虑的问题就是怎么做降配我们不可能给每个分量去提供最准确的计算比如有些东西不可能实时计算有些东西只能给近处的提供高精度的计算我认为有一个非常重要的一点也反复提及的一点是不应该通过暴力地砍掉某个分量来做优化而是要充分考虑到这个分量本身对画面的影响包括移除后带来的负面影响以及是否有更简单的方法去拟合这个分量技术方案选型以下是夹带私货时间选择技术方案的时候我觉得有一点很容易被忽略的那就是这个方案效果是否稳定有些东西乍一看在工程上很巧妙但是使用上有很多瑕疵我举个例子就是贴花阴影效果上很容易穿帮这个会带来很多bug其实就是测试/美术团队的人力成本在开发初期一定要和内容生产线对清楚能不能接受这些问题如果不太能接受是不是能作为低配的一个可选方案还有一个就是延迟光照发展起来后需要去选择自己的抗锯齿算法再加上期望去实时计算一些高级的效果但是硬件又吃不消大家就开始盯上了TAA来做拼好帧越来越多算法依赖TAA来做优化后技术团队就不得不选择TAA作为抗锯齿算法再加上DLSS等算法的出现游戏画面特性可以堆得越来越多但是观感上反而变得越来越糊了我觉得在商业引擎当前的发展下很多算法并不构成技术壁垒反而是选择用什么才是最重要的评估方案的时候还有一个很重要的一点是可伸缩性这个本质上就是降低维护成本如果一个方案具备很好的可伸缩性也就是调一下参数就能提升品质/或者做降级那么也是一个会被优先考虑的做法但是要注意不能想当然地认为一个方案具备可伸缩性比如某些方案可能砍到一定精度后效果已经完全失真这个时候只能说明对于想要达到的目标选型可能是错误的也还有很多技术方案属于捆绑销售的比如在场景中生成了SDF或者生成了HZB那么其它的算法是不是都可以去用这个数据一旦有些东西做了完整的基建那么就会去渗透并且影响到其它的技术选型以及一些商业引擎主推的方案也会成为大家的首选除了能更快看到结果外还有一方面的原因是降低了解释成本比如如果你说我自研了一套全局光照方案老板很可能会对这个东西产生不信任这种不信任是人之常情但如果你说我用了ue5的Lumen技术这种疑虑就会被打消如果越来越多的项目选择使用这个技术那么对于官方而言也是一种利好
全局光照/阴影的几个常见问题
radiance和irradiance是什么这两个分量有着自己准确的物理定义但我们简单理解radiance是某个方向的光照输入irradiance是某个位置接收的光照radiance积分后得到irradianceirradiance某个方向上求导得到radiance我们最终应用的光照信息都是irradiance的游戏中的GI通常是怎么模拟的如果我们假设所有全局光照都是由天光提供的话那么通常包含直接天光 * 天光可见性 天光多次反弹结果同理我们也可以推导出比如对室内的聚光灯全局光照结果包括直接光 * 阴影 聚光灯多次反弹结果我们可以用上面的公式去计算全局光照也可以离线直接把计算结果存储下来要注意运行时光照计算一定是非常简单的天光是什么天光是天空发出的光来自大气对太阳光的散射这里有一些比较反直觉的事情天光是全局光照里的概念它虽然属于环境光照提供了环境照明但是它却是直接光我们计算天光的时候会考虑它的直接分量和间接分量一个比较典型的例子就是洞口越往内天光的贡献度就越低如果我们能拟合出这个效果就会让人感觉很真实GI为什么可以用球谐函数来存储天光和直接光相比不同的地方是它的方向非常多常规情况下需要用cubemap来存储比较费但考虑部分信息是低频的所以通常用球谐函数来存储比如irradiancevisibility此外虽然radiance本身是高频的但是由于它与传输项相乘后是低频的如果我们只关心最终的光照结果也可以用球谐来存radiance什么信息对GI来说是最重要的遮挡信息重要度远远大于颜色信息主要是让人眼感受到画面的颜色不是纯“平”的全局光的颜色信息简化版本可以完全用IBL来提供如果想做的比较细腻会去考虑多摆放一些采样点接下来就是怎么混合这些结果的问题了为什么我们通常需要提供单独的AO信息传统的path tracing中我们不会去考虑AO只会去计算光线的前进路径AO是为了我们方便计算近似的一个概念每个方向的可见性本身是积分内部的一个系数我们把它作为一个单独的积分提取出来probe因为是空间中摆放的受限于显存占用通常是低频的但是由于我们需要一些比较高频的遮挡信息所以会把AO存到贴图里或者用屏幕空间AO算法作为补充可以把AO直接乘到全局光照计算结果上提供近似的效果怎么去理解光照的不同分量直接天光 * 天光可见性 天光多次反弹结果在这个公式中我们认为天光含可见性是长距离传输光照天光反弹结果是短距离传输光照对于一些实时的全局光照算法后者可以用屏幕空间结合世界空间方法来拟合难点在于可能需要不止一次迭代因为我们不可能一次就能命中光源方向前者的难点在于长距离的传播比较耗时需要依赖于一些加速光线追踪的数据结构我们一般怎么存储GI有两种形式一种是存储最终的irradiance包括直接烘光图或者irradiance volume运行时采一次就可以了前者精度比较高但显存占用高并且大小和场景物件复杂度相关后者精度会比前者低一些但可以作用于动态物件并且可以集成到延迟光照的时候计算还有一种是存储一些中间量比如radiance, visibility, scenedata这些信息在运行时应用一些简单的计算这样可以实现一部分动态的效果比如支持动态光照等我们为什么需要体素、SDF这种东西本质上都是为了对场景进行建模对场景建模是为了能加速光线追踪所以也可以理解为一种遮挡信息比如SDF记录的是最近深度体素通常会结合八叉树那么就可以先以比较大的跨度去做锥形追踪加快查询速度虽然说我们选择对场景做建模相当于拟合了一部分遮挡信息但是最终是否需要SSAO/SSGI算法还是取决于数据的精度和频率这个可以类比到shadow即使有了阴影我们也还是需要contact shadow来补充一些近处可能因为bias导致的漏光或者应对几何复杂度太高常规阴影算法吃不消的case室内与室外要做什么特殊处理室内外最大的差异在于光源来源不一样室外主要由天光、平行光提供距离比较远室内主要由LocalLight提供距离比较近如果针对不同的光照特点选择了不同算法就要做很多区分处理室内也分为两种一种是封闭室内一种是半开放室内前者比较好做隔离后者会同时接收两种类型的光源还有一个问题是室内外墙壁可能产生的漏光这个和probe、体素等精度相关没有什么比较好的通解更多的都是工程上和内容生产制作团队的磨合我们实际上在解决什么问题GI虽然看起来很高级但大部分人都在解决工程上的问题光图的UV和模型缠绕在一起的各种bug各种probe摆放导致的漏光问题各种场景中异常发黑/发亮的问题怎么去做近景、中景、远景的不同处理如果选择全烘焙方案怎么做流送和压缩来减少包体和显存压力如果选择做动态计算怎么做分帧降分辨率和重要度采样等来减少运行时计算压力我对Locallight的看法目前有两种比较常见的做法一个是基于stencil的一个是基于cluster屏幕切分的本质上都是为了省像素计算但是灯光复杂度一上去性能表现其实都不好而且遇到了打光范围比较大的情况基本都束手无策还有一个问题是一般这类实时光照算法只会去计算直接光间接光是不考虑的这样就会导致对比度很高就变成了一个非常吃性能效果还不好的东西所以在我看来如果没能力做好效果反而不如选择烘焙的方案如果考虑到希望对动态角色影响再去考虑probe的形式阴影有哪些划分方式虽然市面上有很多阴影算法但本质上都是Fit to Scene或者Fit to View的在这些基础上会产生很多变体但基本都是为了针对性的解决不同问题出现的Fit to Scene的做法效果上会比较稳定但是划分上可能导致精度偏低比如如果是想解决转镜头更新问题那么可以在相机周围去生成或者多做几级这样阴影精度低、单次更新量大但更新频率低如果是想解决单次更新量大有些人可能会去考虑切成tile来更新但是考虑到阴影剔除的计算方式这样反而会增加总绘制数量在应用中要做仔细考量Fit to View是利用率最高的做法精度也是最好的但是要注意为了避免更新时的阴影轮廓抖动需要保证相机的View是固定的这可能需要我们去用一个球体做包围盒这样得到的利用率就不是最优的了也有一些夹在中间的方案比如上述Fit to View的方案利用率不是最优的但也意味着它多画了不少东西这导致镜头移动的时候物件可能还在阴影图上或者可以不去考虑镜头旋转更新问题但取比视锥体更大一些的包围盒计算比如取角色前方的半矩形来更好地降低更新的频率。怎么做降配有一个不得不去考虑的问题就是怎么做降配我们不可能给每个分量去提供最准确的计算比如有些东西不可能实时计算有些东西只能给近处的提供高精度的计算我认为有一个非常重要的一点也反复提及的一点是不应该通过暴力地砍掉某个分量来做优化而是要充分考虑到这个分量本身对画面的影响包括移除后带来的负面影响以及是否有更简单的方法去拟合这个分量技术方案选型以下是夹带私货时间选择技术方案的时候我觉得有一点很容易被忽略的那就是这个方案效果是否稳定有些东西乍一看在工程上很巧妙但是使用上有很多瑕疵我举个例子就是贴花阴影效果上很容易穿帮这个会带来很多bug其实就是测试/美术团队的人力成本在开发初期一定要和内容生产线对清楚能不能接受这些问题如果不太能接受是不是能作为低配的一个可选方案还有一个就是延迟光照发展起来后需要去选择自己的抗锯齿算法再加上期望去实时计算一些高级的效果但是硬件又吃不消大家就开始盯上了TAA来做拼好帧越来越多算法依赖TAA来做优化后技术团队就不得不选择TAA作为抗锯齿算法再加上DLSS等算法的出现游戏画面特性可以堆得越来越多但是观感上反而变得越来越糊了我觉得在商业引擎当前的发展下很多算法并不构成技术壁垒反而是选择用什么才是最重要的评估方案的时候还有一个很重要的一点是可伸缩性这个本质上就是降低维护成本如果一个方案具备很好的可伸缩性也就是调一下参数就能提升品质/或者做降级那么也是一个会被优先考虑的做法但是要注意不能想当然地认为一个方案具备可伸缩性比如某些方案可能砍到一定精度后效果已经完全失真这个时候只能说明对于想要达到的目标选型可能是错误的也还有很多技术方案属于捆绑销售的比如在场景中生成了SDF或者生成了HZB那么其它的算法是不是都可以去用这个数据一旦有些东西做了完整的基建那么就会去渗透并且影响到其它的技术选型以及一些商业引擎主推的方案也会成为大家的首选除了能更快看到结果外还有一方面的原因是降低了解释成本比如如果你说我自研了一套全局光照方案老板很可能会对这个东西产生不信任这种不信任是人之常情但如果你说我用了ue5的Lumen技术这种疑虑就会被打消如果越来越多的项目选择使用这个技术那么对于官方而言也是一种利好