这里回顾GAMES101 Lecture 12,这一讲会继续介绍曲面。

课程主页:

课程作业:

课程视频:

本讲内容

网格操作中的几何处理部分:

  • 网格细分;
  • 网格简化;
  • 网格正则化;

网格细分是指上采样,即增加分辨率:

网格简化是指下采样,即降低分别率,并且尽量保持形状:

网格正则化(使用相同的三角形,修改样本分布以提高质量):

后续会介绍这些操作的细节。

网格细分

Loop细分

Loop细分是三角形网格的常用细分规则:

  1. 创建更多的三角形(顶点);
  2. 调整位置;

例子:

来看下具体细节。

  • 将每个三角形一分为四;

  • 根据权重分配新的顶点位置;

    • 新/旧顶点更新方式不同;

更新

对于新顶点:

更新策略为:

对于旧顶点(例如此处的6度顶点):

更新策略为:

其中:

  • $n$:顶点的度;
  • 如果$n=3$,那么$u=3/16$;否则$3/8n$;

结果:

注意到Loop细分只能处理三角形,更一般的情形则需要使用其他算法。

Catmull-Clark细分(一般网格)

首先给出两个定义:

  • 非四边形面;
  • 奇异点:度不为4的点;

例如对于下图:

  • 三角形标记的区域是非四边形面,即有2个非四边形面;
  • 紫色的点是奇异点,即有2个奇异点;

每次细分步骤:

  • 在每个面上添加顶点;
  • 在每条边上添加中点;
  • 连接所有新顶点;

细分结果:

那么一次细分后:

  • 有多少个奇异点?
    • 4个奇异点;
  • 有多少个非四边形面?
    • 无;

总结后不难发现:

  • 一次细分后会消除所有非四边形面;
  • 每个非四边形面都会增加一个奇异点;

多次细分的结果:

更新

以四边形面为例,整体更新规则为如下。

对于面上的点:

更新公式:

对于边上的顶点:

更新公式:

对于顶点:

更新公式:

注意到,更新的整体思路是计算周围点的加权平均值。

两种方法的效果展示

网格简化

网格简化的目标是在保持整体形状的同时减少网格元素的数量,对于下图,如果在很远处观察3000个三角形的结果和30000个三角形的结果几乎相同:

那么具体该如何操作呢?一个思路是边坍缩,将边换成一个顶点,然后重新连接:

那么现在的问题就是该选择哪条边?以下图为例:

假设我们需要把上图中的3个点变成1个点,一个方式是求平均值,即得到上图,这样做的问题是,化简后的三角形永远无法覆盖原来的多边形。

为了解决这点,引入了二次误差度量,我们希望:

  • 新顶点到原三角形平面的距离平方和(L2 距离)最小;

根据二次度量误差,我们可以使用如下贪心算法进行边坍缩。

算法

  • 对于每条边,计算二次误差度量;
  • while True:
    • 找到二次度量误差最小的边;
    • 坍缩这条边,并且更新和边顶点相连的边;
    • 如果条件满足,则退出循环;

该算法需要使用优先队列。

效果展示

在继续之前,我们来讨论下阴影。注意到光栅化部分介绍的着色只考虑局部,没有考虑全局,所以很难处理阴影,一个解决方案是阴影映射。

阴影映射(贴图)

  • 阴影映射是图像空间算法:
    • 在阴影计算期间不需要了解场景的几何形状;
    • 必须处理走样;
    • 只能处理点光源,阴影有明显的边界;
  • 关键思想:
  • 不在阴影中的点必须同时被光和相机看到;

基于该思想,介绍如下算法。

算法

基于之前的思想,算法即为从光源和眼睛处分别看两次物体,计算深度。

Pass 1: 从光源看向场景

第一步先从在光源处放一个虚拟的摄像机,判断哪些物体可以看到,即计算深度图:

Pass 2A: 从眼睛看向场景

第二步在眼睛处放一个摄像机,判断哪些物体可以看到,即计算深度1:

Pass 2B: 从眼睛看向场景

对于摄像机看得到的点,计算该点到光源的深度2,如果深度1=深度2,则表示该点不在阴影中,可以从下图中理解这点:

可视化阴影贴图

阴影映射的一些问题

  • 硬阴影(仅限点光源);
  • 质量取决于阴影贴图分辨率
    (基于图像的技术的普遍问题);
  • 涉及浮点深度值的相等比较;
    • 浮点数的相等判断很困难;

硬阴影 vs 软阴影

区别:

硬阴影边缘非常锐利,软阴影边缘过渡很平滑。为了解释产生软阴影的原因,需要介绍两个概念:

  • 本影:完全看不到光源;
  • 半影:部分看到光源;

软阴影就是半影,以日食图为例:

黑色区域即为本影区域,灰色部分为半影区域。