Skip to content

高级光线传播与复杂外观建模

上一章我们把材质理解成“表面对光的响应规则”。这已经能解释塑料、金属、粗糙度、高光和基础 PBR 参数。但真实世界里还有很多外观不只发生在表面:光会进入玻璃,穿过水雾,在皮肤内部散开,在头发纤维之间多次反射,在布料纤维之间产生柔和的边缘亮度。

这一章的重点是:复杂外观往往来自更复杂的光线路径。 它不一定是“贴图更多”,而是光在表面、内部和介质中的传播方式变多了。

普通不透明材质可以近似认为:光打到表面,立刻在表面被反射或吸收。这个假设很有用,也足够覆盖大量物体。

但有些材料不能这样简单处理:

  • 玻璃、水和宝石会让光进入物体,并改变方向。
  • 皮肤、蜡、牛奶、玉石会让光进入内部,然后在别的位置散出。
  • 烟、雾、云、浑浊水体会在空间中吸收和散射光。
  • 头发和毛皮由大量细纤维组成,光会沿纤维方向产生特殊高光。
  • 布料由纱线交织而成,反射取决于纤维方向和微小阴影。

这时材质模型要描述的不只是某个表面点的反射,还要描述光在物体内部或介质中如何继续传播。

复杂外观中的光传输类型

透明材质最直观:光可以穿过物体。真正的难点不在“看得见后面”,而在光线进入不同介质时会改变方向。

折射方向由介质折射率决定。空气、水、玻璃、钻石的折射率不同,所以光线弯折程度也不同。图形学中常用 IOR 表示折射率。

空气 IOR 约 1.0
水 IOR 约 1.33
普通玻璃 IOR 约 1.5
钻石 IOR 约 2.4

折射材质还会产生两个重要现象:

  • 菲涅耳反射。 视角越接近掠射方向,反射越强,透射越弱。
  • 全内反射。 光从高折射率介质进入低折射率介质时,某些角度下无法折射出去,只能反射回内部。

这就是玻璃和水面在不同角度下外观变化很大的原因。

透明不代表完全无色。光在介质中传播时可能被吸收,传播距离越长,被吸收得越多。

例如一杯清水看起来几乎无色,但深海会呈现蓝色;一块薄玻璃颜色很淡,厚玻璃边缘颜色更明显。这类现象可以用吸收描述。

透射光 ≈ 入射光 × exp(-吸收系数 × 路径长度)

这说明颜色不仅取决于材质参数,还取决于光在物体内部走了多远。厚的地方更暗、更有颜色,薄的地方更接近透明。

次表面散射描述光进入物体内部后,经过多次散射,再从附近另一个位置出来。它常见于皮肤、蜡、玉石、牛奶、树叶和某些塑料。

如果没有次表面散射,皮肤常会像塑料一样硬;蜡烛和玉石会缺少半透明的温润感。次表面散射让阴影边缘更柔,薄的区域更容易透光,颜色也会在内部传播。

可以从三件事理解它:

  • 进入。 光先穿过表面进入内部。
  • 扩散。 光在内部被多次散射,方向变得随机。
  • 离开。 光从另一个位置离开表面,形成柔和、半透明的外观。

实时渲染中常用近似方法,例如屏幕空间次表面散射、预积分皮肤着色或厚度贴图;离线渲染中可以通过随机游走或扩散近似更准确地模拟。

下面的小程序把三种传播方式放在一起:普通表面反射、次表面散射、体积吸收/散射。它的目的不是做真实渲染,而是帮助你观察“光走在哪里”。

表面反射把光留在命中点附近;次表面散射让光进入物体后从附近散出;体积介质让光在空间中逐步衰减并向周围散射。

可以重点观察:

  • 表面模式下,光主要在命中点附近反射。
  • 次表面模式下,光会进入物体内部,并从附近区域柔和散出。
  • 体积模式下,光在空间中被吸收和散射,路径会逐渐衰减。
  • 把厚度调大时,内部传播和吸收会更明显。

体积介质指光在空间中传播时就会与介质发生作用,而不是等到碰到表面才变化。雾、烟、云、尘埃、水下悬浮颗粒都属于这一类。

体积渲染通常需要处理三个过程:

  • 吸收。 光能量被介质吸收,路径越长越暗。
  • 外散射。 光从当前方向散射到其他方向,使原方向能量减少。
  • 内散射。 其他方向的光散射进当前视线,使介质本身看起来发亮。

这解释了为什么远山在雾中更浅,为什么手电筒光柱在烟雾里可见,为什么云不是简单的白色表面,而是有厚度、有暗部、有边缘透光。

体积渲染的代价通常很高,因为光线不只要找表面交点,还要沿着空间路径积分。实时渲染常用体积纹理、切片、步进采样、低分辨率体积缓冲和时域累积来近似。

头发、毛皮和纤维不是普通光滑表面。每根头发都像细长的半透明曲线,光会沿纤维方向产生各向异性高光,还可能进入发丝内部再折射或反射出来。

头发外观有几个明显特征:

  • 高光通常沿发束方向延展,而不是圆形亮点。
  • 不同颜色头发对光的吸收不同,深色头发更容易吸收光。
  • 大量发丝之间会互相遮挡,形成柔软但复杂的阴影。
  • 逆光下发丝边缘常出现明亮轮廓。

因此毛发渲染通常需要专门的 BSDF,而不是直接套用普通表面材质。

布料看似不透明,但它的外观来自纤维和纱线的微结构。丝绸、棉布、羊毛、天鹅绒的差别不仅是颜色不同,而是纤维方向、绒毛高度、微小阴影和反射分布不同。

例如天鹅绒在掠射角会出现很强的边缘亮度;丝绸有明显方向性高光;粗布的反射更散,细节更多来自法线和遮蔽。

布料建模可以从三个层次看:

  • 宏观形状。 褶皱、垂坠、轮廓。
  • 中观结构。 纱线交织方向和重复图案。
  • 微观纤维。 绒毛、细丝和局部遮挡。

实时渲染常把这些层次压缩进法线贴图、粗糙度贴图、各向异性参数和特殊边缘反射项里。

焦散是光经过镜面反射或折射后,被集中到某些区域形成的亮纹。水杯在桌面上的亮斑、游泳池底部的波纹、宝石内部的强烈亮线都属于焦散。

焦散难渲染,是因为贡献集中在很少的路径上。普通路径追踪从相机出发随机反弹,刚好经过“光源 → 镜面/玻璃 → 某个表面 → 相机”的概率很低,所以需要大量样本才稳定。

常见解决思路包括:

  • 从光源出发追踪光子,记录能量分布。
  • 使用双向路径追踪,同时从相机和光源构造路径。
  • 使用特殊采样策略,提高命中高贡献路径的概率。
  • 在实时渲染中用贴图、屏幕空间方法或预计算近似。

复杂外观越真实,通常成本越高。实际项目里很少无条件追求最物理的解法,而是根据镜头距离、性能预算和视觉重要性取舍。

  1. 先判断光是否进入物体。
    如果只在表面反射,普通 PBR 可能足够;如果进入内部,就要考虑透射、吸收或次表面散射。

  2. 判断效果是否影响轮廓和阴影。
    只影响局部质感的效果可以用贴图近似;影响大范围光照的效果可能需要真正的光传输模型。

  3. 判断是否需要方向性。
    头发、布料、拉丝金属这类材质往往需要各向异性。

  4. 根据距离选择层级。
    近景角色皮肤可能需要复杂 SSS,远景角色可以用更简单的近似。

  5. 用参考图校准。
    复杂外观很容易“看起来高级但不真实”,需要真实照片或扫描材质作为参照。

学习复杂外观时,最容易遇到几个误区:

  • 把透明度当作玻璃。 玻璃需要反射、折射、菲涅耳、吸收和厚度,单纯透明只会像淡化的塑料。
  • 把次表面散射当作模糊。 SSS 不是简单把颜色涂开,而是光在内部传播后从附近散出。
  • 把体积当作半透明平面。 雾和烟存在于空间中,亮度与路径长度、光照方向和密度有关。
  • 把毛发当作普通细圆柱。 头发有专门的方向性反射和内部吸收。
  • 忽略尺度。 同样的吸收系数,在小物体和大物体上会产生完全不同的颜色深度。

这些误区背后有同一个原因:只看最终颜色,而没有追踪光到底走了哪条路。

本章把外观建模从普通表面推进到了更复杂的光传输:

  1. 透明和折射描述光进入不同介质后改变方向。
  2. 吸收让透射颜色与路径长度相关,厚处更暗也更有色。
  3. 次表面散射让光进入内部,再从附近柔和散出。
  4. 体积介质让光在空间路径中被吸收、外散射和内散射。
  5. 毛发、布料和纤维材质需要考虑方向性和微结构。
  6. 焦散来自高能量路径的集中,通常需要更专门的采样方法。

到这里,我们已经从几何、光线、材质走到了复杂外观。下一章会把视角切换到相机与透镜:同一个场景,为什么换一个镜头、焦距、光圈或曝光设置,画面表达会完全不同。