Skip to content

三面镜

背景:Phase 1 渲染增强(Motion Blur/Sharpen/Glow)完成后,Phase 2 目标是更高级的特性——SSR(屏幕空间反射)、SSAO(环境遮蔽)、ReflectionProbe(反射探针)、SSS(次表面散射)。

过程:SSR/SSAO/ReflectionProbe 用独立 pipeline 实现,StandardMaterial 兼容;SSS 因需要 PBR 材质迁移、会破坏 morph 动画系统而延期。


"你觉得这个画面看起来怎么样?"

外交官和 AI 站在一个调试场景里。一个模型站在光影之间,地面有倒影,背景有光晕。

"好看,"AI 说,"挺好看的。Phase 1 的效果都在——Motion Blur 让动作不卡顿,Sharpen 让轮廓清晰,Glow 给灯光加了氛围。"

"但你看这里,"外交官走到模型面前,蹲下来看地面,"这个倒影——它是假的。"

"假的?"

"这是一个假倒影。打开渲染管线的 debug 模式,你会发现它根本不是从模型表面反射过来的——它是一个固定的贴图,旋转了一下,贴在地面上。模型换了个姿势,倒影不变。"

AI 仔细看了看。确实——模型抬起了左手,倒影的手还是垂着的。

"哦,"AI 说,"所以 Phase 1 做完之后,画面虽然'好看'了,但经不起细看。"

"对。Phase 2 的目标就是——让它经得起细看。"


四面镜子

外交官把 AI 带到一面空墙前面。墙上挂着四个镜框,其中三个已经装上了镜子,第四个空着。

"渲染增强 Phase 2,四项技术。我管它们叫四面镜子。"

他站到第一面镜子前面,镜子里映出调试场景的局部画面——地面、墙壁、模型的边缘——像是从另一个角度看到的同一空间。

"第一面镜子:SSR——屏幕空间反射。"

"这面镜子不反射真实的世界——它只反射屏幕上能看到的东西。模型在地面上方,屏幕里有模型的画面,SSR 取这个画面的一部分,贴在反射面上。"

"所以它反射的不是真实模型,是屏幕里模型的画面?"

"对。有限制——如果模型的一部分在屏幕边缘之外,SSR 反射不到。但大部分时候够用。"

外交官在镜框旁边扭了一下旋钮。镜面里的倒影变得更清晰了一些。

"反射强度、边缘衰减、步长、厚度容差——四个参数可控。而且 SSR 和 Bloom 会打架——亮度太高的时候,SSR 的反射会白出一片。引擎里加了保护逻辑:Bloom 强度超过 0.5,自动压低 SSR。"


第二面镜子。镜面里的像是从角落看出去的——墙壁和模型的交缝处有浅浅的阴影,让物体的立体感更强。

"第二面镜子:SSAO——屏幕空间环境遮蔽。"

"把画面想象成一个有很多角落的房间。阳光能直射到的地方亮,墙角、缝隙、物体之间的交界处——光线射不进去——应该暗一些。"

"SSAO 就是做了这件事?"

"对。它算出每个像素周围有多少遮挡——被挡得多的,画暗一点。物体之间的交界就有了'深度感'。"

外交官指了指镜框上的标签:

"遮蔽强度、遮蔽半径、采样数——三个参数。加了 bilateral denoising——一种去噪算法——防止画面因为采样数不够而出现黑斑。"

"为什么这个不需要和任何东西打架?"

"因为 SSAO 是独立 pipeline——它自己读 depth 和 normal buffer,和别的渲染管线不冲突。L1 性能降级的时候保留 SSAO,L2/L3 才关——因为它的性能开销最小。"


第三面镜子。镜面是暗的——什么都没反射。

"第三面镜子:Reflection Probe——环境反射探针。"

"这面镜子不是实时的,"外交官抬手摸了摸空无一物的镜面,"它每 10 秒拍一张周围环境的照片——天空、云、水面、地面——然后把这照片贴到模型的表面作为反射。"

"模型本身在照片里吗?"

"不在。"外交官摇头,"刻意排除了。不然会产生无限递归——模型照镜子,镜子里有模型,模型照镜子……"

"就 10 秒拍一次?模型在动怎么办?"

"模型不在 renderList 里——只拍环境,不拍模型。所以模型怎么动都不影响反射内容。而且反射探针只有 256 像素分辨率,不是全高清——为了性能。"

"那什么时候刷新?"

"每 10 秒自动检查一次环境变化。切换环境预设的时候,手动强制刷新一次——'哎,环境换了,你再用 10 秒拍一次新照片'。"

"够用吗?"

"够用。环境反射不需要每帧更新——天不会 1 秒变 8 次。"


第四面镜子

第四面镜框是空的。

AI 看着那个空镜框:"第四面镜子呢?"

"第四面镜子是 SSS——次表面散射,"外交官说,"它能做一件事——让皮肤看起来像皮肤。"

"什么意思?"

"你知道为什么手机对着强光,手指尖会发红发亮?因为光线穿进了皮肤,在皮下散射,再从另一边透出来。这个效果叫次表面散射——Subsurface Scattering。"

"没有它,皮肤的质感和塑料一样。"

"对。有它,皮肤的质感和皮肤一样。它的效果是最明显的——也是最难的。"

"难在哪?"

"SSS 需要 PBR 材质——基于物理的渲染材质。我们现在用的是 StandardMaterial,不支持 SSS。要支持 SSS,得把所有材质从 StandardMaterial 升级到 PBR。"

"那就升级啊?"

外交官没有直接回答。他拉开旁边一张桌子上的清单:

"升级到 PBR 的影响评估——

  • babylon-mmd 的 morph 动画系统深度绑定 StandardMaterial。转了 PBR,morph 权重不工作——模型的表情动画全废。
  • 模型的外轮廓描边(Outline)依赖 StandardMaterial 的属性结构。转了 PBR,描边崩。
  • toon 贴图和 sphere 贴图——MMD 模型的两个特殊贴图类型——在 PBR 渲染模式下没有对应映射。转了,这些贴图丢失。
  • 换装系统的纹理清理、材质编辑器里 5 处 instanceof StandardMaterial 的守卫判断——全要重写。"

"代价太大了。"

"对。一个渲染特性,换整个材质管线崩盘。这样的交换不划算。"

AI 看着那个空镜框:"所以第四面镜子就不装了?"

"不是不装,"外交官说,"是等。等 babylon-mmd 的未来版本支持 PBR material proxy——等材质类型抽象层的出现——再做。"

"在等的时候呢?"

"在等的时候——前三面镜子已经能让画面好很多了。SSR 给表面加倒影,SSAO 给角落加深度的阴影,Reflection Probe 给模型加环境的反射。三项加起来,画面已经从'好看但不经看'变成了'值得多看两眼'。"

"那第四面镜子的框架……"

"留着。等材料和工具成熟了,再把它装上。"


三面对四面

外交官把三面镜子的旋钮都拧到了中间值,退后几步看。

调试场景里,模型站在光影中。地面映着模型的轮廓(SSR),墙壁和模型的交缝处有细腻的阴影(SSAO),模型的表面微微反着天空的颜色(Reflection Probe)。

"做三件而不是做四件的诀窍是什么?"AI 问。

"诀窍是知道什么能做,什么不能现在做。"

外交官拍了拍那个空镜框:

"如果硬把第四面镜子装上——整面墙会塌。因为镜框的安装方式(材质系统)不支持那面镜子的重量。不是镜子的问题——是墙的问题。"

"等问题解决了,再装。"

"对。到时候只要把镜子放进去,不用拆墙。"


教训:一个渲染特性不该破坏整个材质管线。SSR/SSAO/ReflectionProbe 用独立 pipeline 实现,和现有材质系统不冲突——它们可以做到。SSS 需要材质升级,升级的代价是整个 morph 动画系统和贴图管线——它不能现在做。学会区分"不能做"和"不能现在做"。