目录
1.1.1 Loop细分(Loop Subdivision)
1.1.2 Catmull-Clark细分(Catmull-Clark Subdivision (General Mesh))
(4)算法规则(FYI: Catmull-Clark Vertex Update Rules (Quad Mesh))
(3)坍缩一条边之后,周围的边会变化,周围边的二次度量误差也会变化,怎么办?
1.3 网格正则化(Mesh Regularization (same #triangles))
1 网格(Mesh)-续
网格操作:几何处理(Mesh Operations: Geometry Processing)
·网格细分(Mesh subdivision)
·网格简化(Mesh simplification)
·网格正则化(Mesh regularization)
1.1 网格细分(Mesh subdivision)
1.1.1 Loop细分(Loop Subdivision)
表面细分不仅要增加三角形的数量,而且使模型的表面更加光滑。
注意,Loop细分和循环没有任何关系,只是因其发明人叫Loop。
loop细分仅能对三角形网格进行细分。
下面介绍loop细分的步骤:
(1)将三角形分割成4个
比较简单,如图分割即可
(2)调整新、老顶点的位置
·对于新产生的顶点
该新顶点位于某一条边上,且有两个三角形共用这条边。对于两个三角形的顶点,若顶点落在这条公共边上,则称之为A,B;若不在公共边上,则称为C、D。新顶点的位置就由这A、B、C、D四个点加权得到:3/8 * (A + B) + 1/8 * (C + D)
·对于原来的老顶点
老顶点肯定被多个面共用,这里定义几个量:
n : 老顶点的度,就是与老顶点相邻的边数
u : 常量,影响最终结果与老顶点本身位置的相关程度。
调整后的顶点位置由老顶点本身位置、共用面上的其他顶点位置共同加权决定:
n越大,老顶点相邻的边越多,老顶点自己的权重就越低;n越小,老顶点相邻的边越少,它自己的权重就越高,越能保持在之前的位置。
(1 - n*u) * original_position + u * neighbor_position_sum
(3)Loop细分的结果展示
1.1.2 Catmull-Clark细分(Catmull-Clark Subdivision (General Mesh))
对于更一般的情况,比如四边形网格,或者三角形和四边形网格同时存在的情况,Loop细分就无法解决了。此时Catmull-Clark这两个人提出了他们的细分算法。
(1)概念
四边形面(quad face)
非四边形面(Non-quad face) :三角形、五边形等等
奇异点(Extraordinary vertex):度(与该点相邻的边数)不为4的点。
(2)基本步骤
Step 1: 每条边取其中点
step 2: 每个面取其重心
step 3: 将这些新点都连接起来
问,在经过了一次变换后:
·此时有多少个奇异点?
答:4个。除去之前的两个度为5的奇异点,新引入了两个度为3的奇异点。在非四边形内的新建点都是奇异点,因为它要和非四边形的边的中点连接,边不是4条,中点也不是4个。
·有多少个非四边形面?
答:0个。
(3)性质
从之前的问题可以得到:
Catmull-Clark细分在第一次变换时,增加了非四边形面数个奇异点,之后不再增加。
(4)算法规则(FYI: Catmull-Clark Vertex Update Rules (Quad Mesh))
·新产生的点
分两类,面上的点(Face point)和边上的点(Edge point)
分别有自己的计算公式:
·老点
对周围的点和自己做加权平均
1.1.3 网格细分的整体展示和收敛情况
1.2 网格简化(Mesh simplification)
在一些情况下,并不需要过于精细的面。
比如移动端性能的限制、美术风格的要求,远距离物体的显示等。
这就需要对网格进行简化,以达到某种目的。
下面介绍一种网格简化的方法-边坍缩
1.2.1 边坍缩(Edge Collaps)
(1)如何坍缩,能让坍缩之后的图形和之前的图形比较相似?
要坍缩哪些边?
·这里提出二次度量误差(这里的二次是平方的意思)
坍缩任何一条边后会产生一个新的顶点,我们需要把这个点放到某个位置上,使二次误差最小,从而确定这个点的位置。这就是二次度量误差法。
二次误差:这个新顶点到原来几个面的距离平方和。
(2)如何确定边坍缩的顺序?我们先要从哪个边开始坍缩呢?
·从二次度量误差最小的边开始坍缩.
(3)坍缩一条边之后,周围的边会变化,周围边的二次度量误差也会变化,怎么办?
·动态更新周围边的二次度量误差。
基于这些操作的特点,我们使用堆/优先队列来作为此算法的数据结构。
总的来说,我们先保证了局部的最优性,然后推广到全局(全局不一定最优),这是个典型的贪心算法。
1.3 网格正则化(Mesh Regularization (same #triangles))
把网格大小形状变得差不多,这样能使表面更平滑。
2 阴影图(Shadow Mapping)
阴影作为一个引入光线追踪的例子出现在这里。
一切涉及到全局光线传输、阴影的问题对于光栅化来说都不是很好做。
之前我们说的着色就是单对一个物体来说的,周围的物体不会影响它,自然,阴影也无法计算和形成。如何用光栅化绘制阴影呢?这就是接下来要说的Shadow Mapping。
2.1 概述
·Shadow Mapping在图像空间进行处理
在计算阴影的时候不需要知道场景的几何信息。
它有自己的问题:走样现象。
·关键思想:如果点不在阴影里面,那么这个点会被光源和相机同时看见。
经典的shadow mapping 只能处理点光源照射的物体,这种阴影被称为硬阴影。
2.2 Shadow Mapping步骤
step1:从光源看物体,得到光源能看到东西,并且生成了一幅图,记录看到的任何点的深度
step2:从另外的眼睛位置出发,得到眼睛能看到的点,将这个点投影回光源视角下它应该出现的位置,得到它到光源的深度。然后比较两张深度图。深度图中值相同的点就是可见的,深度值不相同的点就是不可见的。
2.3 Shadow Mapping举例
左图是案例场景,可以看到有一个点光源位于图片左上角。
带阴影和不带阴影的图片对比如右图所示。
(1)从光源看向场景
记录光源视角下的深度图
(2)从实际的相机位置看向物体
用矩阵将这些相机视角的点通过矩阵变换到光源空间,然后比较实际深度和之前光源视角下的深度图上对应的深度。深度不一样的点就位于阴影中。
对比后产生的阴影好像不太干净,这是由于浮点数精度误差所致。
也有很多人在致力于解决这个问题。
有人说:不求相等,只求大于
有人说:引入bios,实际深度不仅要大于记录的深度值,还要大于深度值+bios。
仍无法完美解决。
最终结果:
分析:
如果Shadow Map的分辨率很低,场景分辨率高,则会发生走样现象。
Shadow Mapping需要渲染两遍,开销比较大。
总结:
虽然有很多不足,但Shadow Mapping仍然是
主流的阴影计算方式。
它是众所周知的渲染技术,早期动画(注:如《玩具总动员》等)和几乎所有3D电子游戏的基本阴影技术。
2.4 Shadow Maps的问题
· 硬阴影(点光源),软阴影会考虑到光源的大小,然后考虑从光源的哪个地方看物体。
· 质量取决于阴影贴图的分辨率(基于图像的技术的一般问题),阴影质量一般会指阴影贴图的分辨率。
· 涉及相等比较的浮点深度值:尺度、偏差、容差等问题。
2.5 硬阴影vs软阴影
影子在物理上有本影(Umbra)和半影(Peumbra)之分
本影:完全看不到光源
半影:可以看到部分光源
软阴影其实就是物理上的半影。
上面这幅图说的是“日食”现象,地球上的黑色部分完全看不见(本影),灰色部分可以看到一部分太阳(半影)。
如果有软阴影,那么光源一定有大小,不是点光源。
3. 课程路线回顾
光栅化和几何部分都已经学完了,下节课开始光线追踪。
计算机图形学的学习有个高度的整体把握很重要。