借用场景 LOD 的思想,既然远处的模型替换成了低模,动画看上去也不会动了,那么阴影贴图渲染其实每帧变化并不大,也会随着级联阴影层级的提高变化越来越小;
因此可以想到,对远距离的级联阴影级别下,可以不对每个物体阴影做重新绘制;
将阴影贴图进行 cache 缓存,并对级联阴影的每个级别的阴影贴图块按不同的刷新率去更新,就可以降低每帧投影体绘制的次数了。
- 在 URP 下,主光源级联阴影是通过 MainLightShadowCasterPass 脚本完成的,拷贝一份 MainLightShadowCasterCachedPass,同时修改 UniversalRenderer 中所有 MainLightShadowCasterPass 为 MainLightShadowCasterCachedPass
- 由于级联阴影 Texture 不能每帧创建了,在 MainLightShadowCasterCachedPass 中移除 m_MainLightShadowmapTexture 的释放逻辑,并将释放逻辑分离出接口
- 将 MainLightShadowmapTexture 的释放逻辑移至 UniversalRanderer 下的 Dispose 中,相当于变相延长了它的生命周期
- 添加 bool 变量判断是否是第一帧,添加针对 ShadowMap 的更新数组,数组有几个元素代表了做几帧的更新循环,如 1|4 代表了第一个级别与第三个级别的级联阴影块,如此处代表了每 3 帧中第一个级别更新 2 次,第二个级别更新 1 次,另外一个创建记录当前运行到多少帧的变量,方便取模按照 3 帧一个循环更新阴影贴图
- 修改 MainLightShadowCasterCachedPass 中 ShadowMap 创建逻辑,只有当对象为空或者 ShadowMap 大小发生改变时才创建
- 修改 RenderMainLightCascadeShadowmap 中的每帧渲染逻辑替换为按 3 帧一循环的渲染逻辑,并把 RenderShadowSlice 替换为修改的 RenderShadowSlice,以控制不同级别阴影块的单独绘制,而不是控制整个 ShadowMap 了