前言

几何形体是计算机图形学当中十分重要的一部分内容,如何表示好人物、景物、建筑等各种各样的模型是几何部分的主要研究内容之一。本文主要介绍隐式曲面和显式曲面的特点,以及二者分类之下各自主要的几何表现形式。

 

隐式曲面(Implicit Surface)

所谓隐式曲面指的是并不会具体表示任何点的信息,只会给出该曲面上所有点满足的关系。来举个具体的隐式曲面的例子:

显然这是一个半径为1的三维球体的方程,一般会把隐式曲面的代数方程记作以下形式。

而该球体的表示方式就是

对于隐式方程来说因为没有给出任何点的信息,因此如何采样到曲面上具体的点是一个很难的问题,如下图这样一个例子:

别说找出这样一个圆环上的点了,如果只知道这个代数方程那么连它表现的形状是什么都很难判断。

但反过来说,隐式曲面有一个出众的优点,通过将点的坐标代入隐式曲面方程,可以十分容易的判断出一点与曲面的内外关系,这是一种非常具有吸引力的特性(能够轻易的判定光线与物体是否相交)。

代数曲面(Algebraic Surfaces)

前面的例子就属于代数曲面,也就是通过代数表达式得到的几何曲面,显然曲面越复杂,代数表达式也越复杂。

但似乎单纯用代数表达式的曲面都颇具有规则性,那么对于更复杂的几何形体怎么办呢? 此时CSG(Constructive Solid Geometry)便应运而生了。

 

构造立体几何(Constructive Solid Geometry)

CSG指的是可以对各种不同的几何做布尔运算,如并,交,差:

通过这些操作可以得出各种更为复杂的几何:

通过CSG的方法可以一定程度上缓解隐式曲面难以表现复杂形体的困境 (该种方法广泛存在于各类建模软件之中)。

 

符号距离函数(Signed Distance Function)

除了对于几何的布尔操作,还可以通过距离函数来得到几何形体混合的效果,如下图:

如何得到这种blend的效果,就要从SDF即符号距离函数说起了(这里的符号是指距离可以有正有负)。

首先对于符号距离函数来说本质上就是一种定义距离的函数。如有空间任意一点到各个几何物体表面的距离,对这些距离做各种各样的运算操作最后得到的一个函数就是最终的距离函数了,举一个简单的例子:

对于这样一个二维平面的例子,定义空间中每一个点的SDF为该点到阴影区域右边界的垂直距离,在阴影内部为负,外部为正,因此对于A和B两种阴影来说的SDF分别如上图下半部分所示。有了SDF(A),SDF(B)之后对这两个距离函数选择性的做一些运算得到最终的距离函数,这里采用最简单的SDF = SDF(A)+SDF(B)来举例,最终得到的SDF为零的点的集合即为blend之后曲面,对该例子来说,就是两道阴影之间中点的一条线:

对于一开始的那个例子来说,只需合理定义空间中任意一个点的SDF,再令SDF为0即可得到混合的效果了。

需要注意的的是,对于几何体的混合效果自然不可能像这里简单的两个距离相加就可以得到了,该效果具体实现是找出任一个点到两个几何体表面距离中的最短距离再减去一个变量作为该点最终的SDF。

因此SDF特别适合制作光滑的曲面融合效果,例如下面的模型。

 

水平集(Level Set)

水平集的方法其实与SDF很像(像是SDF的一种特殊形式),也是找出函数值为0的地方作为曲线,但不像SDF会空间中的每一个点有一种严格的数学定义,而是对空间用一个个格子去近似一个函数,如下:

对该面内的每一个点利用已经定义好的格子值进行双线性插值就可以得到任意一点的函数值,找出所有=0的点作为曲面。

该方法的好处是对于SDF,我们可以更加显式的去定义空间曲线的形状。该方法广泛的运用在医学成像和物理模拟之中:

 

分型几何(Fractals)

分型几何是指许许多多自相似的形体最终所组成的几何形状。

如雪花是一个六边形,放大之后会发现每一个边上又是一个六边形,再放大六边形边上的六边形边上又是六边形,就这样无限套娃,有点递归的意思。

 

显式曲面(Explicit Surface)

显式曲面来说是与隐式曲面相对应的,所有曲面的点被直接给出,或者可以通过映射关系直接得到,如下图:

虽然没有直接给出点的xyz坐标,但是拥有UV的取值范围以及从UV坐标到xyz坐标的映射关系,那么只需要将所有的UV坐标代入自然就可求得每个点的xyz坐标。

区别隐式曲面与显示曲面的关键就在于是否可以直接表示出所有的点。

前面说到隐式曲面难以采样曲面上的点,但是可以轻易判断点与曲面的关系,对于显式曲面来说正好相反,可以很轻易的采样到所有的点,但是给予任意一点却很难判断它与曲面的关系。

因此不能说哪一种的几何表现方式更好,根据具体的需求来选择使用隐式曲面或者显式曲面才是合理的做法。

 

点云(Point Cloud)

顾名思义,就是很多很多的点构成的模型,不去考虑点构成的曲面,而是直接给出所有点的信息,点越多模型细节就越丰富,点如果太少模型就会出现缝隙,缺点是大量的点需要消耗更多的存储,一般三维扫描生成的原始模型就是点云,可以通过特定的算法转换成多边形网格等其他种类的显式曲面。

 

多边形网格(Polygon Mesh)

对于多边形网格来说相信读者并不陌生,该方法广泛应用在计算机图形当中,简单来说通过定义各个多边形面的顶点以及顶点之间的连接关系就可以得到许许多多的三角形面或是四边形面,再通过这些面来近似表现出我们想要的模型效果。

例如比较著名的.obj文件,其格式如下

这是一个立方体的模型数据例子。

3-10行定义了立方体的8个顶点信息。 12-25行定义了这些顶点的纹理坐标信息(每个面4个点,共6个面所以最多有24种不同的纹理坐标信息,这里有一些纹理对于不同面上的点是共用的)。 27-34行定义了6个面的法线信息,为什么有8个是因为建模软件输出的精度问题不必在意,其中有两个是重复的。

最重要的就是36-47行了,定义了每个面上顶点的连接关系以及对应的纹理坐标和法线坐标,f 代表一个面,其中x/x/x的第一位表示是哪个顶点,第二位表示该顶点纹理坐标是第几个,第三位表示法线信息是第几个。 3个 x/x/x表示3个顶点的信息构成一个面。

 

本文转载自孙晓磊的计算机图形学系列笔记,有修改,感谢。


人们很容易原谅别人的错误,
却很难原谅别人的正确。

《哈利·波特与混血王子》
——J·K·罗琳(阿不思·邓布利多)