曲线与曲面 (Curves and Curved Surfaces)
"Where there is matter, there is geometry.” —— Johannes Kepler
这句话点明了本章的核心:在计算机图形中,万物皆由几何构成。虽然三角形是硬件渲染的基本图元,但直接使用曲线和曲面来描述模型,能在实时渲染中带来诸多优势。
核心优势:
- 紧凑表示: 用数学方程描述远比存储大量三角形顶点更节省内存和带宽。
- 可伸缩性: 同一个曲面可以根据需要(如距离远近)动态生成不同数量的三角形,是实现**动态LOD (Level of Detail)**的天然方案。
- 平滑与连续性: 能创造出比低多边形网格更平滑的表面和轮廓,提升视觉质量。
- 动画与物理: 对少量控制点进行操作即可实现平滑的形变动画,同时也能进行更高效、精确的碰撞检测。
17.1 参数化曲线 (Parametric Curves)
核心观点: 参数化曲线是使用一个单一参数(通常是 t)来描述空间中一个点的轨迹的函数,写作 。它在实时渲染中被广泛应用于动画路径(如相机、物体运动)、程序化生成(如毛发、藤蔓)等领域。
- 参数 (Parameter): 一个变量,通常用 t 表示,它在某个定义域 (domain)(例如 [0, 1])内连续变化。
- 函数 : 对于定义域中的每一个 t值,这个函数都会返回一个三维空间中的点坐标(x, y, z)。
- 连续性: 当参数 t发生微小变化时,点 在空间中的位置也只会发生微小变化,从而形成一条连续的曲线。
17.1.1 Bézier 曲线 (Bézier Curves)
核心观点: Bézier 曲线是一种通过一组控制点 (Control Points) 来直观定义曲线形状的参数化方法。曲线并不会穿过所有的控制点,而是被它们“牵引”成型,其形状完全包含在这些控制点的凸包 (Convex Hull) 内。
使用 Bernstein 多项式的 Bézier 曲线
Bézier 曲线的数学定义依赖于 Bernstein 基多项式 (Bernstein basis polynomials)。对于一个 n 次(degree n)的 Bézier 曲线,它由 n+1 个控制点 定义。
核心公式:
一个 n 次 Bézier 曲线的表达式为:
其中, 是第 i 个控制点,而  是 Bernstein 基函数:
其中  是二项式系数,即 。
关键特性:
- 端点插值: 曲线必定会穿过起始控制点 () 和终点控制点 () 。
- 凸包特性 (Convex Hull Property): 整条曲线都严格包含在由其所有控制点构成的凸包之内。这是一个非常有用的性质,可以用于快速的碰撞剔除。
- 切线特性: 曲线在起点的切线方向是 ,在终点的切线方向是 。
在实时渲染中,最常用的是三次 Bézier 曲线 (Cubic Bézier Curve),它由4个控制点定义,在性能和表现力之间取得了很好的平衡。
有理 Bézier 曲线 (Rational Bézier Curves)
核心观点: 通过为每个控制点引入一个权重 (weight) ,有理 Bézier 曲线可以表示更广泛的曲线类型,包括圆、椭圆、抛物线等二次曲线,而标准的 Bézier 曲线无法精确表示这些形状。
核心公式:
- 当所有权重 都为1时,它就退化为标准的 Bézier 曲线。
- 增加某个控制点的权重会使曲线向该点“拉近”。
17.1.2 GPU 上的有界 Bézier 曲线 (GPU-based Bounded Bézier Curves)
核心观点: 现代 GPU 提供了直接在硬件上处理和渲染曲线的能力,主要通过曲面细分着色器 (Tessellation Shaders) 来实现。CPU 只需要提交少量的控制点,GPU 会根据需要动态地将曲线细分成一系列线段进行渲染。
这种方法的优势是极大地降低了 CPU 到 GPU 的数据传输量,并且可以根据视点距离等因素自适应地调整细分级别,实现高效的 LOD。
17.1.3 曲线的连续性与分段 Bézier 曲线 (Curve Continuity and Piecewise Bézier Curves)
核心观点: 使用高阶(大量控制点)的单一 Bézier 曲线来描述复杂形状是不切实际的,因为控制点的任何微小移动都可能影响整条曲线(缺乏局部控制性),且计算成本高昂。实际应用中,我们通常将多段低阶(如三次)的 Bézier 曲线连接起来,形成一条分段 Bézier 曲线 (Piecewise Bézier Curve)。
为了让连接处看起来平滑,我们需要定义不同级别的连续性 (Continuity):
- 
C⁰ 连续 (几何连续性): 两段曲线的连接点是同一个点。这是最基础的连续,但连接处可能有尖角。 - 实现: 第一段曲线的终点 与第二段曲线的起点 是同一点。()
 
- 
C¹ 连续 (参数连续性): 在连接点处,两段曲线不仅位置相同,切线向量也相同(方向和大小都相同)。这保证了连接处的平滑过渡。 - 实现: 除了满足 C⁰ 条件,还需要第一段曲线的倒数第二个控制点、连接点、第二段曲线的第二个控制点三点共线,且连接点位于中点。即 。
 
17.1.4 三次 Hermite 插值 (Cubic Hermite Interpolation)
核心观点: Hermite 样条是另一种定义三次曲线的方式,它不直接使用中间的控制点,而是使用曲线的两个端点和两个端点处的切线向量来定义。这种方式更符合某些应用场景的直觉,比如路径动画,我们关心的是物体从哪里出发、到哪里去,以及出发和到达时的方向。
核心输入:
- 起点
- 终点
- 起点切线
- 终点切线
核心公式:
- 关联: Hermite 样条和 Bézier 样条可以相互转换。给定 Hermite 的端点和切线,可以计算出等价的 Bézier 曲线的4个控制点。
17.1.5 Kochanek-Bartels 曲线
核心观点: 这是对 Hermite 曲线的扩展,为动画师提供了更直观的控制。它在 Hermite 样条的基础上,为每个关键点(端点)引入了三个参数,用以调整插值曲线的形状。
- Tension (张力): 控制曲线的“松紧”程度。正值使曲线更紧绷,负值使其更松弛。
- Bias (偏置): 控制曲线在关键点附近的“偏向”。正值使曲线在进入关键点前更弯曲,负值则在离开后更弯曲。
- Continuity (连续性): 控制曲线在关键点处的平滑度。可以用来刻意制造尖角或不连续的效果。
这个曲线也被称为 TCB 样条 (Tension, Continuity, Bias)。
17.1.6 B-样条 (B-Splines)
核心观点: B-样条是 Bézier 曲线的泛化形式,它提供了更强的局部控制性 (Local Control)。移动一个 B-样条的控制点只会影响曲线的一部分,而不是整条曲线。这使得它在交互式建模中非常强大。
关键特性:
- 局部控制: 归功于其基函数只在有限的参数范围内为非零。
- 阶数与控制点数解耦: B-样条的阶数(degree)可以独立于控制点的数量来选择。
- 节点向量 (Knot Vector): B-样条引入了一个名为节点向量的非递减序列,它控制着每个控制点在哪个参数范围 t内对曲线产生影响。通过调整节点向量,可以在曲线的不同位置实现不同程度的连续性,甚至可以创建尖角。
B-样条的数学形式比 Bézier 曲线更复杂,但由于其强大的灵活性和控制力,它在工业设计和建模软件中被广泛使用。在实时渲染中,它通常被预先计算(tessellate)成三角形网格。
17.1.1 Bézier 曲线 (Bézier Curves)
从线性插值说起
核心观点: 最基础的插值方法是线性插值 (Linear Interpolation, Lerp),它可以在两点之间创建一条直线。但当我们需要连接多个点来形成一条路径时,线性插值会在连接处产生不平滑的“尖角”或“抖动”,这在追求平滑运动的图形应用中是不可接受的。
核心公式 (Lerp): 在点 和 之间进行线性插值,参数 :
- 当 ,点在 。
- 当 ,点在 。
Bézier 曲线的几何构造:de Casteljau 算法
核心观点: Bézier 曲线的本质思想是对线性插值进行递归或重复的运用。这个构造过程被称为 de Casteljau 算法,它通过引入额外的控制点 (Control Points) 来“引导”曲线的形状,从而产生平滑的路径。
算法步骤 (以三个控制点 为例):
- 在第一层,使用相同的参数 t分别对线段 和 进行线性插值,得到两个新的中间点。
- 在第二层,对上一层产生的新点  和  再次进行线性插值,得到最终在曲线上的点 。
这个递归过程可以推广到任意 个控制点,最终形成一条 次的 Bézier 曲线。
递归公式: 初始控制点为 。对于第 轮插值( 从 1 到 ): 最终曲线上的点是金字塔的顶点 。
Bézier 曲线的代数形式:Bernstein 多项式
核心观点: 尽管 de Casteljau 算法在几何上很直观,但在计算上效率不高。Bézier 曲线有一个等价的、更直接的代数表达式,称为 Bernstein 形式。它将曲线上的点表示为所有控制点的加权平均,而权重就是 Bernstein 多项式。
核心公式: 一条由 个控制点 定义的 次 Bézier 曲线为: 这里的 就是 Bernstein 基函数 或 混合函数 (Blending Functions): 其中 是二项式系数 。
常用示例 (三次 Bézier 曲线, n=3): 由4个控制点定义,其展开式为:
关键特性:
- 端点插值: 曲线一定通过起始点 和终点 。
- 切线特性: 曲线在起点的切线方向由 决定,在终点的切线方向由 决定。
- 凸包特性 (Convex Hull Property): 整条曲线都严格包含在其控制点构成的凸包之内。这个特性非常重要,可以用于做碰撞检测的快速剔除。
- 变换不变性: 对曲线进行仿射变换(如旋转、缩放、平移)等同于先对控制点进行变换,再生成曲线。由于控制点数量远少于曲线上采样的点,这大大提高了效率。
- 导数: Bézier 曲线的导数仍然是一条 Bézier 曲线,但阶数会降低一阶。
有理 Bézier 曲线 (Rational Bézier Curves)
核心观点: 标准 Bézier 曲线无法精确表示一些常见的几何形状(如圆、椭圆)。有理 Bézier 曲线通过为每个控制点 引入一个额外的权重 (weight) 来解决这个问题,提供了更高的灵活性。
核心公式:
- 当所有权重 时,它就退化为标准的 Bézier 曲线。
- 直观效果: 增加某个控制点的权重,会使曲线被更强地“拉向”该控制点。
17.1.2 GPU 上的有界 Bézier 曲线
核心观点: 我们可以利用现代 GPU 的可编程像素着色器,以一种非常高效的方式直接渲染有界 Bézier 曲线 (bounded Bézier curve)。这种技术的核心思想是将曲线的数学定义转换成一个隐式方程,然后在像素级别判断一个点是否位于曲线所包围的区域内。
这种方法尤其适用于字体渲染和 2D 矢量图形,因为它不依赖于生成大量三角形,而是直接在屏幕空间进行解析计算。
二次 Bézier 曲线的实现方法:
- 
设置: 将曲线的三个控制点 作为顶点,绘制一个三角形。 
- 
纹理坐标技巧: 为这三个顶点分配特殊的纹理坐标 (u, v):
- 
像素着色器: 在渲染这个三角形时,GPU 会自动插值每个像素的 (u, v)坐标。我们在像素着色器中,对每个像素执行一个简单的测试:核心公式 (隐式方程): 
- 
判断: - 如果 ,则该像素位于曲线内部,保留该像素。
- 如果 ,则该像素位于曲线外部,丢弃 (discard) 该像素。
 
关键优势:
- 效率高: CPU 只需发送 3 个顶点,所有计算都在 GPU 上并行完成。
- 质量好: 这种方法可以很自然地扩展,以实现高质量的抗锯齿效果。
- 透视正确性: 即使在三维空间中对这个三角形进行透视投影,渲染出的曲线依然是正确的。
17.1.3 曲线的连续性与分段 Bézier 曲线
核心观点: 在实际应用中,我们几乎不会用一个高阶的 Bézier 曲线来描述复杂形状。取而代之的是,将多条低阶(通常是三次)曲线段连接起来,形成一条分段 Bézier 曲线 (Piecewise Bézier Curve)。为了使连接处看起来平滑无痕,我们必须处理好连续性 (Continuity) 问题。
连续性级别:
- 
C⁰ 连续 (位置连续性): - 定义: 两段曲线在关节 (joint) 处共享同一个点。
- 实现: 第一段曲线的终点 就是第二段曲线的起点 。
- 效果: 这是最弱的连续性,连接处通常会形成一个可见的尖角。
 
- 
G¹ 连续 (几何连续性): - 定义: 在关节处,两段曲线的切线方向相同。即切线向量是共线且同向的,但它们的长度(速率)可以不同。
- 实现: 控制点 三点共线。
- 效果: 视觉上是平滑的,但如果一个物体沿着这条曲线运动,它的速度会在关节处发生突变。
 
- 
C¹ 连续 (参数连续性): - 定义: 这是更强的连续性。在关节处,两段曲线的一阶导数(切线向量)完全相等,无论方向还是长度。
- 实现: G¹ 条件必须满足,并且比例因子 c必须等于两段曲线的参数化区间的长度之比。假设第一段曲线的参数区间是 ,第二段是 ,那么: 如果参数化区间长度相等(例如都为1),则 ,意味着 。
- 效果: 形状和运动速度都实现了平滑过渡,是动画路径的理想选择。
 
参数重映射:
当处理分段曲线时,每一段 Bézier 曲线自身都定义在参数  上。为了在整条复合曲线上使用一个统一的参数(例如,时间),我们需要将全局参数映射到每个线段的局部 [0, 1] 区间。
17.1.4 三次 Hermite 插值 (Cubic Hermite Interpolation)
核心观点: Hermite 曲线提供了另一种定义三次曲线的方式,它比 Bézier 曲线在某些场景下更直观、更易于控制。它不是通过中间控制点来“拉扯”曲线,而是直接指定曲线的端点位置和端点切线。
核心输入:
- 起点:
- 终点:
- 起点切线:
- 终点切线:
核心公式:
- 公式中的四个多项式是 Hermite 混合函数,它们确保了曲线满足以下属性:
- (曲线穿过起点)
- (曲线穿过终点)
- (曲线在起点的切线等于 )
- (曲线在终点的切线等于 )
 
关键优势与应用:
- 直观控制: 对动画师和程序员来说,直接控制起点、终点和它们的切线比调整 Bézier 的中间控制点更符合直觉。
- 切线长度的影响: 切线向量的方向决定了曲线离开/进入端点的方向,而其长度则会影响曲线的“饱满”程度。切线越长,曲线会沿着切线方向延伸得更远,然后再弯曲向另一个端点。
- 应用: Hermite 样条非常适合用于创建路径动画、关键帧插值,以及程序化生成(如游戏中的毛发渲染)。
17.1.5 Kochanek-Bartels 曲线 (TCB 样条)
核心观点: 在连接多段 Hermite 曲线时,我们需要为每个内部点 定义一个切线 。Kochanek-Bartels 曲线提供了一种自动计算这些切线的强大方法,并且通过引入三个直观的参数,为动画师提供了对曲线形状的精细艺术控制。它本质上是 Hermite 曲线的一种自动化和扩展。
这种曲线也被称为 TCB 样条,因为它的三个核心控制参数是:Tension (张力), Continuity (连续性), 和 Bias (偏置)。
切线的计算基础: 在点 ,其切线被定义为前后两个**弦 (chord)**向量 和 的加权组合。TCB 参数就是用来调整这些权重的。
控制参数详解:
- 
Tension (张力 a):- 作用: 控制曲线在连接点处的“尖锐”或“松弛”程度。
- 效果:
- a > 0(高张力): 曲线被“拉紧”,在连接点附近更尖锐,更贴近控制点构成的折线。
- a = 0(默认): 标准的 Catmull-Rom 样条,效果自然。
- a < 0(低张力): 曲线更“松弛”,弧度更大,可能会远离控制点。
 
 
- 
Bias (偏置 b):- 作用: 控制曲线在连接点前后的“倾向性”。
- 效果:
- b > 0: 曲线在到达连接点之前就开始转弯,在离开之后弯曲较缓。
- b < 0: 曲线在到达连接点之前延伸较远,在离开之后才急剧转弯。
 
 
- 
Continuity (连续性 c):- 作用: 控制连接点处的平滑度。它通过将一个点的切线拆分为入射切线 (s_i) 和出射切线 (d_i) 来实现。
- 效果:
- c = 0(默认): 入射和出射切线相同,曲线是 连续的,非常平滑。
- c ≠ 0: 两侧切线不同,可以在连接点处刻意制造出尖角,实现从平滑过渡到折角的效果。
 
 
- 作用: 控制连接点处的平滑度。它通过将一个点的切线拆分为入射切线 (
核心公式 (组合 TCB): 在点 的出射切线 和入射切线 的计算公式如下:
- 注意: 从 到 的曲线段,使用的是出射切线 和下一段的入射切线 。
时间间隔校正: 上述公式假设每个曲线段的参数(如时间)间隔是相同的。如果时间间隔不同(例如,一个动画关键帧之间是1秒,下一段是3秒),则必须对切线长度进行缩放校正,以保证匀速运动的平滑性。
17.1.6 B-样条 (B-Splines)
核心观点: B-样条是 Bézier 曲线的一种泛化,它最大的优势在于局部控制性 (Local Control)。与 Bézier 曲线移动一个控制点会影响整条曲线不同,移动 B-样条的一个控制点只会影响其邻近的一小段曲线。
关键特性:
- 局部控制: 这是通过基函数 (Basis Functions) 实现的。每个基函数只在一个有限的参数范围内非零,因此每个控制点的影响范围是局部的。
- 连续性 (对于三次 B-样条): B-样条在连接处自动保证了高阶的连续性(三次 B-样条为 连续),这意味着不仅位置和切线平滑,曲率也是平滑变化的,效果非常理想。
- 不插值控制点: B-样条曲线通常不会穿过其控制点(除了特殊情况)。曲线是被控制点“群”平滑地“勾勒”出来的。
均匀三次 B-样条的构造:
- 滑动窗口: 任何一段 B-样条曲线段(例如在控制点 和 之间)都是由一个包含 4个相邻控制点 () 的“滑动窗口”决定的。
- 基函数: 它的三次基函数 是一个分段定义的光滑“钟形”曲线。
核心公式 (计算曲线上一点):
对于参数 (其中 i 是整数部分, 是小数部分),曲线上的一点  由以下公式给出:
其中, 是从基函数  推导出的四个混合权重。
总结: B-样条因其强大的局部控制性和内建的平滑性,成为专业建模软件(如 Maya, Rhino)中的首选曲线类型。在实时渲染中,它们通常被预先处理(Tessellation)成三角形网格,但其紧凑的表示和可编辑性在开发流程中极具价值。
17.2 参数化曲面 (Parametric Surfaces)
核心观点: 参数化曲面是参数化曲线从一维到二维的自然延伸。我们不再使用单个参数 t 来定义一条线,而是使用**两个参数(通常是 u 和 v)**来描述一个面上的任意点,写作 。
在实时渲染中,直接使用参数化曲面来建模,相比于传统的静态高精度三角形网格,具有显著优势:
- 紧凑表示: 仅需存储少量的控制点 (Control Points) 即可定义一个复杂、平滑的曲面,极大节省了内存和存储空间。
- 可伸缩性 (LOD): 曲面可以根据需要(如视距、屏幕空间大小)被细分 (Tessellation) 成任意数量的三角形。这使得参数化曲面成为实现动态细节层次 (Level of Detail) 的理想选择。
- 动画效率: 对少量控制点进行动画操作,远比操作一个包含成千上万个顶点的密集网格要高效得多。
17.2.1 Bézier 面片 (Bézier Patches)
核心观点: Bézier 面片(也称张量积 Bézier 曲面, Tensor-Product Bézier Surface)是将一维 Bézier 曲线的思想扩展到二维曲面的直接结果。它的构造基础是从线性插值扩展到了双线性插值 (Bilinear Interpolation)。
从双线性插值开始
双线性插值是在一个由四个点 定义的四边形区域内进行插值。
- 首先,沿着 u方向进行两次独立的线性插值:
- 然后,用得到的两个新点,沿着 v方向再进行一次线性插值:
核心公式 (双线性插值): 展开后,曲面上任意一点 的计算公式为:
- 定义域: 参数 的取值范围通常是 ,构成一个矩形的面片 (Patch)。
推广到 Bézier 面片
正如 Bézier 曲线是对线性插值的重复,Bézier 面片就是对双线性插值的重复。它由一个 的控制点网格 定义。
两种等价的定义方式:
- de Casteljau 算法 (几何构造): 通过递归地对 的控制点组进行双线性插值,最终收敛到曲面上的一个点。
- Bernstein 形式 (代数公式): 这是更直接的计算方法,将曲面点表示为所有控制点的加权和。
核心公式 (Bernstein 形式):
- 这里的  和  分别是 u和v方向上的一维 Bernstein 基函数。
- 这清晰地展示了其“张量积”的本质:一个方向上的基函数与另一个方向上的基函数相乘,作为每个控制点的权重。
另一种理解方式:“曲线的曲线” 我们可以将上述公式理解为: 其中,每一个 本身就是一条 Bézier 曲线。
- 直观解释: 想象有一组并排的 Bézier 曲线(由每一列控制点定义)。Bézier 面片就是在这些并排曲线上,再构造出一条横跨它们的“超级”Bézier 曲线。
Bézier 面片的重要属性
- 插值: 曲面必定穿过其四个角落的控制点 ()。
- 边界: 曲面的四条边界本身就是由边界控制点定义的 Bézier 曲线。
- 凸包特性: 整个 Bézier 面片完全包含在其所有控制点构成的凸包 (Convex Hull) 内。
- 切线与法线:
- 可以通过对  分别求关于 u和v的偏导数 和 ,来得到曲面在该点的两个切线向量。
- 这两个切线向量的叉积,即可得到该点的法线向量 ,这对于光照计算至关重要。
 
- 可以通过对  分别求关于 
有理 Bézier 面片 (Rational Bézier Patches)
核心观点: 与曲线类似,通过为每个控制点 引入一个权重 ,可以构造出有理 Bézier 面片。这提供了更强的塑形能力,能够精确表示二次曲面(如球体、圆柱、圆锥等),而标准 Bézier 面片无法做到。
核心公式:
17.2.2 Bézier 三角形 (Bézier Triangles)
核心观点: Bézier 三角形是 Bézier 曲面的一种形式,其定义域是一个三角形而非矩形。这使得它能与传统的三角形网格无缝集成,是将低多边形网格升级为平滑曲面的关键技术,如著名的 PN 三角形和 Phong 曲面细分算法的基础。
控制点布局:
- 一个 n次的 Bézier 三角形,其控制点 排列在一个三角形的栅格中。
- 索引规则: 控制点的三个下标 i, j, k必须满足 且 。
- 控制点总数: 。
构造方法:
Bézier 三角形的插值基础不再是简单的双线性插值,而是重心坐标 (Barycentric Coordinates)。对于一个由 (u, v) 定义的点,其在三角形内的位置由三个权重  决定。
- 
de Casteljau 算法 (几何构造): 通过递归地使用重心坐标对相邻的三个控制点进行插值,最终收敛到曲面上的一点。 核心公式 (de Casteljau for Triangles): 
- 
Bernstein 形式 (代数公式): 更直接的计算方法,其基函数是重心坐标 u,v和(1-u-v)的多项式。核心公式 (Bernstein for Triangles): 其中,Bernstein 基函数为: 
关键属性:
- 插值: 曲面必定穿过三个角落的控制点。
- 边界: 曲面的三条边界本身就是由边界控制点定义的标准 Bézier 曲线。
- 凸包特性: 整个 Bézier 三角形完全包含在其所有控制点构成的凸包之内。
- 法线计算: 同样可以通过求偏导数并进行叉积来获得表面法线,用于光照计算。
17.2.3 表面连续性 (Continuity)
核心观点: 在使用多个面片(无论是矩形的还是三角形的)拼接成复杂模型时,为了避免在接缝处出现明显的折痕或光照断层,必须严格控制面片间的连续性。
连续性级别 (以两个 Bézier 面片为例):
- 
C⁰ 连续 (位置连续性): - 定义: 两个面片共享一条公共边界。
- 实现: 共享边界上的所有控制点必须完全重合。
- 效果: 面片被“粘”在了一起,但在接缝处可能存在尖锐的折痕,导致光照不连续。
 
- 
C¹ 连续 (参数连续性): - 定义: 沿着共享边界,曲面的一阶导数(即切平面)是连续的。这保证了法线在跨越边界时不会发生突变。
- 实现: 除了满足 C⁰ 条件外,还需满足以下共线约束 (Collinearity Constraint):
- 对于共享边界上的每一个控制点 ,其两侧相邻的控制点 和 必须与 在同一直线上。
- 所有这些共线点对的距离比值必须是一个常数。即 。
 
- 效果: 得到一个视觉上完全平滑的曲面,光照和反射在接缝处能够平滑过渡。
 
实践中的挑战 (The Corner Problem):
- 当四个矩形面片在一个角点处汇集时,要维持严格的 连续性,会导致围绕该角点的 9 个控制点必须共面 (Coplanar)。
- 这个“共面约束”极大地限制了建模的自由度,使得复杂模型的构建变得非常困难。
- G¹ 连续 (几何连续性) 是一个稍微宽松的条件,它只要求切平面连续(即控制点共面),但不对距离比值做严格要求,因此提供了更多的灵活性。
重要结论:
- 对于纹理贴图,为避免扭曲,通常需要 连续。
- 对于光照和反射, 连续通常就能提供足够平滑的视觉效果。
- 手动管理大量面片的连续性非常繁琐且限制性强,这也是为什么细分曲面 (Subdivision Surfaces)(将在后续章节讨论)成为更受欢迎的建模范式,因为它们可以自动处理平滑连续性问题。
17.2.4 PN 三角形 (Point-Normal Triangles)
核心观点: PN 三角形是一种强大的硬件曲面细分 (Hardware Tessellation) 技术,其目标是将一个带有逐顶点法线的标准低多边形三角形网格,动态地“膨化”成一个视觉上更平滑、轮廓更优美的曲面。它的名字 PN 来源于其算法仅需要每个顶点的位置 (Point) 和法线 (Normal) 作为输入。
这项技术的核心是为每一个输入的平面三角形,都即时构建一个对应的三次 Bézier 三角形。
算法流程
给定一个三角形的三个顶点 和它们对应的法线 ,我们需要计算出定义一个三次 Bézier 三角形所需的全部10个控制点。
- 
角点控制点 (Corner Points): - 直接使用原始三角形的三个顶点作为 Bézier 三角形的三个角点。
 
- 
边界控制点 (Edge Points): - 直观思路: 边界上的控制点(如 )决定了曲面如何从一个顶点“出发”。它的位置是通过取两个顶点(如 和 )的三分点,然后将该点投影到顶点 处的切平面上来确定的。
- 核心公式 (以 为例):
- 其余5个边界控制点也用类似的方法计算。
 
- 
中心控制点 (Center Point): - 内部的中心控制点 被计算为所有6个边界控制点的平均值,再减去3个角点控制点平均值的一部分。
- 核心公式:
 
- 
法线插值: - 关键思想: PN 三角形不从生成的新曲面上去计算法线(这很昂贵),而是独立地使用一个二次 Bézier 三角形来插值法线。
- 原因:
- 三次曲面的导数(决定法线方向)是二次的。
- 简单的线性插值无法正确表现曲面存在拐点 (inflection point) 时的法线变化。
 
- 法线控制点: 插值法线所需的边界法线控制点(如 )也不是简单地对顶点法线求平均,而是通过一个反射操作来构造,以确保法线变化的正确性。
 
优缺点与实践
- 优点:
- 效果显著: 能以较低的性能开销,极大地改善模型的轮廓和光照表现。
- 独立计算: 每个三角形的细分是独立的,不需要邻接信息,非常适合 GPU 并行处理。
 
- 缺点:
- 固定细分等级: 为避免网格出现裂缝,所有三角形必须以相同的LOD级别进行细分,这对于小三角形来说是一种浪费。
- 连续性: 算法本身只保证面片间的 (位置) 连续。但由于顶点法线是共享的,它能很好地模拟出 (几何) 连续的效果,通常看起来已经足够平滑。
- 折痕控制难: 难以精确控制锐利的折痕。
 
17.2.5 Phong 曲面细分 (Phong Tessellation)
核心观点: Phong 曲面细分是另一种与 PN 三角形思想类似的实时曲面化技术,但它更简单、计算更快。它的目标是生成一个几何曲面,使其在视觉上与经典的 Phong 着色(即在三角形内部平滑插值法线)的效果相匹配。
算法流程
该算法通过一种巧妙的投影和插值来构造一个二次曲面。
- 基础: 在原始平面三角形上取任意一点 。
- 投影: 将这个点  分别投影到由三个原始顶点定义的三个切平面上。这一步会得到三个新的点 。
- 核心公式 (投影到顶点 i 的切平面):
 
- 二次插值: 使用相同的重心坐标 来线性插值刚刚得到的三个投影点 ,得到一个位于新曲面上的点 。
- 最终混合: 最终的曲面点是原始平面点和新曲面点之间的线性混合,由一个形状因子  控制。
- 核心公式:
- 当 时,就是原始的平面三角形。当 时,三角形会向外“鼓起”。推荐值为 。
 
与 PN 三角形的对比
- 性能: Phong 曲面细分是二次的,而 PN 三角形是三次的,因此前者计算更快、实现更简单。
- 法线: Phong 曲面细分直接使用传统的线性插值法线(同 Phong Shading),而 PN 三角形使用更复杂的二次插值。
- 质量: PN 三角形由于是更高阶的曲线,通常能产生更平滑、更“丰满”的曲面效果。Phong 曲面细分则更轻量。
17.2.6 B-样条曲面 (B-Spline Surfaces)
核心观点: B-样条曲面是一维 B-样条曲线向二维的直接扩展,与 Bézier 面片类似,它也是一种张量积曲面。它继承了 B-样条曲线最重要的优点:局部控制性。
核心公式:
曲面上的点  由一个控制点网格  和在 u、v 方向上的 B-样条基函数  相乘后求和得到:
双三次 B-样条面片 (Bicubic B-Spline Patch):
- 这是最常用的一种 B-样条曲面,在概念上与 Catmull-Clark 细分曲面(后续章节的关键内容)紧密相关。
- 构造方式: 一个双三次 B-样条面片由一个 的控制点网格来定义。
- 局部控制: 移动这个 网格中的任何一个控制点,只会影响这一小块曲面,而不会对整个模型产生全局影响,这使得编辑和调整非常高效和直观。
17.3 隐式表面 (Implicit Surfaces)
核心观点: 隐式表面提供了一种与参数化曲面完全不同的定义模型的方式。它不是用 (u,v) 参数来生成表面上的点,而是定义了一个**“内外”测试函数** 。
核心定义 (隐式函数):
- 判断规则:
- 如果 ,点 在表面上。
- 如果 ,点 在表面内部。
- 如果 ,点 在表面外部。
 
符号距离函数 (Signed Distance Functions, SDF):
- 这是隐式函数的一种特别强大的形式,其中函数 的值直接等于点 到表面的最短距离(带有正负号)。
- SDF 在实时渲染中应用极广,尤其是在光线追踪和程序化内容生成领域。
优点:
- 几何运算简单:
- 构造实体几何 (CSG) 操作非常容易实现。两个物体的并集就是取两个 SDF 值的 min(),交集是max()。
- 可以轻松实现平滑混合 (Blending),常用于创建“融球”(Metaballs) 或软体效果。
 
- 构造实体几何 (CSG) 操作非常容易实现。两个物体的并集就是取两个 SDF 值的 
- 求交测试高效: 非常适合用于光线追踪/光线步进,比参数化曲面更高效。
- 拓扑无关: 形状可以自由地融合、分裂,不会有传统网格的拓扑结构限制。
渲染方法:
- 最主要的渲染技术是光线步进 (Ray Marching),特别是针对SDF的优化版本球体追踪 (Sphere Tracing)。
- 核心思想: 在沿光线方向前进的任意一点,SDF 的值告诉了我们一个“安全距离”——即以此点为球心、距离值为半径的球体内保证没有任何物体。因此,光线可以一次性安全地前进这段距离,极大地加速了在空白空间的穿行。
 
- 也可以通过移动立方体 (Marching Cubes) 等算法,将隐式表面多边形化 (Polygonization),转换为传统的三角形网格进行渲染。
法线计算:
- 隐式表面的法线由其函数的梯度 (Gradient) 向量  给出,即函数对 x, y, z的偏导数所组成的向量。
17.4 细分曲线 (Subdivision Curves)
核心观点: 细分是一种从一个简单的控制多边形 (Control Polygon) 出发,通过迭代求精 (Iterative Refinement) 的过程来生成平滑曲线的技术。它在离散的顶点数据和连续的平滑曲线之间架起了一座桥梁。
基本流程:
- 从一个初始的多边形 开始。
- 应用一套细分规则 (Subdivision Scheme),在现有顶点之间创建新的顶点,并可能调整旧顶点的位置,得到一个新的、更精细的多边形 。
- 重复此过程 ,最终会收敛到一条平滑的极限曲线 (Limit Curve) 。
细分方案的类型:
- 
近似细分 (Approximating): - 特点: 极限曲线不穿过原始控制多边形 的顶点(端点除外)。
- 经典案例: Chaikin 算法 (切角法): 规则极其简单,在每条边的 和 处创建两个新顶点,然后用这些新顶点连接成下一级的多边形。这个过程等价于生成一条二次B样条曲线。
 
- 
插值细分 (Interpolating): - 特点: 极限曲线保证穿过原始控制多边形 的所有顶点。
- 经典案例: 四点细分方案: 在每条边的中点插入一个新顶点,新顶点的位置由其两侧的共 4 个旧顶点加权平均得到。原始顶点在迭代中保持不变。
 
关键应用:
- 细分技术是现代建模软件的核心功能之一。
- 它为细节层次 (LOD) 的生成提供了一种优雅的、基于几何的解决方案。
- 细分曲线的概念是理解更重要、更常用的细分曲面的基础。
17.5 细分曲面 (Subdivision Surfaces)
核心观点: 细分曲面是一种从一个低多边形控制网格 (Control Mesh) 出发,通过一套迭代求精的规则,来程序化地生成任意精度、光滑且无裂缝的曲面的强大技术。它完美结合了多边形建模的灵活性和参数化曲面的平滑性。
核心优势:
- 任意拓扑结构: 与需要矩形网格的 Bézier 面片不同,细分曲面可以应用于任何拓扑结构的模型(如带洞、多分叉的模型)。
- 自动平滑与连续性: 细分算法内置了平滑规则,可以自动保证曲面处处连续,从根本上解决了手动拼接面片时复杂的连续性管理问题。
- 无限细节层次 (LOD): 控制网格本身非常紧凑,通过增加迭代次数,可以生成任意数量的多边形,是天然的 LOD 解决方案。
细分的基本流程 (两阶段过程):
- 细化阶段 (Refinement): 增加几何复杂度。在现有的网格上插入新的顶点和边,将大的多边形分割成更多、更小的多边形。(例如,将一个三角形分裂成四个)
- 平滑阶段 (Smoothing): 调整顶点位置。根据一套加权平均的细分规则 (Subdivision Scheme),计算所有顶点(包括新插入的)的新位置,使整个网格趋于平滑。
图示:细分过程可以看作是先增加顶点(细化),再调整位置(平滑)的迭代。
17.5.1 Loop 细分 (Loop Subdivision)
核心观点: Loop 细分是一种专为三角形网格 (Triangle Meshes) 设计的、经典的近似 (Approximating) 细分方案。
算法核心: 在每一次迭代中,一个三角形会被分裂成四个,并通过以下两条核心规则来计算新顶点的位置:
- 
新“边”顶点 (Edge Vertex): 在每条原始边的中点附近创建一个新顶点。其位置是该边两个端点,以及这两个端点在相邻三角形中的另外两个对顶点的加权平均。 - 权重: 两个端点权重最高(各 3/8),两个对顶点权重较低(各 1/8)。
 
- 
更新“旧”顶点 (Vertex Vertex): 原始顶点的位置会被更新(向邻近顶点“拉拢”以实现平滑)。其新位置是它自身旧位置和所有直接相邻顶点(1-环邻域)的加权平均。 - 权重: 旧位置的权重由顶点价 (Valence)(连接的边数)决定,邻居顶点分享剩余的权重。
 
关键术语:
- 价 (Valence): 连接到某个顶点的边的数量。
- 规则顶点 (Regular Vertex): 在三角形网格中,价为 6 的顶点。
- 不规则/异常顶点 (Extraordinary Vertex): 价不为 6 的顶点。
属性与特点:
- 连续性: 在规则顶点处达到 连续(曲率连续),在异常顶点处达到 连续(切线连续)。这提供了非常高质量的平滑表面。
- 近似方案: 最终的极限曲面 (Limit Surface) 不会穿过原始控制点(端点除外)。
- 收缩性: 一个常见的副作用是,细分后的模型体积会比原始控制网格略微收缩。
- 极限位置: 无需无限次迭代,可以通过一个直接的公式计算出任何顶点在极限曲面上的最终位置和法线,这在实现中是重要的优化。
17.5.2 Catmull-Clark 细分
核心观点: Catmull-Clark 细分是目前业界应用最广泛的细分方案,尤其是在电影(皮克斯首创)和游戏中。它是一种近似方案,可以处理任意多边形网格,但其最自然的应用对象是四边形网格 (Quad Meshes)。
算法核心: 在一次迭代中,会生成三类新的点,并重新连接成一个纯四边形网格:
- 面顶点 (Face Vertex): 在每个原始多边形面的几何中心创建一个新顶点。
- 边顶点 (Edge Vertex): 在每条原始边的中点附近创建一个新顶点。其位置是该边两个端点,以及相邻两个面的新面顶点的平均值。
- 更新旧顶点 (Vertex Vertex): 原始顶点的位置被更新。其新位置是它自身旧位置、与它相连的所有旧边中点的平均值、以及与它共享的所有新面顶点的平均值的加权组合。
属性与特点:
- 生成四边形: Catmull-Clark 的一个显著特征是,经过一次细分后,无论输入是什么,输出的网格都将完全由四边形构成。
- B-样条基础: Catmull-Clark 曲面可以被看作是双三次B样条曲面 (Bicubic B-Spline Surfaces) 在任意拓扑结构上的推广。
- 行业标准: 由于其强大的灵活性和高质量的平滑效果,它已成为高质量角色和生物建模事实上的标准。
17.5.3 分段平滑细分 (Creases, Corners)
核心观点: 标准细分会让整个模型都变得平滑,但这不符合实际需求。分段平滑技术允许美术师通过标记控制网格上的边和点,来创建尖锐的特征,如折痕 (Crease) 和拐角 (Corner)。
实现方式:
- 美术师在建模软件中为某些边指定一个“锐度”值。
- 细分算法在遇到被标记为尖锐的边时,会采用另一套更简单的细分规则(例如,只进行线性插值而不平滑),而在模型的其他部分则使用标准的平滑规则。
- 这使得光滑曲面和硬表面特征能够完美地共存于同一个模型上。
17.5.4 位移细分 (Displaced Subdivision)
核心观点: 这是将细分曲面与位移贴图 (Displacement Mapping) 相结合的顶级渲染技术,用于在平滑的宏观结构上添加极其丰富的微观几何细节。
流程:
- 生成基底曲面: 使用 Loop 或 Catmull-Clark 算法将低多边形控制网格细分成一个足够精细的平滑曲面。
- 应用位移: 读取一张灰度图(位移贴图),并将基底曲面上的每个顶点,沿着其法线方向,根据贴图的灰度值进行实际的物理移动。
核心公式:
- : 细分后的平滑表面点
- : 从位移贴图采样的位移距离
- : 平滑表面该点的法线
- : 最终的、带有细节的表面点
与法线/凹凸贴图的区别:
- 法线贴图只是一个“光照戏法”,它欺骗光照计算,但不会改变模型的实际轮廓 (Silhouette)。
- 位移贴图是真正地移动了顶点,因此它能够正确地产生自阴影、遮挡,并且会极大地丰富模型的轮廓,真实感远超法线贴图。
17.5.5 属性插值 (UVs, Colors, etc.)
核心观点: 当我们对顶点位置进行细分时,也必须对依附于顶点的其他属性(如纹理坐标(UV)、顶点颜色等)进行相应的插值,以避免贴图或着色出现错乱。
通用方法:
- 最简单有效的方法是,将这些属性(如二维的UV坐标、四维的RGBA颜色)也看作是向量,然后应用与顶点位置完全相同的细分规则来进行加权平均。
- 特殊情况 (UV边界): 在处理纹理接缝(UV Seams)时需要特别小心。几何上连续的边,在UV空间中可能是断开的。在这种边界上,必须使用特殊的“边界细分规则”来插值UV,以防止纹理被错误地拉伸或混合。
17.6 高效曲面细分 (Efficient Surface Tessellation)
核心观点: 将曲面的数学表示(如Bézier面片、细分曲面)转换为可供渲染的三角形网格,这一过程称为曲面细分 (Tessellation)。在现代实时渲染中,这个过程已经从 CPU 转移到了 GPU 的专属硬件单元上,以实现无与伦比的效率和灵活性。
传统方法 vs. 现代方法:
- 传统方法 (CPU): 在 CPU 中使用嵌套循环,对参数 (u, v)空间进行均匀采样,生成一个密集的顶点网格,然后将其发送给 GPU。- 缺点: 效率低下,浪费 GPU 带宽,且无法根据实际需求动态调整细节。
 
- 现代方法 (GPU): 将紧凑的曲面表示(如控制点)直接发送给 GPU,利用硬件曲面细分管线 (Hardware Tessellation Pipeline) 来动态生成顶点。
- 优点: 极大地减少了 CPU-GPU 的数据传输,允许实现复杂的自适应细分,从而获得最佳的性能与质量平衡。
 
硬件曲面细分管线回顾:
- 外壳着色器 (Hull Shader): 核心决策阶段。它负责计算曲面细分因子 (Tessellation Factors),即决定一个面片需要被切割成多少块。所有的自适应逻辑都在这里实现。
- 曲面细分器 (Tessellator): 固定功能硬件单元。它根据 Hull Shader 传来的细分因子,在标准化的 (u, v)域(如一个单位正方形或三角形)内生成一个拓扑正确的顶点模式。
- 域着色器 (Domain Shader): 最终计算阶段。它接收曲面细分器生成的每一个 (u, v)坐标,并执行曲面求值函数(如 Bézier 公式),计算出该点在三维空间中的最终位置、法线、UV坐标等。
17.6.1 分数曲面细分 (Fractional Tessellation)
核心观点: 分数曲面细分是现代 GPU 的一项硬件特性,它允许曲面细分因子为非整数(例如 6.8 而非只能是 6 或 7)。
核心优势:
- 平滑的LOD过渡: 这是它最重要的用途。当物体远离摄像机时,细分因子可以从 8.0 平滑地过渡到 7.0,而不是在某个距离阈值上从 8 突变到 7。这能有效地消除或减轻LOD切换时的“突变 (Popping)”瑕疵。
- 避免裂缝: 为了确保相邻面片在共享边上生成的顶点完全一致,GPU 采用了对称的细分模式,从而避免了因浮点数精度问题导致的渲染裂缝。
17.6.2 自适应曲面细分 (Adaptive Tessellation)
核心观点: 自适应曲面细分是在 Hull Shader 中实现的核心智能逻辑,它根据一系列启发式规则动态地计算每条边和每个面片内部的细分因子,目标是**“在需要的地方增加细节,在不需要的地方减少细节”**。
核心评判标准 (Termination Criteria): Hull Shader 通常会综合以下几点来决定细分程度:
- 屏幕空间误差 (Screen-Space Error): 最重要和最常用的标准。计算一条边投影到屏幕上的像素长度。如果长度超过某个阈值(例如,10个像素),则增加细分,反之则减少。这能确保在任何距离和分辨率下,模型的边长都保持在一个合适的像素尺寸。
- 几何平坦度 (Geometric Flatness): 检查曲面本身的弯曲程度。几乎平坦的区域(如墙面)可以用很少的三角形来表示,而曲率大的区域(如鼻尖)则需要更多三角形。
- 视锥体剔除 (View Frustum Culling): 如果一个面片完全在视锥体之外,则其细分因子可以设为0,完全不生成任何三角形。
- 轮廓增强 (Silhouette Enhancement): 位于物体轮廓上的面片对视觉质量影响最大。算法会检测靠近轮廓的边,并显著提高其细分因子,以获得平滑的角色剪影。
- 位移幅度: 如果使用了位移贴图,贴图上细节丰富的区域也需要更高的细分率来表现这些几何细节。
17.6.3 快速 Catmull-Clark 曲面细分
核心观点: Catmull-Clark 是行业标准,但其递归和依赖邻接信息的特性不适合 GPU 的并行架构。因此,研究人员开发了多种高效的 GPU 渲染方案。
1. 近似法 (Approximation using Bézier Patches)
- 核心思想: 一个 Catmull-Clark 曲面在规则区域(所有顶点价都为4的四边形区域)等价于一个双三次 B-样条曲面,而后者可以被精确转换为一个 控制点的 Bézier 面片。对于不规则区域,这种转换则是一个近似。
- 渲染流程:
- 预处理: 对每个四边形,计算出其对应的16个 Bézier 控制点。
- 渲染: 将这16个控制点传入 Domain Shader。Domain Shader 只需执行快速的 Bézier 求值公式即可,无需任何递归或邻接信息。
 
- 缺点: 在不规则顶点周围,这只是一个近似,会导致面片间只有 连续,可能出现光照瑕疵。
2. 特征自适应细分 (Feature Adaptive Subdivision - FAS / OpenSubdiv)
- 核心思想: 这是皮克斯 OpenSubdiv 库采用的、目前业界最主流的精确渲染方法。它是一种混合策略:
- 规则区域: 直接被识别并渲染为高效的 B-样条面片。
- 不规则区域: 在 GPU 上使用计算着色器 (Compute Shader) 进行几轮真正的 Catmull-Clark 递归细分,直到所有不规则顶点都被一个“规则”的四边形环所隔离。
 
- 渲染流程: 渲染时,规则区域直接走硬件细分流程。被细分后的不规则区域也变成了规则的子面片进行渲染。系统使用特殊的过渡面片 (Transition Patches) 来无缝地拼接不同细分层级的区域。
- 优点: 既能精确地渲染 Catmull-Clark 曲面,又能充分利用 GPU 的并行计算和硬件细分能力,实现了性能和质量的完美结合。
3. 自适应四叉树 (Adaptive Quadtree)
- 核心思想: 这是对近似法的一种改进和精确化。它为每个基础网格四边形预计算一个四叉树结构,这个结构编码了该区域内直到某个最大深度的完整细分信息。
- 渲染流程: 在 Domain Shader 中,根据输入的 (u, v)坐标遍历这个四叉树,直到找到对应的叶子节点。该叶子节点存储了直接计算出精确表面位置所需的控制点信息。
- 优点: 渲染整个基础四边形只需一次绘制调用,能产生更均匀的细分模式,在某些情况下性能可能超过 FAS。是目前最快且最精确的方案之一。