解释Reflection Probe的Box Projection算法

解读

国内面试中,这道题常被用来区分“只会挂组件”与“真正理解渲染管线”的候选人。面试官想听的不是“勾一个Box Projection 开关”的操作,而是为什么开启后金属表面不再像贴了一张天空盒,以及Unity 如何用一张立方体贴图还原室内局部反射。答出算法核心、边界情况、性能代价,才能拿到高分。

知识点

  1. 反射向量推导:视线向量 I 关于法线 N 的反射向量 R = I - 2(N·I)N
  2. 立方体贴图采样:以 R 为方向在无穷远环境做查询,默认无“位置”概念
  3. 局部空间假设:Box Projection 把 Probe 视作一个有限长方体,反射射线在此盒内做AABB 相交测试
  4. 射线-盒相交算法:Slab 方法,分别计算 tx1,tx2,ty1,ty2,tz1,tz2,取 tmin = max(max(tx1,ty1),tz1)tmax = min(min(tx2,ty2),tz2);若 tmin<tmaxtmax>0,则相交
  5. 相交后重算方向:命中点 P = O + t*R,新方向 R' = normalize(P - ProbeCenter),再用 R' 采样立方体贴图
  6. 边界与修正:当摄像机或像素点在盒外,需先 clamp 射线起点到盒表面,避免反向偏移
  7. 性能代价:每次反射要额外做 6 次除法与若干 max/min,移动平台需控制 Probe 数量与更新频率
  8. 与屏幕空间反射(SSR)互补:Box Projection 解决“离线局部反射”,SSR 解决“动态物体倒影”,两者常混合使用

答案

Box Projection 的核心是把“无穷远环境”拉回到一个有限长方体 Probe 范围内。
步骤如下:

  1. 在像素着色器里拿到世界空间摄像机位置 O、像素位置 Pworld、法线 N,先算视线 I = normalize(O - Pworld) 与反射向量 R
  2. OR 转换到 Probe 的局部空间(以 Probe 中心为原点,Probe 盒半尺寸为 extents)。
  3. 用 Slab 算法求射线 Ray(O,R)[-extents, extents] 长方体的最近相交参数 t
  4. 若相交且 t>0,计算命中点 Hit = O + t*R,再把 Hit 转回世界空间,得到实际发生反射的世界位置
  5. 用新方向 R' = normalize(Hit - ProbeCenterWorld) 去采样 Reflection Probe 的立方体贴图,得到局部一致的反射颜色
  6. 若不相交或 t<0,退回到传统无穷远采样,保证盒外区域不出现断裂。

这样,金属墙面上的反射会随着摄像机移动而滑动,不再像一张固定天空盒,从而在室内、走廊等封闭场景里获得物理可信的局部反射

拓展思考

  1. 移动端性能优化:
    • 把 Box Projection 计算移到顶点着色器或用Half Resolution 渲染反射, fragment 阶段只插值方向,减少 Slab 计算次数
    • 对远距或粗糙材质直接关闭 Box Projection,用无穷远近似,节省带宽
  2. 与 Shader Graph 的集成:在 Custom Function 节点里手写 float3 boxProjection(float3 R, float3 O, float4 probeParams, float3 boxMin, float3 boxMax),方便美术开关
  3. 多 Probe 融合:Unity 的 Blend Distance 只在无穷远模式下工作,开启 Box Projection 后需自己实现基于距离权重的球谐或立方体插值,否则接缝明显
  4. 与 DXR/Metal RayTracing 对比:Box Projection 是离线烘焙 + 运行时重映射,无法响应动态物体;硬件光追用实时相交,精度高但功耗大,国内中低端机型仍依赖 Box Projection 方案
  5. 常见踩坑:
    • 忘记把射线起点 clamp 到盒表面,导致盒外摄像机出现反向拉伸
    • Probe 尺寸设得过大,相交距离 t 几乎恒为 0,反射结果与无穷远一致,失去局部感
    • 在 Shader 里未做 tmin<tmax 判断,NaN 值会让全屏出现黑斑,面试时提到这一点可体现踩坑经验