[[toc]]
1.几何例子
2.几何的多种表示方法
我们有不同的方式来表示几何,这里主要分为两大类:Implicit隐式几何和Explicit显示几何
Implicit:
- algebraic surface(代数表面)
- level sets(级别集)
- distance functions(距离函数)
- ...
Explicit:
- point cloud(点云)
- polygon mesh(多边形网格)
- subdivision, NURBS
- ...
每个不同的表示方法适合于不同的任务/类型的几何形状
[1]implicit隐式几何
在一个三维空间,表示隐式几何的点并不是实际给出的点,而是给你满足一系列条件的点(例如一个单位球表面上所有的点都满足)
对于一个更为通用的表现显示,就是通过变换,将条件函数右边变换为0,然后我们要是能找到所有的点,我们就能把表面化出来,比如下面的例子:
根据上面隐式的定义可以很快发现其缺点:隐式表面采样可能很困难:
例如我给一个函数关系式:
那么如何获得满足的点呢
显然可以发现,有些任务使用隐式表示很困难
但是,它也有它的优点:例如判断一个点在不在一个面上(或者判断某个顶于某个几何的关系)
判断点与上面球体的关系,这就很简单了,将点代入上面的函数:
-
则点在表面上
-
则点位于球体内
-
0,位于球体外
是不是有点简单,那下面举一些图形学中常见的所有隐式几何的例子
Algebraic surfaces代数曲面
曲面是 x,y,z 中多项式的零集(用数学公式去绘制形状),上面举的例子就是属于这一种
Constructive solid geometry(CSG)建设性实体几何形状
通过一些列几何的基本几何的集合运算来定义新的几何
也就是通过基本/简单几何创建复杂几何,同时这也是很常见的操作,例如各种制图软件都是支持这种方式的
Distance Functions
对于任意一个几何,不直接描述表面,而是描述空间中任何一个点到几何体的最小距离。
距离函数会返回空间中任何一个点到物体表面的最短距离,我们只需要找出距离为0的所有点,即可得到这个物体表面,而距离小于0的点代表在物体内部,距离大于0的点代表在物体外。
距离函数返回空间中任何一个点到一个几何形体上面的最小距离(可为负:点在物体内部)
例如上面的过程:将上面的两个球的距离函数计算出来,然后对这两个距离函数做一个Blending(融合),然后在把它恢复成原来的物体(就是距离函数都返回0时的点)
An Example:混合(线性插入)移动边界
符号距离函数(Signed Distance Function,简称SDF)或定向距离函数(Oriented Distance Function,简称SDF)
Shader中使用距离函数(Distance Function)绘制二维图形
Level Set Methods水平集
像距离函数类似的封闭形式的方程很难描述复杂的形状(不容易使用公式去写),但是还是可以通过某种方法表示出来就可以了,利用Level Set Methods水平集方法(如下图)
- 其实和等高线一个原理。。。。。
- 其实和距离函数类似,其实就它函数的表达形式不同而已
水平集在医疗上的应用(三维):恒定的组织密度
物理模拟中的水平集:
[2]Explicit显式几何
所有的点直接给出或通过参数映射给出
例如,下面的参数映射,把u和v映射导右边的式子中,最终求得相应得值
与隐式几何不同,判读一个点在几何体得表面、外部、还是内部就比较困难了
如何判断点得位置呢?
这就比较困难了,所以说隐式和显式几何的优缺点是互补的,没有最好的表示几何的方式,我们得根据实际情况的需要去选择。
对几何得表示方法不仅仅是上面的那些
下面说说常见的显示几何表示的应用
Point Cloud
- 最简单的表示方法,只通过一些点集(x,y,x)表示即可
- 很容易表示任何几何形状
- 适用于大型数据集(>> 1 point/pixel)
- 通常将其转化为多边形网格
- 在采样不足的区域很难绘制(点不够)
Polygon Mesh多边形网格
- 存储顶点和多边形(通常是三角形或四角形)
- 更容易进行处理 /仿真,自适应采样
- 更复杂的数据结构
- 图形中最常见的表示形式
Wavefront对象文件(.OBJ)格式
- 通常用于图形研究
- 只是一个文本文件,指定顶点,法线,纹理坐标及其连通性
3.曲线
[1]Bézier Curves
贝塞尔曲线:用一些控制点来定义曲线曲线,而这些控制的要满足一定的规则:
- 曲线起点方向为方向,终点的方向为方向
- 曲线一定要经过起始点,其他点不一定
de Casteljau算法
de Casteljau(德卡尔斯特里奥):给定任意多个点将贝塞尔曲线上的点出来算法
详见另一篇文章
[2]splines样条
图形学中不仅仅应用到贝塞尔曲线,还有其他许多类型的曲线,比如说:splines样条
- 由以系列控制点控制的曲线,且满足一定的连续性
- 简单而言:一个可控的曲线
样条中常见的有B-splines样条
-
属于贝塞尔曲线的一个扩展,它比贝塞尔曲线能力更强(比如贝塞尔曲线如果你动了一个控制点,那么整条线条的变化是很大的),而B-splines则具有局部性的,可控的调整某个范围的变化,当然分段的贝塞尔曲线同样具有这一性质,但是B—splines则不用分段
-
基样条的简称
-
比Bezier曲线需要更多的信息
-
满足 Bézier 曲线的所有重要性质(即超集)
-
但是,B-splines很难学。。所以这里就不深入了
4.表面
[1]Bezier表面
使用两个t,这里我们使用来定义来实现贝塞尔曲面,让其扫描成一个面即可
这样就可以通过参数来确定曲面上具体的点了,和之前使用de Casteljau Algorithm来实现
- 首先确定一个参数,这样可以获得4个点
- 然后在确定另外一个参数v,这样就可以确定处曲面上具体的点了
这里可以联想到之前的贝塞尔曲线的相关问题,也可以发现所有贝塞尔曲面也会面临着类似的问题,例如:如何多个平面相交等问题等等,这里就先不展开深入
[2]Mesh格网面(三角形和四角形)
在计算机图形学中应用的比较多的还是mesh网格面,所以还得着重学习学习——网格操作: 几何处理部分
- Mesh subdivision网格细分
- Mesh simplification网格简化
- Mesh regularization网格真规化
5.网格面处理
[1]Mesh subdivision网格细分
一个非常重要的操作
如何增加更多的三角形,使图形更加光滑(类似于增加图形的分辨率)
三角形网格的一般细分规则:
- First, create more triangles (vertices)
- Second, tune their positions
Loop Subdivision
-
把每个三角形分成四个
-
调整新/旧顶点的位置来让这个模型变得光滑(新顶点/旧顶点的更新方式/算法不同)
对于新的顶点的更新位置:
- 例如白点为新顶点
- 将其位置跟新至以使其更平滑(加权平均)
对于旧顶点的更新:
- 一部分根据相邻的老的顶点的平均值,另外一部分是根据其自己的位置
- n:vertex degree(图论中的度)
- 老顶点更新到:
例如:loop 细分的效果
总结:先细分,在调整
Catmull-Clark 细分(通用网格)
对于不同网格的细分——例如一个图形中有三角网格细分,正方形网格细分,那么这时loop就不太适用了(loop细分只能用在三角网格细分)
细分后:
How many extraordinary(奇异点) vertices?
- 4个(有两个是原本的奇异的,增加了2个,因为划分了三角形)
What are their degrees?
- 3(新的奇异的的度为3)
How many non-quad faces?
- 0(无——一次细分之后所以的非四边形们都改进型了)
Catmull-Clark 细分性质:
- 在一次细分后增加的奇异的数为非四边形面数(之后奇异的数就不会增加了)
catmull-clark顶点更新规则(Quad网格)
- 将物体表面上的点细分为三类
- Face point(在面中间的新点)
- Edge point(边的中间的点)
- Vertex point(老的点)
[2]Mesh simplification网格简化
目标:减少网格元素的数量 同时保持整体形状
做网格简化的目的主要是为了在确保用户体验的情况西进一步的提高性能,也就是在不影响体验的情况下进行简化
Collapsing An Edge边坍缩
一种常见的网格简化的方法Collapsing An Edge——把两个或多个顶点捏成一个
那么那些边是重要的(不能把它黏在一块),那些边是不重要的(可以把它黏在一块),也就是为了使模型变化更小,为此引入了一个度量——Quadric Error Metrics(二次误差度量)来解决该问题
Quadric Error Metrics(二次误差度量)
如图所示,将中间三个黑点坍缩成一个蓝点之后,就完成了所谓的简化效果,但是如何确保其进行简化的同时使图形变化最小
新顶点所在的位置与原来各个平面的垂直距离的平方和即为二次误差度量。如果能够使得这个误差最小那么对整个模型样貌修改一定程度上也会较小。
所以曲面简化的流程为:
- 计算模型的每条边的二次测量误差
- 选取二次测量误差最小的边做坍缩
- 坍缩完之后,与之相连其他的边的位置会改动,更新这些边的权值
- 重复上述步骤,直到到达终止条件
因为需要求最小值,同时又要动态更新,所以以上过程可以用优先队列(堆)
这是一个标准的贪心算法,并不能达到全局最优解,但是仍然有不错的效果
[3]Mesh regularization网格真规化
6.Shadow Mapping
Shadow mapping——draw shadows using rasterization
-
是一种图像空间算法
- 在阴影计算中没有场景几何知识
-
Shadow mapping核心思想:
- 将点看出处于两种状态:能被光源照射得到的和能被camera看得到的(非0及1的过程)
- 这种阴影称为硬阴影
- 仅适用于点光源情况下
Pass 1: Render from Light
第一步从光源找到能看到的点,从而生成一幅图,这个图不需要做着色,把不同位置它所看到的点对应的深度记录下来。
从光源看(虚拟相机)向所有的点,并记录你看到的所有的点的深度是多少——进而得到一幅深度图
Pass 2A: Render from Eye
-
从相机视角看某个点,然后将相机看到的某个点的反投影回去然后计算处黄色线的深度,然后和之前在点光源处(虚拟相机)获得的该点的深度进行对比,如果是相同的那么就表面该点是看得到的(也就是不是在阴影下并且能看得到的点)
-
如下图为从点光源看到的情况和相机视角下看到的同一点的深度不同的情况下。这样的话可以判断该点是在阴影下的(相机能看到,点光源看不到)。
example:
看一个实际案例(shadow mapping实现)
先从点光源方向开始(生成深度图)
然后比对(这里并不是简单的比较是否相等,其实还包含很多问题需要处理:例如浮点数精度问题等)
Problems with shadow maps
- 阴影(只支持点光源)
- 质量取决于阴影图分辨率 (基于图像的技术的一般问题)
- 涉及到浮点深度值的等式比较,意味着尺度、偏差、公差等问题
软阴影vs硬阴影