Geometry几何1(Introduction)
本节课主要内容:
1 具体的几何例子
2 不同的几何表示方法
1 几何的例子
不同形状的几何:杯子上的曲线是如何描述的
车子上的曲面如何定义
发动机中的各种叶片、齿轮的位置和大小
衣服、布料:很显然不是一个简单的表面,它是透明的。布料是用很多线一根压一根,通过它们之间的摩擦力所形成的结构,中间还很可能有缝。一根线是由很多不同的纤维(fibre)扭曲拧成不同的股(ply),不同的ply在一起扭曲形成线(thread),然后再用thread编成各种不同的形状
水滴滴在水中,涉及到模拟,模拟任何一个时刻,会有怎样的力造成下一个时刻的水花飞溅。水滴进去的时候会形成一个表面,水是有表面张力的,有一些水花飞溅出去,有些还没有,这应该如何用几何去描述
下图是一个城市,城市复杂在东西多,所以要考虑这么多几何如何存储?之后又应该如何渲染?在《超能陆战队》中就有相关研究,离得远应该如何简化几何模型?如何利用光线之间的连续性?
复杂的几何在很近的距离,可以看到狗身上的一股一股的毛发,以及背上飞起的毛发
近到细胞、蛋白质,可以看到一些微观的几何,所以什么时候用复杂的,什么时候用简单的,中间应该如何去过渡
二维的情况下,比如不同的画,下面是一棵树,有树干、树枝,分形几何
2 不同的几何表示方法
2.1 分类
1)Implicit(隐式)
• algebraic surface
• level sets
• distance functions
• ...
2)Explicit(显式)
• point cloud
• polygon mesh
• subdivision, NURBS
• ...
2.2 Implicit(隐式)几何表示
隐式的几何表示方法不会告诉你具体的点在哪,而是告诉你这些点满足的关系
例:一个单位球在空间中可以写成一个式子:x2+y2+z2 = 1 ,说明给定任何x、y、z,可以判断是不是在定义的表面上
1)定义的推广:只要能找到x、y、z满足f(x,y,z) = 0,就可以认为(x,y,z)就是我定义表面上的一点,要是能找到所有的点,就可以将表面画出来
2)缺点:
很难描述复杂的形状
如果这些点满足的是上面的式子,就认为点在所定义的表面上的,但是如果问哪些点会满足上面的式子?这个式子表达的是怎样的几何?就是一个相对困难的事情
实际上上面的式子表示的是下面这个圆环
3)优点:
表述比较容易,要么用一个函数表示,要么通过一个并不是很明显的方法(距离函数等)定义,存储也更有利
隐式表示的表面很容易和光线做求交的(显式的也并不难)
容易处理拓扑结构的改变
给你一个点,很好判断这个点在不在这个面上,只需要将这个点代入式子,如果是0,就在这个面上;如果为负,就在物体内;如果为正,就在物体外
2.3 Explicit(显式)几何表示
1)对于模型,之前用三角形面就是显式的表示方法,会将面上的点实际表示出来
2)或者通过parameter mapping(参数映射)定义的表面
比如定义了空间uv(下左图),上面任意一个点用坐标uv表示,并且会定义任何的点对uv都会映射到空间中的某一点。也就是说给你一个函数,输入是uv,输出是(x,y,z),将所有uv走一遍,就可以得到所有(x,y,z),下右图为一个马鞍面
例:
这个表示的也是一个圆环
缺点:对于显式的表面,我想判断任何一个点在不在表面上?在表面内还是表面外?就非常困难,比如下图给大家一个显式的公式,问一个点是否在物体内部,是难以下手的,除非你从式子中看出它定义的是一个单位球,将它画出来
2.4 总结
目前来说,没有比较好的方法完全的解决几何的问题,要根据需要选择
2.5 更多隐式(Implicit)的表示方法
Algebraic surfaces、Constructive solid geometry、Level set methods、Fractals...
1)Algebraic Surfaces (代数曲面)
数学公式表达,可是不直观,复杂的形状也很难表示
2)Constructive Solid Geometry(简称CSG,构造实体几何)
通过对基本几何的基本运算(如布尔),来定义新的几何。下面这些布尔运算(并、交、差)可以在各种建模软件中见到
3)Distance Functions(距离函数)
对于任何一个几何,都不直接描述它的表面,而是去描述任何一个点到这个表面的最近距离
下面表示两个球逐渐靠近,发生了形状上的融合,最后形成一个球。这就是通过距离函数做blend(融合)的结果。
距离函数:是指空间中的任何一个点到你想要表述的几何形体上面的一个点之间的最小距离(可正可负,通过signed来表示,正的认为有一个点在物体表面的外面,负的则在物体内部)。
将两个物体的距离函数都算出来之后,就可以将两个距离函数做一个blending(融合),然后再恢复成原来的物体,就可以得到以上的变换
例:应用距离函数
如下图,我们认为它是表达某种几何的边界,假设有一个物体挡住了你能看到的视口的1/3(A图),然后另外有一个物体,或者说物体经过移动后,挡住了左边的2/3(B图),我希望求出物体从左到右移动的中间状态,或者说是两个物体融合起来,做一个简单的线性的blend,左边1/3还是会被挡住,中间的1/3,因为A没被挡住,B被挡住,所以属于一个半被挡住的状态,右边1/3是谁也没挡住。如果看成是两张图片的线性融合,会得到1/3分别为黑灰白这样的状态,但这样并不能表述运动信息
可是我想要得到一个准确的运动过程,比如blend后的结果是左边一半是黑的,右边一半是白的。
我们要先求出A和B的有向的距离函数(SDF,Signed Distance Functions)(都以阴影部分的右边为边界,边界也就是物体表面),定义任何一个点的SDF为该点到边界的垂线距离,靠近边界,值就比较小,远离边界,值就比较大,边界处值为0;在阴影内(也就是物体内部)为负,外(物体外部)为正(SDF图的左边为负,右边为正)。
我们想要得到左黑右白的结果,这里通过相加blend两个SDF,这样两张图在1/2处相加为0,左边还是负的,右边还是正的,恢复成原来的形状,当SDF为0的时候就是边界。所以blend两个SDF,等于是在blend它们的边界,可以得到左边是黑的,右边是白的。
(油管搜索Coding Adventure:Ray Marching会有更清晰的了解)
距离函数的表示能力非常强,如下图,是Shadertoy中的一个例子:
那如何将blend后的距离函数恢复成表面?
将距离函数对应的0的位置全找出来,对应的就是物体的表面。但当距离函数不太好写成解析的形式时,也可以用其他形式表示,如Level Set(水平集)
4)Level Set Methods(水平集)
这个方法的思路和距离函数其实完全一样,仅仅是函数的表述是写在格子上的,函数在不同的格子上有不同的值,只需要找出中间值为0的地方(可以通过双线性插值计算),就可以将函数试图描述的平面提取出来
实际上函数等于多少就画一条线,这和地理上的等高线的概念是一致的
水平集还可以定义在三维空间中的格子,如果有一个三维的纹理表示的是人体不同位置的密度,那从这个三维的信息如何提取出表面呢?可以让密度函数等于某个密度
包括模拟水花四溅的过程,可以通过距离函数或水平集进行水滴和水滴之间的融合
5)Fractals(分形)
分形是自相似的意思,也就是说自己的一个部分和它的整体长得非常像,和计算机科学中说的递归是一个道理
下面第二幅图是一种叫Romanesco的西兰花(罗马花椰菜)
这种类型的几何对于渲染和描述来说都是巨大的挑战,渲染时会引起强烈的走样(因为变化频率太高了)
2.6 更多显式(Explicit)的表示方法
triangle meshes、Bezier surfaces(贝塞尔曲面)、subdivision surfaces(细分曲面)、NURBS、point clouds(点云)...
1)Point Cloud(点云)
不考虑物体是一个表面,而是表面上的一堆点,我把每一个点都都表示成一个点,只要这些点表示得足够细。
之后就会涉及到一个问题,给一个点云,怎么把它变成三角形面或多边形面?
如果点云密度很低,如下图雕塑的下面部分,就很难画出来,所以除了最原始扫描出来的数据,人们很少用点云
下图也是一个点云的例子,左边是一堆点,可以将其变成各种各样不同的面,然后通过各种shading的方法就可以得到一个看上去比较连续的面
2)Polygon Mesh(多边形面)
在图形学中得到最广泛应用的(像三维建模),就是多边形面,特别是三角形和四边形面。
任何的面可以拆成小的三角形,如下图
三角形就涉及到它们之间的连接关系,所以在这个方面就比点云要复杂
那如何用三角形面表示形成的物体的?
下面介绍一种特定的文件格式——The Wavefront Object File (.obj) Format
是一个文本文件,一个文件存储一个物体或场景
把空间中的一堆顶点、法线和纹理坐标分开来表示,然后在一块把他们组织起来形成模型
如下图,描述的是一个立方体:
- 一个立方体空间中的8个点,用左图前8行v x y z的形式表示;
- 立方体的6个面,每个面有一个朝向,也就是6种法线,用右图的前6行表示(图中8行是因为自动建模有冗余的地方,29和30行实际上是一回事,不考虑数值精度的问题);
- 再定义12个纹理坐标(每个面要定义四个点的纹理坐标,就是最多24个,但还有共用的问题)(左图下面部分,但图中也有冗余);
- 再定义它们之间的连接关系,右图下面部分用于表示哪三个点形成一个三角形,用f(face)定义,格式是第几个 v(顶点)的坐标/vt(纹理坐标)/vn(法线)的坐标,比如说第一行表示,用第5个、第一个和第4个顶点,第1个、第2个、第3个纹理坐标,都是第1个法线坐标定义第一个三角形面