中EN
概念页

球面几何与方向参数化

Spherical Geometry & Direction Parameterizations

渲染中大量计算发生在单位球面上:方向就是球面上的点,一组方向就是球面上的一块区域。本页按 PBRT 4e 3.8 节整理立体角、球面多边形面积、三种球面参数化(球坐标、八面体编码、等面积映射)以及用于剔除光源的方向锥,并附原书一处公式问题。

立体角(3.8.1)

平面角是物体投影到单位圆上的弧长(整圆 2π2\pi rad);立体角 (Solid Angle) 是物体投影到单位球面上的面积,单位球面度 (sr),整个球面 4π4\pi sr,半球 2π2\pi sr。微分立体角 dωd\omega 就是单位球面上的面积测度,所以对方向积分就是在球面上积分(辐射度量中的用法见 辐射度量学与光度学)。

球面多边形与球面三角形面积(3.8.2)

平面多边形投影到单位球上得到球面多边形:顶点是指向原多边形顶点的单位向量,边是过球心和两顶点的平面与球面相交得到的大圆弧(两点间的球面最短路径)。顶点处的角是两条边所在平面的二面角。球面三角形三个角之和不是 π\pi,而是 π+A\pi+A,由 Girard 定理:

A=α+β+γ−π(式 3.5)A=\alpha+\beta+\gamma-\pi\quad(\text{式 3.5})

直接实现要调用多次反三角函数,还有浮点相消误差。更快更准的是 Van Oosterom & Strackee (1983) 的公式:

tan⁡A2=a⋅(b×c)1+(a⋅b)+(a⋅c)+(b⋅c)(式 3.6)\tan\frac A2=\frac{a\cdot(b\times c)}{1+(a\cdot b)+(a\cdot c)+(b\cdot c)}\quad(\text{式 3.6})

本页用随机球面三角形验算:取分子绝对值、结果为负时加 π\pi(即用 atan2),与 Girard 公式一致到 10−1510^{-15}。球面四边形面积为 α+β+γ+δ−2π\alpha+\beta+\gamma+\delta-2\pi。用途:求面光源(多边形)对一点所张的立体角,见 面光源。

球坐标(3.8.3)

x=rsin⁡θcos⁡ϕ,y=rsin⁡θsin⁡ϕ,z=rcos⁡θ(式 3.7)x=r\sin\theta\cos\phi,\quad y=r\sin\theta\sin\phi,\quad z=r\cos\theta\quad(\text{式 3.7}) θ=arccos⁡z,ϕ=arctan⁡yx(式 3.8)\theta=\arccos z,\qquad \phi=\arctan\frac yx\quad(\text{式 3.8})

  • SphericalDirection() 接收 sin⁡θ,cos⁡θ\sin\theta,\cos\theta 而不是 θ\theta,因为调用方通常已经有了;SphericalTheta() 用 SafeACos 防止 ∣z∣|z| 因舍入略大于 1;SphericalPhi() 把 atan2 的结果调整到 [0,2π][0,2\pi]。
  • 在法线对齐 zz 轴的局部坐标里,cos⁡θ=ωz\cos\theta=\omega_z;sin⁡2θ=max⁡(0,1−cos⁡2θ)\sin^2\theta=\max(0,1-\cos^2\theta)(防止舍入出负数);cos⁡ϕ=x/sin⁡θ\cos\phi=x/\sin\theta,sin⁡ϕ=y/sin⁡θ\sin\phi=y/\sin\theta,全都不需要反三角函数。BSDF 代码大量依赖这些函数。
  • 球坐标就是经纬度 (equirectangular) 映射,两极畸变大,不适合存规则采样的数据(与 环境贴图 中经纬度贴图的缺点一致)。

八面体编码(3.8.3)

Vector3f 存单位向量要 12 字节,而且能表示任意长度,大部分取值浪费;球坐标要三角函数,并且精度集中在两极。OctahedralVector 用 4 字节(两个 16 位整数)存单位向量,精度分布均匀,所有 32 位取值都对应合法单位向量:

  1. 除以 L1 范数 ∣vx∣+∣vy∣+∣vz∣|v_x|+|v_y|+|v_z| 投影到八面体表面;
  2. 上半球 (vz≥0v_z\ge0) 直接取 (x,y)(x,y);下半球用 x′=(1−∣vy∣) sign(vx)x'=(1-|v_y|)\,\mathrm{sign}(v_x)、y′=(1−∣vx∣) sign(vy)y'=(1-|v_x|)\,\mathrm{sign}(v_y) 把四个三角形翻折到正方形外角,整个过程不需要分支;
  3. 把 [−1,1][-1,1] 量化为 16 位:round(clamp((f+1)/2,0,1)⋅65535)\mathrm{round}\big(\mathrm{clamp}((f+1)/2,0,1)\cdot65535\big)。解码反向执行再归一化。

本页按书中代码对 20 万个随机方向编码再解码,最大角误差约 0.0037°0.0037°,平均约 0.0013°0.0013°。Meyer 等 (2010) 指出该表示用 52 位时精度与归一化的 Vector3f 相当;方法源自 Praun & Hoppe (2003),pbrt 还采用了 Cigolle 等 (2014) 的改进。实时渲染里同一方法用于 G-buffer 法线和顶点法线压缩,见 顶点压缩与精度;RTR4 给出的八面体环境贴图公式(见 环境贴图)以 yy 为"上"轴、输出 [0,1][0,1] 纹理坐标,pbrt 以 zz 为上轴、输出 [−1,1]2[-1,1]^2,本质相同。

等面积映射(3.8.3)

用于在球面上制表(如环境光的采样分布):连续、畸变较低,且每个存储值代表相同的立体角。它把八面体映射与 Shirley–Chiu 同心圆盘映射的变体结合 (Clarberg 2008):

  • 正方形第一扇区(u≥0u\ge0、u−∣v∣≥0u-|v|\ge0)映射到圆盘:r=ur=u,ϕ=π4vu\phi=\frac\pi4\frac vu,ϕ∈[−π/4,π/4]\phi\in[-\pi/4,\pi/4];其余三个扇区类似。
  • 圆盘到上半球: x=cos⁡ϕ r2−r2,y=sin⁡ϕ r2−r2,z=1−r2(式 3.9)x=\cos\phi\,r\sqrt{2-r^2},\quad y=\sin\phi\,r\sqrt{2-r^2},\quad z=1-r^2\quad(\text{式 3.9}) 本页数值验证两步都保面积:正方形到圆盘的面积放大率恒为 π/4\pi/4,圆盘到半球恒为 2(半球面积 2π2\pi 除以圆盘面积 π\pi)。
  • 扩展到整个球面:先做八面体映射;上半球对内部正方形套用式 3.9(要补偿 45°45° 旋转);下半球先沿所在象限的对角线镜像,再套映射并把 zz 取负。pbrt 的实现取 ∣u∣,∣v∣|u|,|v| 把四个象限折到第一象限,用到对角线 u+v=1u+v=1 的有符号距离求 rr 与上下半球,最后用 copysign 恢复 cos⁡ϕ,sin⁡ϕ\cos\phi,\sin\phi 的符号,全程无分支(对 GPU 有利)。WrapEqualAreaSquare() 处理双线性插值时略出界的坐标。

方向锥(3.8.4)

DirectionCone 用中心方向 ww 和扩展角的余弦 cosTheta 表示一组方向的包围锥(存余弦是为了用点积代替三角函数);空锥用 cosTheta = ∞ 表示。用途:光源只朝某些方向发光时,可剔除肯定照不到的着色点(第 12 章 BVH 光源采样)。

  • 包含测试:cos⁡∠(v,w)≥\cos\angle(v,w)\ge cosTheta。
  • BoundSubtendedDirections(b, p):先求包围盒的包围球,pp 在球内则返回整个球面(pp 可能在球内却在盒外,此时过于保守,习题要求改进);否则中心方向指向球心,sin⁡θ=r/d\sin\theta=r/d,cos⁡θ=1−sin⁡2θ\cos\theta=\sqrt{1-\sin^2\theta}。
  • 两锥合并:θa,θb\theta_a,\theta_b 为扩展角,θd\theta_d 为两轴夹角。若 min⁡(θd+θb,π)≤θa\min(\theta_d+\theta_b,\pi)\le\theta_a 则 aa 已包含 bb;否则新扩展角 θo=(θa+θd+θb)/2\theta_o=(\theta_a+\theta_d+\theta_b)/2(≥π\ge\pi 则返回整个球面),新轴由 a.wa.w 绕 a.w×b.wa.w\times b.w 旋转 θo−θa\theta_o-\theta_a 得到;叉积为零(两轴相反)时返回整个球面。不能直接用两轴的平均方向作为新轴,否则需要更大的扩展角。

原书问题

位置原书说法核对结果
3.8.4 两锥合并用平均方向作轴"需要扩展角 θd/2+max⁡(2θa,2θb)\theta_d/2+\max(2\theta_a,2\theta_b)"(解码在线版 SVG 字形确认绘出的就是 2θa2\theta_a、2θb2\theta_b)平均轴与两条原轴各成 θd/2\theta_d/2,要包住锥 aa 只需 θd/2+θa\theta_d/2+\theta_a,所以应为 θd/2+max⁡(θa,θb)\theta_d/2+\max(\theta_a,\theta_b)。本页对 2000 组随机锥数值验证此式与实际所需角度一致(误差约 10−1510^{-15})。"它不小于 θo\theta_o"的结论不受影响,因为 max⁡(θa,θb)≥(θa+θb)/2\max(\theta_a,\theta_b)\ge(\theta_a+\theta_b)/2。来源:https://pbr-book.org/4ed/Geometry_and_Transformations/Spherical_Geometry (3.8.4 节)及本页推导
式 3.6在线版曾把分子显示为 a⋅(b×b)a\cdot(b\times b)已修正,当前版本为 a⋅(b×c)a\cdot(b\times c)(pbr-book-website issue #21 已关闭,#17 仍为 open 状态但内容相同)

取舍

参数化优点缺点典型用途
球坐标 / 经纬度直观,BSDF 局部坐标中 cos⁡θ=ωz\cos\theta=\omega_z 等很便宜两极畸变、精度不均,转换需三角函数解析推导、BSDF 角度计算
八面体4 字节、精度均匀、编解码只用加减和符号不保面积,不适合直接计算大量单位向量的存储、法线压缩
等面积每个纹素立体角相同、连续、低畸变实现较复杂球面函数制表与采样分布
  1. PBRT 4e source excerpt: chapter 03 (Geometry and Transformations)
  2. Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 3 章 3.8 节,pbr-book.org/4ed/Geometry_and_Transformations

相关页面

图形学辐射度量学与光度学Radiometry & Photometry辐射度量学精确度量电磁辐射,是基于物理渲染的第一步;光度学用人眼灵敏度对它加权。渲染中最重要的量是辐射亮度 L:眼睛和相机测的就是它,着色方程要算的也是沿视线的辐射亮度。图形学面光源Area Lights真实光源从来不是点。面光源要求对光源所张立体角 \omegal 积分 BRDF,实时渲染倾向于用闭式解或近似而不是多条光线取平均。主要做法有:Lambert 表面的矢量辐照度与包裹光照、光泽表面的粗糙度修正和"最具代表性的点",以及最准确的线性变换余弦 (LTC)。图形学环境贴图Environment Mapping把球面函数记录在一张或多张图像里、用纹理查找来解码,就是环境贴图。它比其他球面表示占内存多,但解码简单快速,能表达任意高频和任意动态范围。最基本的用法是反射贴图:假设镜面 BRDF,用反射视线向量查表。本页比较经纬度、球面、立方体、双抛物面和八面体等投影。图形学顶点压缩与精度Vertex Compression & Precision网格数据像纹理一样可以压缩:传输用的整体压缩(Draco 等)一次性解码,渲染用的定长压缩让顶点着色器在 GPU 上逐顶点解码,从而降低内存、带宽并改善缓存。另一面是精度问题:大世界中单一坐标系会让远离原点的物体抖动,需要相对相机的变换或分段原点。游戏数学包围体构建Bounding Volume Construction紧凑的包围体能降低相交测试成本:光线击中凸体的概率与其表面积成正比,拒绝永远不比相交慢,所以求交加速应最小化 BV 表面积;碰撞检测则常最小化体积。本页讲 AABB/k-DOP、包围球(AABB 法、Ritter 近似法、Welzl 最优法)、凸包(Quickhull)以及 OBB(PCA 法、数值最小化、Larsson 与 Källberg 的近优线性算法)的构建方法与取舍。游戏数学点与向量运算Points & Vector Operations游戏程序员最常用的数学是三维向量与矩阵(三维线性代数)。本页按 GEA 第 5 章整理点与向量的基础:坐标系与手性、点与方向的区别、标量乘与 Hadamard 积、加减、模长与归一化、点积与投影、叉积、伪向量与外代数,以及线性插值 (lerp)。贯穿全章的两条经验是:能在二维里想清楚的问题先在二维里想,以及能不开方就不开方。游戏数学投影矩阵Projection Matrix投影矩阵把视景体变换到规范视体(OpenGL 为 [-1,1]^3,DirectX 的 z 为 [0,1]),在那里裁剪更高效。正交投影保持平行线平行、物体大小与距离无关;透视投影让远处变小,产生的深度与观察深度成反比,近平面位置和"反向 z"决定深度精度。游戏数学形状采样Shape Sampling把形状当作面光源时,需要在形状上采样点。最简单的是按面积均匀采样再把 PDF 换算成立体角;更好的是只在参考点看得到的立体角内均匀采样,消掉 1/r^2 和背面带来的方差。本页按 PBRT 第 4 版第 6 章整理各种形状的采样公式及其推导要点。图形学纹理映射管线Texturing Pipeline纹理通过修改着色方程中使用的值(颜色、粗糙度、法线等)来高效表现表面材质的变化。通用纹理管线是:空间位置 → 投影函数得到纹理坐标 → 对应函数变换到纹理空间 → 取值 → 值变换 → 用于着色。本页还整理纹理坐标约定、纹理表示方式、程序纹理、纹理动画、材质贴图、alpha 贴图和纹理光源。图形学基于图像的光照Image-Based Lighting用纹理数据(通常是相机拍摄的 360° HDR 全景)照明场景称为基于图像的光照。实时引擎常用预滤波的高光立方体贴图(配合 split-sum 近似)处理高光,用辐照度环境贴图或球谐系数处理漫反射。它们只依赖少量光照图元而不需要知道场景其他表面,因此仍属局部光照。图形学多光源采样与光源 BVHMany-Light Sampling & Light BVH场景有成百上千个光源时,不可能在每个着色点对所有光源做直接光照。利用求和的蒙特卡洛估计 \sumi fi\approx fj/p(j),每次只随机选一个(或几个)光源并除以其概率即可无偏。选择概率可以均匀、按功率,或随着色点变化——后者需要一棵把光源聚合起来的层次结构(光源 BVH)。本页对应 PBRT 4e 12.6 节,并对照实时渲染的分簇/分块光源剔除。

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原