在移动端实现SSR的Hierarchical-Z优化
解读
面试官问的是“在Unity移动端把屏幕空间反射(SSR)跑起来,还要用Hierarchical-Z(Hi-Z)做加速”。
国内项目场景通常是中低端安卓机占比高、GPU带宽小、Tile-Based延迟渲染为主,SSR又属于全屏后效+随机采样的带宽杀手,直接照搬PC的Ray-Marching会被GPU占用率/发热/帧率三杀。
因此考点聚焦在:
- 能否把Hi-Z做成单通道MipChain且不破坏移动端TBDR的On-Chip Depth;
- 能否用Unity CommandBuffer + Custom Renderer Feature把Hi-Z生成、SSR Ray-Trace、Resolve三阶段无缝塞进URP管线的AfterOpaque;
- 能否用Half-Res + Bilateral Upsample + Tile-Based Ray Budget把千元机(Adreno 530 / Mali-G71 同级)压到2 ms以内、带宽<200 MB/s;
- 能否回退到Reflection Probe + SSR混合,在GPU不支持UAV写Texture2D的老机型上不Crash。
知识点
- 移动端TBDR架构:Tile Memory大小仅16–32 KB,Hi-Z Mip-Chain必须一次Pass完成,否则Depth Resolve回系统内存代价爆炸。
- Hierarchical-Z生成:
- 用Compute Shader做2×2 Max Reduction,输出R16F格式,Mip0=原Depth,MipN=1/2^N分辨率;
- 在Unity 2022.3+ URP里用RTHandle.ScalableAllocator申请_CameraHiZTexture,每帧复用避免Realloc。
- 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,避免重复采样。
- 移动端优化三板斧:
- Half-Res Ray:256×150起步,Bilateral Upsample时把GBuffer Normal打包到RGB10A2节省带宽;
- Ray Budget:每像素最大16 Step,Adreno 530实测1.7 ms;
- Fresnel Mask:用Schlick近似把F0<0.04的像素直接Kill Ray,节省30%采样。
- Unity落地细节:
- GLES3.1机型不支持RWTexture2D<float>,Hi-Z生成Pass要回退到Fragment Shader + MRT;
- Vulkan/Metal下用Subpass把Hi-Z生成与SSR Trace合并,减少一次RenderPass切换;
- Package必须ScriptableRenderPass+ScriptableRendererFeature写法,方便SRP Batcher合批。
答案
“我去年在××项目做水上镜面反射时,把SSR搬进了URP管线,目标机型是红米Note 5(Adreno 509)。
第一步,用CommandBuffer.Blit把_CameraDepthTexture转成R16F的Hi-Z Chain,Compute Shader里2×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,策划可在面板直接调,无需重启游戏。”
拓展思考
- Vulkan Subpass能把Hi-Z生成与SSR Trace合并到同一RenderPass,节省一次Tile Memory Store,在天玑9000上可再降0.4 ms;
- Variable Rate Shading(VRS)在Adreno 7xx上可把Half-Res Ray的1×1 Rate降到2×2,带宽再省25%,但需Unity 2023.2+ SRP 15.0;
- SSR+SSGI共用Hi-Z Chain,把Ray方向拆成Reflection/Diffuse GI两档,MipN层级复用,整体<3 ms;
- 国内渠道包体限制100 MB,Hi-Z Chain默认R16F占1.5 MB,可压缩到R11G11B10或8-bit LogDepth,误差<0.3%,包体-0.8 MB;
- 腾讯WeTest GPU性能测试显示,Hi-Z SSR在Mali-G52上带宽瓶颈>ALU瓶颈,下一步可尝试把Ray-Trace改成FP16,带宽再降15%。