解释Half Resolution与Dual Kawase Blur的优化思路

解读

国内Unity项目面试中,这道题常被用来快速判断候选人对移动端GPU带宽瓶颈后处理管线设计的理解深度。面试官想听的不是“把分辨率砍一半”这种表面答案,而是:

  1. 为什么半分辨率能省采样带宽ALU
  2. Dual Kawase Blur怎样把传统高斯模糊O(n²)复杂度降到O(log n)并天然适配半分辨率;
  3. 在U3D里如何落地:RenderFeature怎么拆Pass、怎么与Unity的RTHandle系统配合做自动scale、自动回收,以及怎么在ShaderLab里用Branch做Early-Exit防止Overdraw;
  4. 最终如何把耗时从8 ms压到1.5 ms以内,让低端骁龙665也能跑满30 FPS。

知识点

  • GPU带宽公式:带宽≈分辨率×每像素字节数×(读+写次数);半分辨率直接×0.25。
  • Kawase Blur核心:分离卷积→双线性采样一次取4邻域→迭代步长指数递增→四次迭代等效64 tap高斯。
  • Dual Kawase优化:Down→Up两条金字塔,Down阶段每级双线性降采样并做3×3 Kawase,Up阶段反向重建,利用half resolution RTbilinear upsample减少cache miss。
  • Unity实现细节
    • Rendering.RenderPassInput的**ConfigureInput(ScriptableRenderPassInput.Color)**告诉URP不要额外申请全屏RT;
    • 用**RTHandles.Alloc(scaleFactor)**动态申请0.5×RT,避免常驻显存;
    • Blit时设置RenderBufferLoadAction.DontCare省一次读;
    • 用**#pragma multi_compile _ _USE_HALF_RES**在Shader里做条件编译,防止低端机Fallback全分辨率。
  • 常见坑:半分辨率+Alpha通道带透明物体时会出现边缘重影,需要在Down Sample前做一次Alpha预乘并关闭sRGB Read/Write防止色偏。

答案

“Half Resolution的核心是把后处理RT的宽高各砍一半,GPU带宽直接降到25%,同时片元着色器执行次数也减到四分之一,对千元机非常有效。
Dual Kawase Blur在此基础上再做算法级优化:

  1. 先降采样到半分辨率,用双线性采样一次取4邻域,做一次3×3 Kawase,迭代4次,等效64 tap高斯,复杂度从O(n²)降到O(log n)。
  2. 升采样阶段用同样的Kawase核反向重建,利用bilinear upsample把半分辨率结果插值回全屏,视觉损失几乎不可见
  3. 在Unity里我封装成CustomRenderPassFeature,用RTHandleSystem动态申请0.5×RT,RenderPassEvent.AfterRenderingTransparents插入,CommandBuffer.SetRenderTarget时把LoadAction设成DontCare省一次读,整体耗时从8 ms降到1.2 ms,在骁龙665上跑《XX项目》30 FPS稳定。
  4. 为了防透明物体边缘重影,我在Down Sample前加了一次Alpha预乘并关闭sRGB,最终UI Bloom效果与全分辨率PSNR>48 dB,策划验收通过。”

拓展思考

  • 如果项目需要4K输出,可以把Dual Kawase改成Quarter Resolution+Temporal Stabilization,用Motion Vector做重投影,FSR做锐化,带宽再降75%,但需解决鬼影闪烁
  • URP 16Rendering Debugger里打开Frame Timing,可以看到半分辨率RTcache miss rate比全分辨率低60%,这是Dual Kawase在Mali-G52上比传统Two-Pass Gaussian快3倍的底层原因。
  • 未来Vulkan Subpass+Fragment Shading Rate可以把半分辨率Dual Kawase做到0.8 ms以内,但Unity 2022 LTS还不支持,需要改Custom SRP并手动写VkSubpassDescription,风险较高,建议等Unity 6000 LTS官方支持。