在移动端实现SSR的Hierarchical-Z优化

解读

面试官问的是“在Unity移动端屏幕空间反射(SSR)跑起来,还要用Hierarchical-Z(Hi-Z)做加速”。
国内项目场景通常是
中低端安卓机占比高、GPU带宽小、Tile-Based延迟渲染
为主,SSR又属于全屏后效+随机采样的带宽杀手,直接照搬PC的Ray-Marching会被GPU占用率/发热/帧率三杀。
因此考点聚焦在:

  1. 能否把Hi-Z做成单通道MipChain不破坏移动端TBDR的On-Chip Depth
  2. 能否用Unity CommandBuffer + Custom Renderer Feature把Hi-Z生成、SSR Ray-Trace、Resolve三阶段无缝塞进URP管线的AfterOpaque
  3. 能否用Half-Res + Bilateral Upsample + Tile-Based Ray Budget千元机(Adreno 530 / Mali-G71 同级)压到2 ms以内、带宽<200 MB/s
  4. 能否回退到Reflection Probe + SSR混合,在GPU不支持UAV写Texture2D的老机型上不Crash

知识点

  1. 移动端TBDR架构:Tile Memory大小仅16–32 KB,Hi-Z Mip-Chain必须一次Pass完成,否则Depth Resolve回系统内存代价爆炸。
  2. Hierarchical-Z生成
    • Compute Shader2×2 Max Reduction,输出R16F格式,Mip0=原DepthMipN=1/2^N分辨率
    • Unity 2022.3+ URP里用RTHandle.ScalableAllocator申请_CameraHiZTexture每帧复用避免Realloc。
  3. Hi-Z Ray Intersection
    • Coarse-to-Fine 3级跳跃:先4×4 Tile级,再2×2,最后逐像素
    • Early-Out阈值设为0.995×Zmax,减少Over-Stepping
    • GroupShared Memory缓存当前Tile的Hi-Z Mip,避免重复采样
  4. 移动端优化三板斧
    • Half-Res Ray:256×150起步,Bilateral Upsample时把GBuffer Normal打包到RGB10A2节省带宽;
    • Ray Budget:每像素最大16 StepAdreno 530实测1.7 ms
    • Fresnel Mask:用Schlick近似F0<0.04的像素直接Kill Ray节省30%采样
  5. Unity落地细节
    • GLES3.1机型不支持RWTexture2D<float>,Hi-Z生成Pass要回退到Fragment Shader + MRT
    • Vulkan/Metal下用SubpassHi-Z生成与SSR Trace合并,减少一次RenderPass切换
    • Package必须ScriptableRenderPass+ScriptableRendererFeature写法,方便SRP Batcher合批。

答案

“我去年在××项目做水上镜面反射时,把SSR搬进了URP管线,目标机型是红米Note 5(Adreno 509)
第一步,用CommandBuffer.Blit_CameraDepthTexture转成R16F的Hi-Z Chain,Compute Shader2×2 Max Reduction一次Dispatch生成6级Mip,最底层32×18
第二步,Half-Res Ray-Trace,Compute Shader里每像素16 Step,用GroupShared缓存当前Tile的Hi-Z,Coarse-to-Fine 3级跳跃,Early-Out阈值0.995×Zmax,把Fresnel<0.04的像素直接discard;
第三步,Bilateral Upsample,用4 Tap+Depth+Normal权重边缘误差<1%
第四步,混合Reflection Probe,用Metalness+Smoothness球谐L0权重GPU不支持UAV的老机型自动回退。
最终红米Note 5 720p整帧2.1 ms、带宽180 MB/s、发热<3 ℃iOS iPhone 7做到1.3 ms
代码层面,Custom Renderer Feature暴露MaxStep/RayHitRadius/UpsampleRadius三档Quality,策划可在面板直接调无需重启游戏。”

拓展思考

  1. Vulkan Subpass能把Hi-Z生成与SSR Trace合并到同一RenderPass节省一次Tile Memory Store,在天玑9000上可再降0.4 ms
  2. Variable Rate Shading(VRS)Adreno 7xx上可把Half-Res Ray1×1 Rate降到2×2带宽再省25%,但需Unity 2023.2+ SRP 15.0
  3. SSR+SSGI共用Hi-Z Chain,把Ray方向拆成Reflection/Diffuse GI两档,MipN层级复用整体<3 ms
  4. 国内渠道包体限制100 MB,Hi-Z Chain默认R16F1.5 MB,可压缩到R11G11B108-bit LogDepth误差<0.3%包体-0.8 MB
  5. 腾讯WeTest GPU性能测试显示,Hi-Z SSRMali-G52带宽瓶颈>ALU瓶颈,下一步可尝试把Ray-Trace改成FP16带宽再降15%