表示选择

几何表示服务于具体查询。渲染需要快速采样表面与求交,碰撞检测关心内外和距离,编辑系统需要局部控制,流体模拟还要允许拓扑变化。不存在对所有任务都最优的表示。

隐式与显式几何的常见形式

表示方法大致分为两类:

  • 隐式表示 Implicit Representation 通过关系 f(x,y,z)=0f(x,y,z)=0 定义表面,通常容易做内外测试和求交,却不一定容易枚举表面点。
  • 显式表示 Explicit Representation 直接列出点、网格连接,或给出参数映射 p=f(u,v)\mathbf p=f(u,v),通常容易采样,内外判断可能更复杂。

纹理也可以表示一个与几何相关的场,但不能把它和几何表面混为一谈。立方体贴图 Cube Map 把六张纹理放在立方体的六个面上,用从中心出发的方向向量选择面和二维坐标,常用于环境光、反射和天空盒。它保存的是方向上的颜色采样,不定义可碰撞的表面;反射光线改变方向后重新查表,就能得到环境的近似外观。

Cube Map 用六个面记录方向上的环境颜色

代数曲面

球面可以写成

f(x,y,z)=x2+y2+z2R2=0.f(x,y,z)=x^2+y^2+z^2-R^2=0.

f<0f<0f=0f=0f>0f>0 可分别表示内部、表面和外部。更高次多项式能表达环面等复杂形状,解析形式紧凑、精确,也便于把光线方程代入求交;但多项式阶数上升后,建模和求根会迅速变难。

实体构造

构造实体几何 Constructive Solid Geometry 使用简单实体和布尔运算搭建复杂物体:

  • 并集 ABA\cup B
  • 交集 ABA\cap B
  • 差集 ABA\setminus B

一个 CSG 模型可组织成树,叶节点是基础实体,内部节点是布尔运算。它保留了高层结构,适合机械零件等规则造型。若最终渲染器只接受三角网格,还需要把布尔结果转换为显式表面。

CSG 用基础实体和布尔运算组合出复杂形状

距离函数

有符号距离函数 Signed Distance Function 定义点到表面的最短距离,并用正负区分内外:

d(x)={dist(x,S),x 在内部,0,xS,dist(x,S),x 在外部.d(\mathbf x)= \begin{cases} -\operatorname{dist}(\mathbf x,S),&\mathbf x\text{ 在内部},\\ 0,&\mathbf x\in S,\\ \operatorname{dist}(\mathbf x,S),&\mathbf x\text{ 在外部}. \end{cases}

零等值面 d(x)=0d(\mathbf x)=0 就是目标表面。若约定内部为负,两个形状的布尔组合可以写成

dAB=min(dA,dB),d_{A\cup B} = \min(d_A,d_B),

dAB=max(dA,dB),d_{A\cap B} = \max(d_A,d_B),

dAB=max(dA,dB).d_{A\setminus B} = \max(d_A,-d_B).

这些硬 min/max 公式取的是两个场的下包络或上包络:并集由 min\min 选择离外部更近的分支,交集由 max\max 选择同时满足约束的分支,差集先反转被减去的场再取 max\max。它们能正确给出布尔结果的符号与零等值面,但在切换曲面处通常不可微;交界附近的数值也未必仍等于到新表面的精确欧氏距离。

在可微且最近表面点唯一的区域,真正的 SDF 满足 Eikonal 条件

d=1.\lVert\nabla d\rVert=1.

因此表面法线可由

n=dd\mathbf n = \frac{\nabla d} {\lVert\nabla d\rVert}

得到。尖角、多个最近点组成的中轴和离散采样位置上,距离函数可能不可微,数值梯度也只近似满足该条件。

距离融合

两个距离场可以直接做线性插值:

dt(x)=(1t)d0(x)+td1(x),t[0,1].d_t(\mathbf x) = (1-t)d_0(\mathbf x) +td_1(\mathbf x), \qquad t\in[0,1].

新形状由零等值面 dt(x)=0d_t(\mathbf x)=0 定义。先看一维移动边界。边界从 x=ax=a 移到 x=bx=b,两端 signed distance 为

d0(x)=xa,d1(x)=xb.d_0(x)=x-a, \qquad d_1(x)=x-b.

线性融合后

dt(x)=(1t)(xa)+t(xb)=x[(1t)a+tb].\begin{aligned} d_t(x) &=(1-t)(x-a)+t(x-b)\\ &=x-[(1-t)a+tb]. \end{aligned}

dt(x)=0d_t(x)=0,新边界位于

xt=(1t)a+tb,x_t=(1-t)a+tb,

恰好按相同参数线性移动。三维中同样可以在方形、圆形等完全不同形状的 signed distance 之间生成连续 morph。

融合边界上的点通常不在任一原边界上。它可能位于第一个形状外部,满足 d0>0d_0>0,同时位于第二个形状内部,满足 d1<0d_1<0,正负加权后抵消为零。若某点对两个形状都在外部,两个距离都为正,普通正权重线性插值当然不可能得到零。

距离场线性融合会移动两条边界之间的零等值面

线性融合描述的是形状插值,与并集的 min(d0,d1)\min(d_0,d_1) 含义不同。它直接插值两个标量场,因此会把两个场的梯度也按权重相加;形状差异较大时,零等值面可能出现收缩、鼓包或拓扑变化,而不是沿某条几何路径运动。

若要把两个相交物体的连接处变圆,可使用 smooth-min 一类平滑并集。取过渡宽度 k>0k>0,一个常见的多项式形式是

h=max(kabk,0),smink(a,b)=min(a,b)kh36.h=\max\left(\frac{k-|a-b|}{k},0\right), \qquad \operatorname{smin}_k(a,b) =\min(a,b)-\frac{k h^3}{6}.

其中 kk 控制 aba\approx b 附近的过渡带宽度。它把硬下包络的折线切换替换成一段圆滑的连接,几何上相当于对并集交界附近做圆角化;增大 kk 会让圆角和形态变化更明显,也可能填平窄缝或改变局部拓扑。也可使用 log-sum-exp 等平滑近似,但平滑参数、零等值面位置和数值稳定性需要一起校准。

无论线性融合还是 smooth-min,结果一般不再是严格 Euclidean SDF,因此 d\lVert\nabla d\rVert 未必等于 1。梯度长度偏离 1 会影响法线归一化,也会破坏 Sphere Tracing 把 dd 当作安全步长的保证:梯度过大时可能跨过表面,梯度过小时步长过于保守。实际实现应使用保守缩放或 Lipschitz 上界限制步长,并在需要时重新初始化距离场;数值法线也应按局部采样尺度计算,不能假设混合场仍具有精确距离语义。

圆形和方形距离场的融合展示平滑过渡

Distance Blending 融合的是整个标量场,最终表面仍然只是“融合后函数等于零”的位置。

Sphere Tracing 沿归一化光线

x(t)=o+td,d=1\mathbf x(t)=\mathbf o+t\mathbf d, \qquad \lVert\mathbf d\rVert=1

前进。若当前点在形状外,迭代为

tk+1=tk+d(x(tk)).t_{k+1} = t_k+d(\mathbf x(t_k)).

d(x(tk))d(\mathbf x(t_k)) 是当前点到任意表面点的最短距离,以当前位置为球心、该距离为半径的开球中不可能有表面。沿任意方向移动不超过这个半径都不会穿过交点,所以这一整步是安全的。

dd 小于容差时可认为命中;超过最大距离或最大步数则结束。一般隐式函数 f(x)=0f(\mathbf x)=0 的数值没有距离意义,直接把 ff 当步长可能越过表面。若方向未归一化,参数 tt 也不再等于实际距离,更新量必须相应换算。

零等值面足以定义形状;只有真实距离或已知安全下界,才能直接保证 Sphere Tracing 不跨过表面。

等值面

复杂隐式函数可以只在规则网格上存储离散值,再由插值重建连续场。满足

f(x)=cf(\mathbf x)=c

的点构成 等值集 Level Set。医学 CT、MRI 的密度场可以抽取组织边界;流体模拟也常用有符号距离记录液体与空气的界面。Marching Cubes 等算法能把等值面转换为三角网格。

网格分辨率决定可表达的最小细节,离散场还需要重初始化或其他数值处理,才能长期保持良好的距离性质。

Level Set 在规则网格上用离散标量值表示零等值面

分形

分形在多个尺度上重复相似结构,能描述海岸线、植物和地形等自然形态。递归规则或噪声函数可以生成极丰富的细节,但参数与最终形状之间缺少直观的局部控制。无限细节也意味着显示时必须按像素尺度过滤,否则会产生严重混叠。

参数曲面

参数曲面 Parametric Surface 把二维参数域显式映射到三维:

p(u,v)=(x(u,v)y(u,v)z(u,v)).\mathbf p(u,v)= \begin{pmatrix} x(u,v)\\y(u,v)\\z(u,v) \end{pmatrix}.

给定 (u,v)(u,v) 就能直接得到表面点和切向量,因此采样和纹理映射很自然;但给定任意空间点,判断它是否在封闭曲面内部通常没有简单公式。一个形状可能需要多个参数片覆盖,并在片之间处理接缝和连续性。

两个参数方向的偏导数给出局部切向量:

pu=pu,pv=pv.\mathbf p_u = \frac{\partial\mathbf p}{\partial u}, \qquad \mathbf p_v = \frac{\partial\mathbf p}{\partial v}.

只要二者不平行,表面法线为

n=pu×pvpu×pv.\mathbf n = \frac{ \mathbf p_u\times\mathbf p_v }{ \lVert\mathbf p_u\times\mathbf p_v\rVert }.

叉积接近零说明参数化在该处退化,法线和纹理微分都会变得不稳定。

与几何位移相关的纹理也要区分层次。凹凸贴图 Bump Mapping 只改变着色时使用的局部法线,不改变实际顶点、轮廓或碰撞几何;位移贴图 Displacement Mapping 则沿法线移动真实表面,需要足够的细分或自适应曲面求值,才能把高频细节反映到轮廓和阴影中。前者便宜但掠射角和遮挡关系仍来自原表面,后者更真实却会增加几何和求交成本。

Bump Mapping 与 Displacement Mapping 对表面细节和轮廓的不同影响

点云

点云 Point Cloud 直接保存大量三维点,可附带颜色、法线和置信度。它是扫描仪与多视图重建的自然输出,表示任意拓扑也不需要显式连接关系。

点云没有定义点之间的表面,采样不足时会出现孔洞,也难以直接执行平滑、细分和物理模拟。若每个像素投影范围内有充足点,可以用 splatting 等方式直接渲染;更常见的流程是先估计法线和邻域,再重建网格。

多边形网格

多边形网格 Polygon Mesh 由顶点、边和面组成,三角网格最常见。它显式记录连接关系,便于光栅化、局部编辑、细分和碰撞检测。除了位置,顶点或面还可携带法线、UV、颜色和材质索引。

共享顶点能节省存储并表达邻接,但硬边、UV 接缝或不同材质边界常需要逻辑上重复顶点,让同一空间位置拥有不同属性。实际数据结构还要支持从顶点查邻面、从边查两侧面等拓扑查询,Half-Edge 是常见选择。

Half-Edge 将一条无向边拆成两个相反方向的半边,并为每个半边保存 twinnext、所属 face 和起点 vertex。沿 next 可以遍历一个面的边界,沿 twin 可以跳到相邻面,因此顶点一环邻域、边两侧面和边界状态都能在局部常数步操作中查询。Loop 或 Catmull–Clark 细分、边折叠和局部法线更新都依赖这类邻接访问;边界边没有有效的另一侧时,通常让 twin 指向边界哨兵,避免把不存在的面当作普通邻域。

OBJ 格式

Wavefront OBJ 是简单的文本格式。常见记录包括:

  • v x y z:顶点位置;
  • vt u v:纹理坐标;
  • vn x y z:顶点法线;
  • f v/vt/vn ...:面的索引组合。

f 可以列出三角形,也可以列出四边形等多边形;例如四边形面可写成四组索引。由于光栅化和多数求交器以三角形为基本单元,导入时通常要把四边形三角化。非平面或凹四边形的对角线并不唯一,选择不同对角线可能改变插值、法线和轮廓,因此不能只按文件顺序盲目拆分。

位置、UV 和法线使用彼此独立的索引,而许多渲染 API 要求每个顶点只有一个统一索引。导入时通常需要按索引三元组拆分顶点。三角网格中,内部边通常恰好被两个三角形共享,边界边只被一个三角形使用;若一条边连接超过两个面,则是非流形连接,三角化和细分都需要额外处理。OBJ 便于交换静态几何,但不擅长保存骨骼、动画和复杂场景层级。

表示转换

隐式转显式需要在空间中找到零等值面,显式转隐式则要构造占据场或距离场。转换通常会引入采样误差,也可能改变拓扑。实践中经常混合表示:用三角网格渲染外表面,用 SDF 做碰撞和布尔运算,用纹理或体素保存局部细节。选择标准应是目标操作是否稳定、高效,而不是表示名称是否统一。