计算机图形学——Games101笔记深度解析_第五章 |几何表示|

环境光贴图

可以使用纹理来表示环境光
在这里插入图片描述
但是如果展开就会出现上下扭曲
在这里插入图片描述
解决方法就是用立法体去映射:
在这里插入图片描述
展开来就是这样:
在这里插入图片描述

凹凸/法线贴图(Bump/Normal Map)

很多模型中都有凹凸不平的地方,一般我们不会选择去用模型去把这些小的凹凸给表现出来,因为太过于消耗资源。又因为凹凸不平的地方是靠着光线的明暗去表达的,所以在计算光照的时候我们用一个像uv图那种去储存这种凹凸的光照信息,这就是凹凸贴图。
总结起来就是:

  • 在不增加三角形数量的前提下,为表面增加细节。
  • 只是用于光照计算,不改变真正的几何结构。
  • 使用一张纹理图(bump texture)来描述每个纹素的“高度差”。

二维状态下去修改法线

这个时候我们把上面要做的进行模型简化就是这样:
在这里插入图片描述
光照计算中法线是贯穿全局的,所以我们需要去求改变的后的法线才是关键。
在凹凸贴图中,我们是有高度函数的,这函数负责输出在模型上我们所设置的高度:h(p)h(p)h(p) ,p就是二维中的点。然后我们也知道,在这个平面中,因为没有高度,所以发现直接就是一个垂直向上的(0,1)
有了上面的条件之后我们就可以去求修改后的法向量了。思路很简单,我们只要求得这个函数的切线,然后法向量就是跟这个切线垂直的就行了。但是我们采样是离散化的点,所以整个直接求导去求切线是不可取的,因为我们的输出压根就不连续。但是我们可以基于现在情况来接近。
我们都知道导数的定义是这样的:h′(x)=lim⁡Δx→0h(x+Δx)−h(x)Δxh'(x) = \lim_{\Delta x \to 0} \frac{h(x + \Delta x) - h(x)}{\Delta x}h(x)=Δx0limΔxh(x+Δx)h(x)
那我们只需要用最小变换单位去实现变化率函数的效果,没错这个概念不就是差分吗?
差分代替函数就是这样:h′(x)≈h(x+1)−h(x)1h'(x) \approx \frac{h(x + 1) - h(x)}{1}h(x)1h(x+1)h(x)
在图形学中,这个“+1”指的是在纹理坐标中向前一个像素/texel。

  • 如果像素足够密集(纹理分辨率高),这种近似就非常准确。
  • 这是数值微分中常用的方法(称为前向差分法)。
    最后标准化写出来就是这样:dp=c⋅[h(x+1)−h(x)]dp = c \cdot \left[ h(x+1) - h(x) \right]dp=c[h(x+1)h(x)]
    其中 c 是一个缩放因子(通常与纹理坐标间距相关,可设为1以简化)。

所以我们得到的切线方向的向量就是(变化了一个像素值,高度变化为dp):t⃗=(1,dp)\vec{t} = (1, dp)t=(1,dp)
所以这里的法线方向的向量就为(两者相乘为0):n⃗raw=(−dp,1)\vec{n}_{raw} = (-dp, 1)nraw=(dp,1)
最后归一化(转化为单位向量):n⃗(x)=(−dp,1)dp2+1\vec{n}(x) = \frac{(-dp, 1)}{\sqrt{dp^2 + 1}}n(x)=dp2+1(dp,1)

三维下去改变修改法线

前面我们都是做的二维方向去求法线(从三维方向看就是只求了高,和一个水平方向的法向量),为的就是利用纹理图中的uv的两个水平坐标分别和高度h(p)h(p)h(p) 去求到两个方向切线向量(因为纹理图中的两个方向就是uv方向),最后将两个方向的切向量叉乘就是完成了三维图中的法向量了。

这里我们仍然使用偏导数的办法去求这两者的分法向量:

  1. 与uv相关的高度函数z:z=h(u,v)z = h(u, v)z=h(u,v)
  2. 当uv分别变换时,高度虽其的变化为:
    • ∂h∂u≈h(u+1,v)−h(u,v)\frac{\partial h}{\partial u} \approx h(u+1, v) - h(u, v)uhh(u+1,v)h(u,v)
    • ∂h∂v≈h(u,v+1)−h(u,v)\frac{\partial h}{\partial v} \approx h(u, v+1) - h(u, v)vhh(u,v+1)h(u,v)
  3. 所以两个方向上的切向量:t⃗u=(1,0,∂h∂u)=(1,0,dp/du)\vec{t}_u = (1, 0, \frac{\partial h}{\partial u}) = (1, 0, dp/du)tu=(1,0,uh)=(1,0,dp/du) t⃗v=(0,1,∂h∂v)=(0,1,dp/dv)\vec{t}_v = (0, 1, \frac{\partial h}{\partial v}) = (0, 1, dp/dv)tv=(0,1,vh)=(0,1,dp/dv)
  4. 叉乘然后归一化:n⃗raw=t⃗u×t⃗v\vec{n}_{raw} = \vec{t}_u \times \vec{t}_vnraw=tu×tv
    n⃗=(−dp/du,−dp/dv,1)(dp/du)2+(dp/dv)2+1\vec{n} = \frac{(-dp/du, -dp/dv, 1)}{\sqrt{(dp/du)^2 + (dp/dv)^2 + 1}}n=(dp/du)2+(dp/dv)2+1(dp/du,dp/dv,1)

[!note] 这里我们仅仅是假设整个三维上的法向量为(0,0,1) ,实际情情况需要进行转换。

位移贴图(Displacement mapping)

  • 位移贴图会真实改变模型,会展现出凸起部分的投影。
  • 模型需要足够细致,采样需要足够高。
    在这里插入图片描述

表示几何形状的方法

一种是Implicit(隐式表示):用数学函数或公式定义几何体,而不是明确列出所有点或面。

  • algebraic surface(代数曲面):使用方程(如 x2+y2+z2=1x^2 + y^2 + z^2 = 1x2+y2+z2=1)描述形状。
  • level sets(等值面):通过标量场中某一特定值的等高面来表示,例如图像分割中常见。
  • distance functions(距离函数):例如Signed Distance Function (SDF),用来表示某点到物体表面的距离。

第二种是Explicit(显式表示):显式表示是指直接列出几何的构成要素,如点、线、面等。

  • 用密集的点放在空间中
  • 是某个坐标系下的数据集
  • 每个点包含了坐标、颜色等一系列信息
  • 只要采样足够密集,理论上可以表示任意集合体
  • 如果采样不够密集,将会无法分辨模型的形状
  • 应用:激光扫描

距离函数(Signed Distance Function, SDF)

在这里插入图片描述
图 A:表示一个物体的起始状态(左边1/3为实体,右边为空)。

  • 图 B:表示一个物体的结束状态(右边2/3为实体,左边为空)。
  • blend(A, B):表示通过线性插值(blending)将A和B混合得到的中间状态,边界从左向右平滑移动。

两张图能表达“变化”,第三张是表现“中间状态”

距离函数可以将两个靠近的集合体进行融合。

分型这种递归问题在渲染中会引发严重的走样

[!note] 分型
就是又无数个相同的单位组成一个相同但是更大的单位

在这里插入图片描述
之所以引起走样就是因为采样率不够

多边形信息的储存

使用OBJ格式讲几何体的点、法线、纹理坐标分别表示,然后再表示,面与面的连接关系。

下图定义了一个立方体,有八个顶点(V),六个面(Vn)多个纹理坐标(vt)表示,然后使用f表示他们之间的关系((f V/Vt/Vn)
在这里插入图片描述

贝塞尔曲线

只要求一定要经过起止点,起止点之间的若干个控制点用于控制曲线弯曲的方向,最终形成一条经过起止点的光滑曲线被称为贝塞尔曲线。
通过德卡斯特里奥算法法来绘制贝塞尔曲线。
举个例子:
我们现在要画一个以b0b_0b0 为起点,b2b_2b2 为终点的曲线。
在这里插入图片描述
首先引入一个参数 t (范围为0-1),然后从 b0b_0b0b1b_1b1b1b_1b1b2b_2b2 从开始等分如下:
在这里插入图片描述
然后连接b01{b_0}^1b01b11{b_1}^1b11 ,然后以相同比例从b01{b_0}^1b01b11{b_1}^1b11 等分。
在这里插入图片描述
最后只剩一个点的b02{b_0}^2b02 就是这条曲线上的点,随着t的变化,所有点就会变成一条曲线
在这里插入图片描述
再多点都一样:
在这里插入图片描述
这个时候我们能发现一个规律:
在这里插入图片描述
这看着就是二次方开括号的形式,我们其实就能得到一个通式:Bjn(t)=(nj)tj(1−t)n−jB_j^n(t) = \binom{n}{j} t^j (1 - t)^{n-j}Bjn(t)=(jn)tj(1t)nj
举个例子:
B03(t)=(30)t0(1−t)3=(1−t)3B13(t)=(31)t1(1−t)2=3t(1−t)2B23(t)=(32)t2(1−t)1=3t2(1−t)B33(t)=(33)t3(1−t)0=t3\begin{align*} B_0^3(t) &= \binom{3}{0} t^0 (1 - t)^3 = (1 - t)^3 \\ B_1^3(t) &= \binom{3}{1} t^1 (1 - t)^2 = 3t(1 - t)^2 \\ B_2^3(t) &= \binom{3}{2} t^2 (1 - t)^1 = 3t^2(1 - t) \\ B_3^3(t) &= \binom{3}{3} t^3 (1 - t)^0 = t^3 \end{align*}B03(t)B13(t)B23(t)B33(t)=(03)t0(1t)3=(1t)3=(13)t1(1t)2=3t(1t)2=(23)t2(1t)1=3t2(1t)=(33)t3(1t)0=t3
所以整个曲线的公式如下:bn(t)=∑j=0nbjBjn(t)\mathbf{b}^n(t) = \sum_{j=0}^{n} \mathbf{b}_j B_j^n(t)bn(t)=j=0nbjBjn(t)

贝塞尔曲线性质(n个控制点)

  • b(0)=b0;b(1)=bn−1b(0) = b_0; b(1) = b_{n-1}b(0)=b0;b(1)=bn1
  • 端点切线斜率 b′(0)=(n−1)(b1−b0);b′(1)=(n−1)(bn−1−bn−2)b'(0) = (n-1)(b_1 - b_0); b'(1) = (n-1)(b_{n-1} - b_{n-2})b(0)=(n1)(b1b0);b(1)=(n1)(bn1bn2)
  • 仿射变换后做贝塞尔曲线,与先做贝塞尔曲线再仿射变换,结果一致
  • 凸包性质:贝塞尔曲线一定在凸包(最小围住控制点的多边形)内

分段贝塞尔曲线(Piecewise Bézier Curve)

由于普通贝塞尔曲线一个点的变化会带动整条曲线变化,这样不利于对一段曲线的调整,而且整个曲线不可能有棱角,多样性就不高。

解决方法就是一根曲线由多个贝塞尔曲线组成。
在这里插入图片描述

CN连续

将两个逐段贝塞尔曲线中的两部分连接,连接点被称之为C0连续。 C0C^0C0continuity: 第一段终点和第二段起点相同,an=b0a_n = b_0an=b0
若相邻两个控制点距离连接点相同且共线则该连接点被称之为C1连续(再连接处一阶连续可导)。
C1C^1C1continuity: 还要求切线斜率一致,an=b0=12(an−1+b1)a_n = b_0 = \frac{1}{2}(a_{n-1} + b_1)an=b0=21(an1+b1)
在这里插入图片描述

贝塞尔曲线

与二维的贝塞尔曲线思想类似,但是需要定义两个参数u和v(取代之前的参数t)
先对f(u)进行遍历得到曲线,再嵌套遍历得到曲面f(u,v),类似于两层for循环进行遍历
在这里插入图片描述
在这里插入图片描述

网格操作(Mesh)

分为三种操作:

  • 细分(subdivision):让网格的面数更多
  • 简化(simplification):让网格面数更少
  • 正则(regularization):让网格中的三角形趋近于正三角形
    在这里插入图片描述

Loop Subdivision(Loop是人名,与循环无关)

  • 将每个三角形变为4个三角形
  • 根据权重指定新的顶点位置
  • 新的顶点和老的顶点以不同的规则来改变自己的位置
    在这里插入图片描述
    左边这张图讲的是新点如何生成和计算:展示的是新生成的顶点(odd vertices)的插值规则。在细分过程中,每条边中间会插入一个新顶点。这个新顶点的权重分配是两端原顶点各占 3/8;相邻两个三角形的另外两个顶点各占 1/8。

右边这张图讲的是原来的老顶点怎么调整位置:更新后的位置通过公式计算,其中涉及原位置加权;邻居顶点的位置按余弦函数(cos)加权;公式整体保证了细分后的表面连续性和平滑性(是Loop细分保持二阶连续的数学基础)。

Loop细分只能解决三角形网格的细分问题,对于一般的情况可以采用Catmull-Clark细分。

Catmull-Clark Subdivision

相对于Loop细分的优势:可以用于任意不同的面的细分。

基本概念

  • 非四边形面(Non-quad face):顾名思义。
  • 奇异点(Extraordinary vertex):度数不为4的点。(度数:连接一个点的线段数量)

首先,添加新点

  • 取每个面的一个点(比如重心),取每个边的中点,将所有新添加的点做连接
  • 经过一次细分,所有非四边形面会消失,变成一个奇异点
    在这里插入图片描述
    然后按规则调整位置:
    在这里插入图片描述

简化(simplification)

一般使用边坍缩(edge collapsing)的方法来简化曲面。
在这里插入图片描述
先要介绍二次误差(quadric error),即新的点应该使与它相关联的面的平方和达到最小。简单来说就是计算哪条边探索后对物体的改变最小,具体细节先挖坑。
在这里插入图片描述
简化的步骤如下:(贪心算法)

  1. 假设坍缩每一条边,然后分别得到它们的二次误差。 做为各自的分数
  2. 每次都坍缩分数最小的边,然后更新被影响边的分数
  3. 重复步骤1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值