GAMES101 学习12——曲面与阴影

lutianfei 发表于 2022/05/09 18:28:47 2022/05/09
【摘要】 一、曲面 1.1 Mesh subdivision 网格细分在计算机图形学中,网格细分指的是给定已知粗糙表面(由网格构成),通过某种方法生成光滑的表面。为什么需要细分?因为对于简单模型来说,当纹理的频率高于模型的面数时,如果直接使用高分辨率的纹理会导致失真(纹理出现拉扯的情况),这时就需要更加精细的模型,由此引入了网格细分。网格细分本质上往模型引入更多的三角形,它是递归的,它通过一定的细分...

一、曲面

1.1 Mesh subdivision 网格细分

在计算机图形学中,网格细分指的是给定已知粗糙表面(由网格构成),通过某种方法生成光滑的表面。为什么需要细分?因为对于简单模型来说,当纹理的频率高于模型的面数时,如果直接使用高分辨率的纹理会导致失真(纹理出现拉扯的情况),这时就需要更加精细的模型,由此引入了网格细分。

网格细分本质上往模型引入更多的三角形,它是递归的,它通过一定的细分方案重新对原有网格进行划分,生成更多的面和边来让表面变得光滑。同时,它还会根据附近旧顶点的位置计算网格中新顶点的位置,在某些细分方案中,旧顶点的位置也可能会改变。

image.png

1.1.1 Loop Subdivision

image.png

这是一种针对三角形网格进行细分的方案,主要步骤分为两步:①添加顶点 ②更新顶点位置

  1. 添加顶点
    对于每个三角形网格,分别在每条边的中点上添加顶点,此时会把该网格分成四个三角形。将添加的顶点看做新的顶点,原来的顶点看作旧的顶点,这两种顶点分别用不同的更新方案对位置进行更新。

image.png

  1. 更新顶点位置
    ①新的顶点:
    image.png

如图所示,考虑一般情况,假设新的顶点为白点,那么它一定被两个三角形所共享,分别找到这两个三角形。设和白点同边的顶点为 A ,B;不同边的顶点为 C,D;那么新的点(白点)的更新方案为: 3 / 8 ( A + B ) + 1 / 8 ( C + D ) 3 / 8*(A+B)+1 / 8*(C+D)

②旧的顶点:
image.png

如图所示,以白点为例。不考虑新增加的顶点,首先找到它所有相邻的三角形中旧的顶点,设为 u , n表示白点的度数(在图论中,一个顶点在图中的度 (degree)为与这个顶点相连接的边的数目),白点的更新规则如下:
( 1 n u ) o r i g i n a l P o s i t i o n + u n e i g h b o r P o s i t i o n S u m (1-n*u) * originalPosition + u*neighborPositionSum

originalPosition 表示这个点原来的位置,neighborPositionSum表示相邻点位置的和。这个公式的意义为:旧的点的更新需要考虑邻接点和自身的权重,当邻接点较多时,那么自身的权重就可以减少一些。

1.1.2 Catmull-Clark Subdivision (General Mesh) 为例

Loop Subdivision 适用于三角形网格细分,而 Catmull-Clark Subdivision 更加一般化,适用于非三角形网格。

①定义:
quad face:四边形面
Non-quad face:非四边形面
Extraordinary vertex :奇异点(degree != 4,即度不为4的点)

如图所示: 非四边形面指的就是没有四个顶点的面(图中橙色三角形),奇异点指的是度不为4的点(图中紫色圆点)

image.png

细分规则:
在每个面中添加一个顶点(面的重心),在每条边中添加一个中点。对于每个面来说,将面中添加的顶点与边中添加的中点依次连接;得到的结果如图所示:
image.png

由此可以得出 Catmull-Clark Subdivision 的性质:
在进行第一次 Catmull-Clark Subdivision 后,细分前的非四边形面消失了,且新增了奇异点数,增加的顶点个数为细分前非四边形的面数。在后续的 Catmull-Clark Subdivision 中,不会再增加奇异点。

顶点更新公式:
Catmull-Clark Subdivision 将顶点分为三类进行更新,分别是 Face point、Edge Point 和 Vertex Point,如图所示:

image.png

1.2 Mesh Simplification 网格简化

网格简化指的是通过某种方法,将复杂的网格变得简单,即减少一部分顶点和面,同时还需要保留原有网格的形状与外观。在游戏中,复杂的网格模型往往包含更多的顶点和面,但是如果这个模型距离相机较远,我们就只需要简单的包含物体轮廓的模型来显示。
image.png

1.2.1 edge collapsing 边塌缩

边坍缩指的就是将网格中的两个点捏成一个点,有将某个点合并到另一个点,也有将两个点合并到他们的中点,如图所示:

image.png

如何选定需要进行坍缩的那条边呢?这里就引入了二次度量误差来进行寻找。

1.2.2 Quadric Error Metrics (二次误差度量)

本质是使得坍缩后得到的顶点到原本邻接面的二次误差最小,而这里的二次误差采用的就是坍缩后的顶点到原本邻接面的距离的平方和,所以我们只需要找到使得二次误差最小的那条边,对其进行坍缩即可。

image.png

需要注意的是每次坍缩会影响邻接边的二次误差,所以需要对邻接边的二次误差进行重排。
因此在工程实现上需要使用优先队列或者堆结构。

1.3 Mesh Regularization 网格正规化

网格正则化通过修改顶点的位置,让模型中的三角形更加趋于正三角形(更平滑)。
image.png

二、shadow mapping 阴影(光栅化阶段)

Shadow mapping 是图形学中计算阴影的过程。它本质上是一种图像空间的算法,即在计算阴影的过程中不需要知道场景中的几何关系。
image.png

理解 Shadow mapping 中最核心的一点是:如果物体不在阴影中,那么它肯定能被相机看见且被灯光照射到。此处说的是硬阴影(点光源情况下,边缘锐利),软阴影(有过度)后边会涉及。

阴影按类型可分为硬阴影和软阴影,硬阴影是由点光源产生的,软阴影是由范围光源产生的。

2.1 硬阴影

渲染步骤:
第一步: 从光源处出发,假设光源处有一个相机,计算光源处看向场景的深度,渲染成深度图保存(记录看到点的深度);
image.png

第二步: 从实际相机(眼睛)出发,计算相机看向场景的深度后,投影回光源处的相机空间(常称为光源空间),并与第一步得到的深度进行比较。如果第二步得到的深度大于第一步得到的深度,那么说明该点在阴影内,反之不在。
image.png

2.1.1 一个实例:用Shadow mapping的方法生成 shadow map 并应用它生成shadow

①从光源看
image.png

② 记录深度(Depth buffer/z-buffer)
image.png

③真正的相机看到的,对比shadow map和实际深度的关系
image.png

→④最终场景
image.png

2.1.2 硬阴影存在的问题

①为什么需要投影回光源空间?
因为两个相机看到的深度需要处于同一空间下进行比较

②如何将第二步看到的顶点变换到光源空间?
将第二步中得到的处于世界坐标系下的顶点乘以光源空间下的 PV矩阵即可(投影和视角)

③在计算阴影时的比较问题
如图所示,非绿色部分表示阴影,图中阴影部分明显出现了较多的噪声。这是因为深度缓冲区的深度采用的是浮点表示,而浮点比较会存在精度问题,无法直接判断相等。

2.2 软阴影

软阴影是由范围光源产生的。相比硬阴影,软阴影的边界更加模糊。
image.png

软阴影是由自然中叫penumbra(半影)造成的。
软阴影一定是因为光源有大小(点光源不可能有软阴影)

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请发送邮件至:cloudbbs@huaweicloud.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。