中EN
概念页

参数曲面与贝塞尔面片

Parametric Surfaces & Bézier Patches

参数曲面把参数曲线从一个参数推广到两个参数 (u,v)(u,v),由少量控制点定义,运行时细分成任意多个三角形,是质量与速度之间的天然权衡:三角形多则着色和轮廓更好。矩形定义域的是贝塞尔面片(张量积曲面),三角形定义域的是贝塞尔三角形,后者是 PN 三角形和 Phong 细分的基础。

为什么用参数曲面(17.2 节)

  • 细分 (tessellation):在若干参数位置求值并连成三角形逼近曲面,因为硬件擅长渲染三角形。
  • 可以只动画控制点再细分,比直接动画大三角网格便宜。

贝塞尔面片(17.2.1 节)

  • 从双线性插值出发:四点 a,b,c,d\mathbf{a},\mathbf{b},\mathbf{c},\mathbf{d}, p(u,v)=(1−u)(1−v)a+u(1−v)b+(1−u)vc+uvd\mathbf{p}(u,v)=(1-u)(1-v)\mathbf{a}+u(1-v)\mathbf{b}+(1-u)v\mathbf{c}+uv\mathbf{d} 与纹理双线性过滤同型,是最简单的非平面参数曲面;定义域为 [0,1]×[0,1][0,1]\times[0,1] 的曲面称为面片 (patch)。
  • nn 次面片有 (n+1)2(n+1)^2 个控制点 pi,j\mathbf{p}_{i,j},de Casteljau 推广为反复双线性插值;Bernstein 形式 p(u,v)=∑i=0m∑j=0nBim(u)Bjn(v) pi,j\mathbf{p}(u,v)=\sum_{i=0}^{m}\sum_{j=0}^{n}B_i^m(u)B_j^n(v)\,\mathbf{p}_{i,j} 两方向次数可以不同(m×nm\times n)。固定 vv 时它就是一条贝塞尔曲线。
  • 性质:插值四个角控制点;每条边界是由边界控制点决定的 nn 次贝塞尔曲线,角点处的两条切线由边界曲线给出;位于控制点凸包内;先变换控制点再求值等价且更快;移动一个控制点主要影响其附近。
  • 偏导数次数在求导方向降一: ∂p∂u=m∑j=0n∑i=0m−1Bim−1(u)Bjn(v)[pi+1,j−pi,j]\frac{\partial\mathbf{p}}{\partial u}=m\sum_{j=0}^{n}\sum_{i=0}^{m-1}B_i^{m-1}(u)B_j^n(v)[\mathbf{p}_{i+1,j}-\mathbf{p}_{i,j}] vv 方向同理;未归一化法线 n=∂p∂u×∂p∂v\mathbf{n}=\dfrac{\partial\mathbf{p}}{\partial u}\times\dfrac{\partial\mathbf{p}}{\partial v}。
  • 有理贝塞尔面片在分子分母中各加权重 wi,jw_{i,j},增加自由度。

贝塞尔三角形(17.2.2 节)

  • 三角形定义域反而比矩形复杂。nn 次三角形每边 n+1n+1 个控制点 pijk\mathbf{p}_{ijk}(i+j+k=ni+j+k=n),总数 (n+1)(n+2)2\dfrac{(n+1)(n+2)}{2}。
  • 用重心坐标 (u,v)(u,v),w=1−u−vw=1-u-v。de Casteljau: pi,j,kl=u pi+1,j,kl−1+v pi,j+1,kl−1+(1−u−v) pi,j,k+1l−1\mathbf{p}^l_{i,j,k}=u\,\mathbf{p}^{l-1}_{i+1,j,k}+v\,\mathbf{p}^{l-1}_{i,j+1,k}+(1-u-v)\,\mathbf{p}^{l-1}_{i,j,k+1} Bernstein 形式 p(u,v)=∑i+j+k=nBijkn(u,v)pijk\mathbf{p}(u,v)=\sum_{i+j+k=n}B^n_{ijk}(u,v)\mathbf{p}_{ijk},其中 Bijkn(u,v)=n!i! j! k!uivj(1−u−v)kB^n_{ijk}(u,v)=\frac{n!}{i!\,j!\,k!}u^iv^j(1-u-v)^k
  • 插值三个角点,每条边界是贝塞尔曲线,位于凸包内。Unreal、Unity、Lumberyard 等引擎支持基于它的 Phong 细分和 PN 三角形。

面片拼接的连续性(17.2.3 节)

两个双三次面片(各 4×4 控制点 aija_{ij}、bijb_{ij}):

  • C0C^0:共享边界控制点 a3j=b0ja_{3j}=b_{0j}。
  • C1C^1:对每个 jj,a2ja_{2j}、b0jb_{0j}、b1jb_{1j} 共线,且比例相同 ∥a2j−b0j∥=k∥b0j−b1j∥\lVert a_{2j}-b_{0j}\rVert=k\lVert b_{0j}-b_{1j}\rVert,kk 对所有 jj 相同。
  • 四片共享一个角时,角点周围九个控制点必须共面并构成双线性面片;只要求角点处 G1G^1 时共面即可,占用更少自由度。
  • 取舍:C1C^1 是跨边界纹理好看的必要条件;反射和着色有 G1G^1 即可接受,C1C^1 以上更好。由大量贝塞尔曲面构造复杂物体时很难保证所有边界的连续性,这是转向 细分曲线与细分曲面 的原因之一。

B 样条曲面(17.2.6 节)

sn(u,v)=∑k∑lck,l βn(u−k) βn(v−l)s^n(u,v)=\sum_k\sum_l c_{k,l}\,\beta^n(u-k)\,\beta^n(v-l) 双三次 B 样条面片需要 4×4 控制点,实际曲面位于最内侧 2×2 控制点之内。用于纹理过滤时它是高度场,ck,lc_{k,l} 是一维高度。双三次 B 样条面片是 Catmull-Clark 细分曲面的基础。

GEA 的视角:场景几何的三种表示(卷 II 11.3.5)

  • 广义表面:光的有趣行为大多发生在不同材质的边界上,包括实体表面和不同透光介质的界面,GEA 统称为广义表面,游戏开发者叫"场景几何"。场景可描述为一组表面加上每个表面所围子体积的材质;烟、雾这类没有明确边界的参与介质也能建模为有边界的体积,让材质属性在体积内变化(表面透明、越往里越浑浊)(卷 II 11.3.5,见 参与介质与体积散射)。
  • 解析曲面:曲面是嵌入三维空间的二维流形,有时可解析表示,如球面 (x−c)⋅(x−c)=r2(\mathbf{x}-\mathbf{c})\cdot(\mathbf{x}-\mathbf{c})=r^2。可渲染几何大多无法解析描述,但解析球和平面在引擎中用途很多:碰撞体、包围体、触发区,以及光线追踪引擎的简单测试用例(卷 II 11.3.5.1,见 几何图元的表示)。
  • 参数曲面:影视行业常用由少量控制点定义的二维样条矩形面片表示曲面,包括贝塞尔曲面(如三次面片)、NURBS、贝塞尔三角形和 N-patch(法线面片);GEA 把用面片建模比作用小块布或纸浆糊雕像(卷 II 11.3.5.2)。
  • 细分曲面:Pixar 的 RenderMan 等高端影视渲染器用细分曲面定义形状,控制多边形可用 Catmull-Clark 算法不断细分,通常细分到每个多边形小于一个像素;最大好处是无论相机多近都能继续细分,轮廓边永远不会显得有棱角(见 细分曲线与细分曲面)。
  • 游戏传统上用三角网格,原因见 三角形带、扇与索引网格 中的 GEA 部分。

PBRT 的视角:双线性面片与曲面微分几何(PBRT 4e 6.2、6.6)

双线性面片

四个顶点不必共面:f(u,v)=(1−u)(1−v)p00+u(1−v)p10+(1−u)vp01+uvp11f(u,v)=(1-u)(1-v)\mathbf p_{00}+u(1-v)\mathbf p_{10}+(1-u)v\mathbf p_{01}+uv\mathbf p_{11}(式 6.11)。固定 uu 或 vv 都得到直线,所以是双直纹曲面。它能表示平面四边形和简单的弯曲面,适合作为高阶参数曲面转换后可直接求交的目标形状。偏导数为 ∂p∂u=(1−v)(p10−p00)+v(p11−p01),∂p∂v=(1−u)(p01−p00)+u(p11−p10)(式 6.13)\frac{\partial p}{\partial u}=(1-v)(\mathbf p_{10}-\mathbf p_{00})+v(\mathbf p_{11}-\mathbf p_{01}),\qquad\frac{\partial p}{\partial v}=(1-u)(\mathbf p_{01}-\mathbf p_{00})+u(\mathbf p_{11}-\mathbf p_{10})\quad(\text{式 6.13}) 面积 ∫01 ⁣∫01∥∂up×∂vp∥ du dv\int_0^1\!\int_0^1\|\partial_u p\times\partial_v p\|\,du\,dv(式 6.12)一般没有闭式:矩形直接用边长乘积,否则用 3×3 点的黎曼和近似并缓存。IsRectangle() 依次检查相邻顶点重合、四点共面,以及四点到质心距离相等(用相对误差,与尺度无关)。法线方向锥取四角法线的平均方向和最大夹角。求交见 光线求交测试,采样见 形状采样。

法线的导数:Weingarten 方程

纹理抗锯齿需要知道法线随 (u,v)(u,v) 怎样变化。第一基本形式 E=∣∂up∣2, F=∂up⋅∂vp, G=∣∂vp∣2E=|\partial_u p|^2,\ F=\partial_u p\cdot\partial_v p,\ G=|\partial_v p|^2,第二基本形式 e=n⋅∂uup, f=n⋅∂uvp, g=n⋅∂vvpe=\mathbf n\cdot\partial_{uu}p,\ f=\mathbf n\cdot\partial_{uv}p,\ g=\mathbf n\cdot\partial_{vv}p,则 ∂n∂u=fF−eGEG−F2∂p∂u+eF−fEEG−F2∂p∂v,∂n∂v=gF−fGEG−F2∂p∂u+fF−gEEG−F2∂p∂v\frac{\partial\mathbf n}{\partial u}=\frac{fF-eG}{EG-F^2}\frac{\partial p}{\partial u}+\frac{eF-fE}{EG-F^2}\frac{\partial p}{\partial v},\qquad\frac{\partial\mathbf n}{\partial v}=\frac{gF-fG}{EG-F^2}\frac{\partial p}{\partial u}+\frac{fF-gE}{EG-F^2}\frac{\partial p}{\partial v} EG−F2EG-F^2 用 DifferenceOfProducts() 计算以提高精度,为 0 时要避免除零产生 NaN。双线性面片只有 ∂uvp\partial_{uv}p 非零;三角形和圆盘法线导数为 0。参考 Gray (1993) 14.3 节。

旋转曲面的面积

曲线 y=f(x)y=f(x) 绕轴旋转 ϕmax\phi_{max} 角得到的曲面面积为 ϕmax∫abf(x)1+f′(x)2 dx\phi_{max}\int_a^b f(x)\sqrt{1+f'(x)^2}\,dx。对球 f(z)=r2−z2f(z)=\sqrt{r^2-z^2},被积函数化简为常数 rr,于是部分球面积 A=ϕmaxr(zmax−zmin)A=\phi_{max}r(z_{max}-z_{min}),完整球为 4πr24\pi r^2;圆柱 A=(zmax−zmin)rϕmaxA=(z_{max}-z_{min})r\phi_{max},圆盘(圆环)A=ϕmax2(r2−ri2)A=\frac{\phi_{max}}2(r^2-r_i^2)。

纹理坐标与参数坐标分离

双线性面片若带每顶点纹理坐标 (s,t)(s,t),就要把 ∂p/∂u\partial p/\partial u 换成 ∂p/∂s=∂p∂u∂u∂s+∂p∂v∂v∂s\partial p/\partial s=\frac{\partial p}{\partial u}\frac{\partial u}{\partial s}+\frac{\partial p}{\partial v}\frac{\partial v}{\partial s} 等;纹理映射退化时保留原偏导(至少叉积给出正确法线),并保证新法线与原法线同侧。

  1. realtime_rendering_4ed.pdf 第 17 章 Curves and Curved Surfaces
  2. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  3. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 11 章 11.3.5 节
  4. PBRT 4e source excerpt: chapter 06 (Shapes)
  5. Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 6 章 6.2.2–6.2.3、6.6 节,pbr-book.org/4ed/Shapes

相关页面

游戏数学贝塞尔曲线Bézier Curves参数曲线 \mathbf{p}(t) 用参数 t 生成连续的点,实时图形中常用于让相机或物体沿预定路径移动(与帧率无关),也用于渲染头发和字体。贝塞尔曲线由反复线性插值(de Casteljau 算法)得到,等价于 Bernstein 多项式加权控制点;多段拼接时要关注 C^n / G^n 连续性。游戏数学埃尔米特与 Kochanek-Bartels 样条Hermite & Kochanek-Bartels Splines三次 Hermite 曲线用两个端点和两个端点切线定义,比贝塞尔控制点更直观;把多段 Hermite 曲线串起来经过一系列点时,Kochanek-Bartels 用张力、偏置、连续性三个参数从相邻弦计算切线,默认参数即 Catmull-Rom 样条。均匀三次 B 样条则以不经过控制点为代价换来处处 C^2 连续。图形学PN 三角形与 Phong 细分PN Triangles & Phong Tessellation两种只用每个三角形自身的顶点位置和法线、把平面三角形替换成曲面三角形的方法,不需要邻接信息,适合硬件细分即时生成。PN 三角形构造三次贝塞尔三角形并二次插值法线;Phong 细分是"几何版 Phong 着色",生成二次曲面,更快更简单。两者都能明显改善低模的轮廓和着色。图形学细分曲线与细分曲面Subdivision Curves & Surfaces细分从一个控制多边形 / 控制网格出发,反复"细化 + 平滑",极限是光滑的曲线或曲面。它能从任意拓扑的网格得到连续、无裂缝的曲面,规则简单、天然支持无限 LOD,连接了离散三角网格与连续曲面。游戏和电影最常用的是 Catmull-Clark(四边形)和 Loop(三角形)两种逼近型方案,可扩展出折痕和置换细分。图形学高效曲面细分Efficient Tessellation实时渲染曲面需要把它细分成三角网格。与其在 CPU 上细分后传大量三角形,不如把曲面描述送到 GPU,由硬件细分管线(外壳着色器 → 细分器 → 域着色器)展开。本页讲分数细分因子、按曲率/屏幕尺寸/轮廓决定细分率的自适应细分、避免裂缝与跳变的方法,以及 Catmull-Clark 曲面的快速 GPU 渲染(近似面片、OpenSubdiv 特征自适应细分、自适应四叉树)。图形学纹理过滤与 MipmapTexture Filtering & Mipmap纹理在屏幕上被放大时需要插值,被缩小时一个像素覆盖许多纹素,必须预先滤波才能避免混叠。放大用最近邻、双线性或双三次;缩小的主流方案是 mipmap + 三线性插值,斜视角下用各向异性过滤减少过度模糊。注意:过滤纹理值只在输入与着色结果线性相关时等价于过滤最终颜色。图形学隐式曲面与有符号距离函数Implicit Surfaces & Signed Distance Functions隐式曲面用 f(\mathbf{p})=0 定义:代入点结果为零即在曲面上。返回到最近表面有符号距离的 f 称为有符号距离函数 (SDF)。它们便于做光线求交、构造实体几何 (CSG)、混合与变形,通常用光线步进可视化,也可用移动立方体等方法转为三角形。图形学三角形带、扇与索引网格Triangle Strips, Fans & Indexed Meshes让共享顶点的三角形成组送入管线,可以减少顶点着色器调用。三角形扇和带把每三角形发送的顶点数降到接近 1;现代 GPU 的标准做法是带单一索引缓冲的三角形网格,理论上每三角形只需处理约 0.5 个顶点,实际效果取决于变换后顶点缓存,由三角形顺序优化(Forsyth、Tipsify 等)决定。游戏数学几何图元的表示Geometric Primitive Representations除点、向量、矩阵、四元数外,游戏引擎还天天用到直线/射线/线段、球、平面、AABB、OBB、视锥和凸多面体区域。本页按 GEA 整理它们在内存中如何表示以及最基本的「点在内部吗」测试;各种求交与重叠算法见 RTR4 来源的相交测试系列页面。图形学参与介质与体积散射Participating Media & Volumetric Scattering参与介质是充满粒子、通过吸收和散射参与光传输的体积,如空气、水、雾、烟、云;皮肤、蜡等致密材质也有强烈散射——"一切都是散射"。实时渲染主要考虑单次散射:沿视线积分透射率衰减后的内散射光,内散射由相位函数和对光源的可见性(不透明阴影 × 体积阴影)决定。通用实时方案把介质材质和散射结果体素化到相机视锥体素 (froxel) 中逐片累积(RTR4 14.1、14.3、14.8 节)。游戏数学形状采样Shape Sampling把形状当作面光源时,需要在形状上采样点。最简单的是按面积均匀采样再把 PDF 换算成立体角;更好的是只在参考点看得到的立体角内均匀采样,消掉 1/r^2 和背面带来的方差。本页按 PBRT 第 4 版第 6 章整理各种形状的采样公式及其推导要点。游戏数学光线求交测试Ray Intersection Tests光线求交用于拾取、光线追踪、地面高度查询等。本页给出四类经典测试:光线-球(代数解与带早期拒绝的几何优化解)、光线-盒(平板法与光线斜率法)、光线-三角形(Möller-Trumbore,直接从顶点求重心坐标与距离)、光线-多边形(先求平面交点,再投影到二维做交叉数测试)。共同思路是先做便宜的拒绝测试、推迟除法与开方、必要时降维。

输入关键词开始搜索

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