Games101学习笔记
本文最后更新于240 天前,其中的信息可能已经过时,如有错误请联系作者

Games101学习笔记

01 Overview

课程内容主要包含

  • 光栅化(rasterization):把三维空间的几何形体显示在屏幕上。实时(30fps)是一个重要的挑战。
  • 几何表示(geometry):如何表示曲线、曲面、拓扑结构等
  • 光线追踪(ray tracing):慢但是真实。实时是一个重要的挑战。
  • 动画/模拟(animation/simulation):譬如扔一个球到地上,球如何反弹、挤压、变形等

02 Linear Algebra

点乘可以判断前后,如下图

叉乘可以判断左右和内外,如下图

  • 上图左:通过叉乘结果正负,判断左右
  • 上图右:通过点是不是在三边的同一侧,判断是否在三角形内外

03 Transformation

自信点,你都会了

几种二维上的基本变换

缩放变换

镜像变换

切变

旋转

平移变换

但通常在齐次坐标下进行。所谓齐次坐标就是用n+1维向量表示n维坐标。在2D transformation下就是用3维向量表示2维坐标(在x、y轴外增加了w轴

合在一起成为仿射变换

逆变换即逆矩阵

基本变换组合为符合变换

三维情况下的变换

3D 的缩放、镜像、切变基本和 2D 可直接类比。但是旋转会有一些麻烦。这是一种解决方案,将任意旋转分解为绕坐标轴旋转。

并且这里需要注意坐标系,课程中使用的是右手坐标系,部分API和软件会使用左手坐标系(说的就是你UE和Unity)

绕任意轴旋转的方程

视图或摄像机的变换

MVP起手

View Transformation

三维摄像机有 7 个维度

  • 位置:3维
  • 朝向:3维
  • 画面旋转:1维

通常用三个向量进行对应

  • 位置向量
  • 朝向向量
  • 上方向量(由于一定和朝向正交,所以会冗余2维)

正向考虑 摄像机变换 的矩阵是比较麻烦的一件事情

但反向考虑则比较容易,所以可以通过反向考虑,配合矩阵求逆得到结果。

Projection Transformation

投影变换本身是一个降维变换,图形学中主要针对于将三维投影至二维

3D 至 2D 的投影主要有两种:正交投影和透视投影

正交投影的操作比较简单,直接丢掉坐标中的 Z 分量即可。但通常需要 canonical ,即首先将视图空间中心平移至 原点,再缩放为标准正方体。

下图左边是投影结果规则化 右边是正交投影结果移动到原点位置

Perspective Transformation

透视投影本质上是将空间投影至一个点,但在过程中用一个平面(如胶片)截下。而对于透视变换,可以考虑将其先变换为正交,再用正交投影。

透视投影矩阵就等于正交投影矩阵乘以透视变正交矩阵

透视变正交矩阵

04 Rasterization

这一章主要解决的就是光栅化和反走样问题,首先就是在通过MVP操作之后,我们得到一个标准立方体,接下来需要进行视口变换,将标准立方体的x和y与屏幕坐标x和y对应,然后就是真正进行光栅化操作,以每个三角形为单位,逐个进行绘制:通过遍历图像上的像素点(这里有一些加速处理,比如bouding box,扫描线等等),然后判断像素点的中心点是否在三角形中(叉乘判断,若三者叉乘符号相同,便是在内部),若在三角形中,则首先需要对该像素进行深度测试,若该像素深度小于深度缓存的深度即表面通过深度测试,此时便对该像素进行着色,也就是给该像素赋予颜色值,如此往复,最终实现绘制。若要使用反走样技术,比如MSAA,就通过超采样实现,但这会带了更多的开销,不同的反走样技术实现起来也不同。解决了之前理论课一直没弄明白的点:先模糊再采样的本质是什么?即改变颜色再着色,而先采样再着色则是先着色再改变周围像素块的颜色。

这节课主要介绍光栅化本身,和现代光栅化的对象–三角形 相关的一些操作。即在经过将场景进行基本变换后,如何将变换后的正方形内容呈现在屏幕上。

首先弄清楚什么是屏幕。

再弄清楚像素,Pixel 原来是 picture element 的浓缩版。

定义屏幕空间,和每个像素的坐标表示方法

三角形

选用三角形作为基本形体单位的原因。

但应该如何把一个三角形给光栅化呢?

一种方式是对每个像素去采样,中心在三角形内即标内部颜色,否则标外部颜色。

判断像素是否在三角形以内可以用叉积判断点是否在三条边(全逆时针或全顺时针)的同侧。同即内部,否则外部。

对于刚好在边界的情况,通常只要自己定义清楚就行,在哪边都不回有太大影响(openGL 会根据是否是左上的边进行区别选择)

一些加速遍历的方法

一些实际机器上的像素排列。

三星 Galaxy S5 的排列方式可以节省一些像素点。绿色偏多是由于人眼对绿色更敏感。

一些其他的成像算法。比如打印机用这种排列,目的主要是为了节省油墨。

抗锯齿(Antialiasing)

事实上仅仅用上节提到的采样方法,会得到这样的结果。非常不像我们想要的三角形。

甚至还有更严重的事情发生,比如采样得到了完全不同的花纹,这已经不是锯齿的问题了。

还有这种运动错觉(同偶尔看到车轮反转的错觉)

这些问题出在哪呢?

都是采样造成的问题

对于其中的锯齿问题

如果考察照相机(照片一般不会有这种问题),会发现位于边界的每个像素会吸收边界两边的光子,得到一个混合的结果,使整体看上去边界顺滑自然。

采样时也理应可以做到人工边界模糊,达到接近相机的效果。

比如先模糊,再采样。

效果还不错

但做这种事情时需要注意顺序:需要先模糊再采样,而非先采样再模糊

针对于前面的现象,应该如何解释呢?

这可以追溯至傅立叶变换

越高频的信号要求越高频的采样,否则会出现走样

对于图片而言,也可以进行二维的傅立叶分解

频域上的两条直线线主要由于做变换时等效于将图片横纵重复了很多次,而边界往往是非常难匹配的,即对应了高频变化。

频域上越远离中心,在时域上越对应突变的边

低频则对应模糊

卷积定理:时域上的卷积,对应频域上的乘积。而频域上的卷积,对应时域上的乘积。

卷积定理的例子

而对于一个时域上的函数a,对其进行固定间隔采样的操作实质等效于用一系列冲击函数c去和a乘,最后得到e。

根据卷积定理,时域上的乘积对应频域上的卷积。

假设a对应的频域为b。而冲击函数c对应的频域为d。b和d卷积后则理应得到f。

这时我们可以看出如果原始函数比较低频,即对应的频域函数局限在较小区域,则在采样之后不会有重叠。

否则,则会在频域上有重叠,进而对于重叠部分无法区分是重叠导致的,还是原始信号天生如此,造成走样。

据此,分析反走样的原理也就比较容易了。

要么提高采样频率,相当于增大频域上的间隔,使其不容易重叠。

也可以通过模糊化操作,使其不包含高频信号,以至于不会重叠

除了模糊化以外,还可以采用对单个像素密集采样求平均的方法来减少锯齿或走样问题。

也能达到很好的效果,不过与此同时也需要付出计算代价。

最后介绍一些当下的反走样技术。

05 Shading

Z-Buffer

知道了如何光栅化一个三角形,再介绍如何光栅化一个场景。

为了解决远近覆盖问题。容易想到的一种处理方式是画家算法:由远往近依次画。

画的时候近处物体覆盖远处物体。

但这样做也是有局限的。特别是有些情况下难以对三角形进行远近排序。

对三角形难以远近排序,对像素却是可以做到的,所以有了 Z-Buffer 算法。每个像素用 Z 最近的光栅化值。

实际上等效于在记录 RGB 三色的同时,加入 Depth 的记录。

由于只用找最小,而不是排序,所以 Z-Buffer 复杂度仅 O(n)

且为了更高的运行效率, Z-Buffer 已经集成在了各个 GPU 内部,直接硬件层面支持。

使用上述的方法可以得到下面的效果,但这样是远远不够的。

我们想要下面的效果

为什么会这样呢?为什么“相同”颜色的方块的每一面颜色不一致呢?

容易发现,是环境光的影响。

我们看到的物体画面是由物体本身和环境光共同作用得到的结果。所以需要考虑环境光。

这个共同作用的方式,则体现出了物体的材质。

那什么是Shading,在本课中则对应着将材质应用于物体本身的过程。

Blinn-Phong模型

Blinn-Phong 是经验总结下的容易实现的材质模型。

其原理来自于观察,类似于绘画中的三大面。可以把物体表面分为高光区域、漫反射区域、环境光区域。

需要注意的是,Shading 有局部性,只关心每个三角形本身,不关心三角形相互的作用,

Shading ≠ shadow

关于漫反射

Blinn-Phong 模型中,漫反射的颜色受到三个部分影响

  1. 材料的固有色,对应一个系数(可为颜色向量) kd
  2. 反光点和光源的距离光源,距离越远亮度月底,对应于 I/r2
  3. 表面法线与光线的夹角,夹角越大则单位面积能反射的光子理应越少,一旦大过 π/2 则意味着背光,不再漫反射。于是对应于 max(0,n∗l)

仅利用漫反射模型,且单一灰阶的固有色即可渲染出下面的效果。

关于高光

高光对应于镜面反射,摄像机越接近光源的镜面反射的出方向,则应接受到越强的镜面反射光。

度量这个“接近度”有一个聪明的比较容易的计算的方法,是比较光源方向和摄像机方向的中间方向(很容易计算)和法线方向的夹角,夹角越大则越不接近。

且对于这个接近度可以取一个次数 p,使整体更容易调整,且接近想要的效果。

p 越高,高亮区域越小。通常而言会用到 100~200。

加入了高光项后,可以得到下图效果,且可以看出两个参数在调整时对结果的影响

关于环境光

对于暗部,并不希望全黑,所以可以加入环境光项,当然,并没有办法保证有光,也不可能环境光处处相同,所以这只是个不符合物理的趋近方法

最后综合 漫反射、高光、环境光 三项后可以得到下图效果

频率

同样是应用 Blinn-Phong,也可以由于面向对象不同得到不同结果,上方三张图依次对应于

  1. 低频:面向三角形
  2. 中频:面向顶点,三角形内部应用重心坐标差值
  3. 高频:面向像素

面向三角形的 Shading 计算量最小。但对于不够高面又光滑曲面的物体而言会不再光滑

对顶点着色,并应用差值

对每个像素着色。这里的 Phong Shading 对应于着色频率,而非 Blinn-Phong 着色模型。

这几种着色频率对应足够高面的模型而言表现是近似的。所以如果足够多面,应优先选择更低频的着色方式,减少计算量。

对逐顶点着色而言,是需要获得顶点的法线的。可以采用相邻三角形法线的简单平均,或者根据三角形面积加权平均。

对逐像素着色而言,则需要获得每个像素的法线方向,通常使用自己和附近面的法线用一些方式加权平均。

渲染管线

将一次渲染分成几步,大部分集成在 GPU 内部,成为硬件逻辑。部分可以编程。

比如一开始先处理顶点(等效于处理三角形,因为三角形被顶点决定)

光栅化

对片面的测试和处理(也可以算作光栅化的一部分)

Shading 根据不同着色频率可以对应至这两个步骤。

纹理映射也属于 Shading 一部分

纹理映射

将二维的表面和一张二维的图逐点一一对应

一些纹理是可以上下左右拼接的,做到重复利用

用对面三角形面积占比计算

用公式计算

直接采样,又会有锯齿问题

可以通过双线性插值(Bilinear)一定程度解决。当然还可以用 Bicubic 三阶差值(取周围16个点),得到更好的效果

双线性插值的方法

当纹理过大也会有问题,问题源自一个像素对应了纹理上太多像素

超采样可以解决,但计算量过大

Mipmap是一种对贴图进行预处理后很好的一种方式

使用 Mipmap 的情况下,如果直接为每个像素点指定一个层级,会让过渡比较硬。

可以用相邻两个层级进行线性插值

效果更好

不过 Mipmap 依旧不能解决这个问题

这是由于 Mipmap 擅长解决正方形的采样,但不擅长非正方形的采样

所以后来还有 Ripmaps 可以支持任意正放的长方形采样

还有 EWA 更加复杂,但可以支持把任意形状分成多个圆形。但也意味着多次查询需要的更多开销

贴图的其他应用

记录环境光

环境光可以记录在球上,但球的两极会有扭曲,所以一般记录在正方体的表面

还可以记录表面相对高度,即凹凸贴图(与法线贴图目标近似,但计算和优势不同)

二维上计算法线的方式是查分求导再旋转。

三维也类似

还可以在处理顶点时事实地改变顶点位置。

不过这要求模型的精细度足够高,以保证有足够多的顶点可以随贴图改变。目前 Direct X 支持这种情况下动态改变模型的精细度。

纹理也可以是 3D 的,甚至是函数化的

还可以用于预烘培,提前计算一些阴影啥的

或者记录三维信息

评论

  1. shenmiren
    Windows Chrome
    9 月前
    2024-8-01 16:05:10

    这就开始了???

    来自天津
    • Avatar photo
      R1ckYan
      博主
      shenmiren
      Windows Chrome
      9 月前
      2024-8-01 16:06:18

      旭哥不在,没别的事情可以干啊

      来自山西
  2. shenmiren
    Windows Chrome
    8 月前
    2024-9-22 16:59:48

    不发新的,原来在这偷偷更新是吧😡

    来自天津

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇