GPU Gems 1 · Chapter 18. Spatial BRDFs

用紧凑的空间 BRDF 参数表示每个表面点的角度反射差异,并支持离散光与预卷积环境光的实时渲染。

学习目标

  • 能区分空间变化与角度变化,并用自己的话解释为什么纹理与 BRDF 的组合比单独的颜色贴图更能描述真实表面
  • 能实现 Lafortune representation 的 diffuse 加多个 specular lobe,并说明 Cx、Cy、Cz、n 和 albedo 各自控制什么
  • 能把每个 texel 的 lobe 参数打包到纹理,在 local surface coordinates 中完成离散光评估
  • 能解释预卷积环境图如何把 sharpness n 映射为 cube mipmap LOD,并在质量、带宽和精度之间做取舍

一张普通颜色纹理只回答“这个位置是什么颜色”,而一个普通光照模型只回答“这个位置在不同入射、出射方向下如何反射”。真实的木纹、刷痕、丝线和金属表面同时拥有这两种变化:不同位置的材质不同,同一位置从不同角度看也不同。GPU Gems 1 第 18 章把两者合并为 Spatial BRDF,并讨论用紧凑参数在硬件上实时评估。

为每个表面位置保存一组反射参数,而不是让整张物体共享一个材质。这里的空间坐标通常通过 UV 找到 texel,角度则在 shading 时由光向量和视向量提供。这样,同一个模型可以在不同位置混合粗糙、镜面、织物或带方向性的反射行为。

SBRDF:空间变化 × 角度变化surface pointp + uvtexture mapsdiffuse + lobeslocal frameT B NT, B, Nrenderlights / env每个 texel 都可以有不同的 BRDF,而不是只换一张颜色贴图
SBRDF 将二维空间变化与入射、出射角度变化组合起来;每个 texel 不再只有颜色,还拥有自己的反射模型参数。

1. 从 BRDF 到可存储的空间表示

关注一个点的角度响应;空间 BRDF 再为表面上的每个点提供不同的响应。最直接的方案是在每个 texel 保存完整 BRDF 参数,但参数数量必须足够紧凑,才能接受纹理带宽、缓存和 fragment shader 成本。

GPU Gems 采用 Lafortune 风格的和式:一个 diffuse reflectance 加上若干 specular terms。可以用下面的结构理解它,而不必把它当成对所有真实光传输的精确测量:

fr(p,wi,wr)d(p)+jsj(p)(Cx,jwi,xwr,x+Cy,jwi,ywr,y+Cz,jwi,zwr,z)njf_r(p, w_i, w_r) \approx d(p) + \sum_j s_j(p)\,\bigl(C_{x,j}w_{i,x}w_{r,x} + C_{y,j}w_{i,y}w_{r,y} + C_{z,j}w_{i,z}w_{r,z}\bigr)^{n_j}

把每个 term 看作一个可缩放、可偏转的高光形状。 的 albedo 控制能量,C 系数控制峰值方向与各向异性,n 控制峰值宽窄。一个、两个或三个 lobe 通常足以表达常见材质的质量与速度折中。

Lafortune representation:diffuse + specular lobeslobe 1lobe 2lobe 3N / z axisC · wi → peakper lobealbedo sshape Cx, Cy, Czsharpness none, two, or three lobesC 的符号可表达 isotropic、off-specular、retro 或 thread-like 行为
少量 lobe 的关键不是复制每个测量样本,而是用 C 向量把峰值推向合适方向,用 n 控制宽窄,再让每个 texel 保存自己的参数。

当 Cx 与 Cy 相等时,响应更接近各向同性;不同符号和不同大小可以把峰值从法线反射方向拉开,表达 off-specular、retroreflection,或沿刮痕和丝线方向不同的 forward/back scattering。需要注意的是,这种灵活性来自参数近似,不能自动恢复测量数据中所有尖峰和遮挡。

2. local frame 与 lobe 评估

将方向对齐到材质的切线框架:z 轴是法线,x、y 轴可以指向木纹、刷痕或织物主方向。顶点阶段应把 light vector 和 eye vector 以一致的坐标约定传给片元阶段,否则 C 系数的方向意义会错位。

离散光路径可以按以下顺序组织:

  1. 由 UV 读取 diffuse albedo、每个 lobe 的 albedo 和 shape 参数。
  2. 用 scale-bias 解码八位纹理里的 Cx、Cy、Cz 与 n;若使用浮点纹理,则减少量化误差但增加带宽。
  3. 归一化 local-space 的 to-light 与 to-eye,按 lobe 计算广义点积,再累加 diffuse 和 specular response。
  4. 将每个 light 的 incident radiance 乘上 max(0, N dot L),再把所有 light 的 exitant radiance 相加。
float3 EvaluateLobe(float3 wi, float3 wr, Lobe lobe) {
  float3 shearedEye = lobe.C * wr;
  float shape = max(0.0, dot(shearedEye, wi));
  return lobe.albedo * pow(shape, lobe.n);
}
 
float3 ShadeSbrdf(float2 uv, float3 wi, float3 wr, float3 lightColor) {
  float3 result = sampleDiffuse(uv);
  for (int j = 0; j < LOBE_COUNT; ++j) {
    Lobe lobe = decodeLobe(uv, j);
    result += EvaluateLobe(normalize(wi), normalize(wr), lobe);
  }
  return result * lightColor * max(0.0, wi.z);
}

这里的伪代码将 lobe 的形状和入射 irradiance 分开,便于检查能量是否被重复乘入。原始实现还会处理 HDR exposure、alpha 和多个 light;工程实现应保持参数解码、坐标变换和归一化的一致性。

texture packing:把每个 texel 的 BRDF 参数带进 shadertex_difdiffuse albedolobe mapss_j albedoCx, Cy, Cz, nscale 96 · bias 128localT, B, Nwi, wrlobe evalpoint sample非线性 shape 参数直接线性插值可能产生 sparkle,优先验证采样方式
将 diffuse、lobe albedo 和 shape 参数拆成可控的纹理通道;参数纹理的解码与采样策略决定了高光能否稳定。

八位纹理无法直接覆盖 Cx、Cy 的负值范围,因此需要约定 encoded = value * scale + bias,读取后再反解码。示例中可用固定 scale 与 bias 让数值落入可存储范围;实际平台应通过材质范围、压缩格式和误差测试校准,而不是把一个示例常数当成普适物理单位。

3. 纹理采样与质量预算

普通 diffuse albedo 通常可以使用线性过滤,因为颜色在空间上的平滑混合较自然;但 Cx、Cy、Cz 与 n 进入非线性 lobe 函数,线性插值可能产生视觉上不连续的峰值、sparkle 或错误各向异性。point sampling 是保守起点,代价是 zoom 或 mip 过渡时可能显得块状。

有三种常见取舍:

  • point sample:保持每个 texel 的参数离散性,减少参数被混合到非法范围的机会;需要处理纹理放大和 mip 选择。
  • 浮点参数纹理:减少 scale-bias 和八位量化,适合精细材料;带宽、缓存占用和平台支持会增加成本。
  • 受控滤波:如果必须平滑参数,应在 lobe 评估之前做约束、重归一化或对 log-sharpness 等更合适的量进行滤波,并用极端 C 值测试。

不要只看高光中心截图。应同时检查镜头移动、纹理接缝、远近 mip、斜视角和各向异性方向;一个在静态近景看似准确的压缩策略,可能在动画中产生跳变。

4. 用预卷积环境图服务很多空间 BRDF

离散光只需要对有限个 light 评估每个 lobe;环境光则需要对整个入射半球积分。如果每个 texel 都有自己的 BRDF,为每个 BRDF 单独卷积环境图会不可行。 的策略是预先卷积若干固定 sharpness 的 kernel,再让运行时用方向与 n 选择合适的层。

最简单的组织方式是把不同 n 的卷积结果放入 cube mipmap:较粗层保存宽 lobe,较细层保存尖 lobe。n 作为 LOD 的依据,lobe 的峰值方向 p(wr) 作为 cube lookup 方向;最后用 lobe albedo 和适当的 irradiance factor 组合结果。diffuse 环境项可以单独用法线方向索引的预卷积图。

environment map:预卷积方向与 sharpnessincident Li(wi)all incident directionsconvolven = 0n = 16n = 64n = 256runtimep(wr)LOD ← none lookup× lobe albedo把复杂的全方向积分换成可控的预处理与近似
预卷积把运行时对所有入射方向的积分转成一次环境图 lookup;n 越大,lobe 越尖,通常需要更细的 mip 层。

预卷积的核心近似是把入射积分中的权重集中到 lobe 峰值附近。它减少了运行时成本,但要记住三点:卷积层只覆盖预设 n 集合,峰值方向需要从 local frame 正确变到 world space,且归一化与 irradiance falloff 不能被误当成同一个量。对 HDR 环境图,还要保留足够的动态范围,例如使用 RGBE 或浮点路径。

卷积本身也可能是离线成本。一个朴素实现遍历 cube map 每个面、每个 texel 和每个 incident direction,计算 kernel weight 后归一化;真正的工具链可以加入重要性采样、并行生成、缓存和质量分档,但必须用同一套 BRDF 参数验证离线与运行时方向约定。

5. 动手实验:在表现力与带宽之间选方案

先预测四个变化:增加 lobe 数量会提高材质表现力但带来更多纹理读取与 shader 工作;增大 n 会收窄高光并要求更细的预卷积层;把各向异性推离零会让峰值沿切线框架移动;把 shape 参数改成 linear filtering 可能让尖锐 lobe 出现 sparkle。

Spatial BRDF Lab

先猜:sharpness 增大,lobe 和纹理过滤会怎样?

可交互
preconvolved environmentgloss 0.64lobe 1lobe 2width 8.0 · direction shift 0.30 · artifact 0.19n 选择预卷积环境图的 LOD

观察:增加 lobes 能表达更多材质行为但增加纹理和 shader 成本;n 越大高光越尖,非线性 shape 参数用 linear filtering 更容易 sparkle;environment 模式把积分成本换成预卷积与 LOD。

实验图是确定性的示意模型,不代替 GPU profile。把它对应到实际材质时,至少记录 lobe 数量、参数纹理格式、采样方式、环境图卷积层和目标分辨率;这样当画质或带宽预算改变时,才知道要牺牲哪一层近似。

小结:让每个表面点拥有适度复杂的反射

  • spatial BRDF 把纹理的空间变化与 BRDF 的角度变化组合起来,让不同 texel 拥有不同的反射模型。
  • Lafortune representation 用少量 specular lobe 近似 diffuse 之外的复杂反射,albedo、C 系数和 n 分别控制能量、方向和宽窄。
  • local surface coordinates 让各向异性方向进入 lobe 评估;坐标变换和归一化错误会直接表现为高光方向错误。
  • 参数纹理需要处理负值范围、量化和非线性采样;point sampling 是保守起点,浮点纹理和受控滤波是更高成本选项。
  • preconvolved environment map 把环境积分换成方向与 sharpness lookup,必须同时验证卷积层、LOD、HDR 动态范围和 irradiance 近似。

练习

问题 1|改 Demo 代码 一个材质当前只有一个 specular lobe,n=16。请把它扩展为两个 lobe:第一个保持宽而弱,第二个变为窄而亮;说明你会新增哪些纹理参数,以及如何避免两个 lobe 的能量被重复归一化。

问题 2|推导题 某个 texel 的编码 Cx 为 160,采用 value = encoded / 96 - 128 / 96 解码。计算 Cx,并判断它相对于零是正还是负;再说明如果误省略 bias 会怎样。

问题 3|独立实现题 为一面具有木纹各向异性的墙面选择离散光、预卷积环境光或混合方案。要求镜头移动稳定、近景高光有方向、远景带宽可控,请写出你的参数纹理和验证计划。

名词解释

本章出现的专业名词,用大白话再讲一遍。

spatial BRDF
将表面空间变化与 BRDF 角度变化组合起来的反射表示。
BRDF
描述固定表面点在入射方向和出射方向之间反射比例的函数。
Lafortune representation
用 diffuse 与多个可调 specular lobe 近似空间 BRDF 的参数化表示。
specular lobe
表示局部镜面峰值的高光项,包含 albedo、shape 和 sharpness。
local surface coordinates
由切线、双切线和法线构成,用于在材质局部方向中评估 BRDF 的坐标系。
preconvolved environment map
把环境辐射按反射 kernel 预先积分,运行时按方向和 sharpness 查表的环境纹理。

资料与写作方式声明

本章以GPU Gems 1 · Chapter 18. Spatial BRDFs公开完整正文核定章节范围、事实坐标与时代语境,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…