# 现代计算机图形学基础

## 现代计算机图形学基础

### **L1 Overview of Computer Graphics**

如何判断游戏画面质量好不好，看画面是否足够亮就可以。其中涉及到的技术知识是全局光照，如果全局光照做得好，画面就会亮。

#### **图形学的挑战**

与虚拟世界真实的互动效果

对真实世界的理解

新的计算/展示方法

#### **技术上的挑战**

投影/曲线/表面等数学知识

光照/阴影的物理知识

3D 形体的展示与变换

动画与仿真

**光栅化**：把 3D 的物体显示在平面上，实时（30fps）计算机图形学的主要应用

光线追踪-慢，新的技术：**实时光线追踪**

#### **图形学 VS 计算机视觉**

视觉：一切需要猜测的内容。比如，根据图片识别出人和物体/深度学习。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fc83d6defc68ab262ca47018f850cdbed872b071e.png?generation=1605580681723011\&alt=media)

### **L2 线性代数入门**

#### **叉乘**

可以用来判断点在向量的左边还是右边，拓展，通过这一应用可以来判断点是否在三角形内部：与边的三个向量叉乘都为正或者都为负

#### **矩阵**

点乘和叉乘都可以写成矩阵的乘法形式

a，b 点乘 等于 a 的转置乘 b

a，b 叉乘 等于 a 的对偶矩阵（dual matrix）乘 b

### **L3/L4 Transformation**

#### **Why Study**

Modeling 模型变换

Viewing 视图变换

#### **齐次坐标**

二维中，点的坐标可以扩展为(x, y, 1)，向量的坐标可以扩展为(x, y, 0)。向量之所以是 0，是因为向量具有平移不变性。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F878889ed48bbcd538f2f0efaad4cf548a08da547.png?generation=1605580708718368\&alt=media)

#### **仿射变换**

仿射变换=平移+线性变换

用于仿射变换的齐次矩阵是先线性变换，再平移。

#### **投影**

正交投影/平行投影，不会造成近大远小的现象

透视投影，更加贴近人眼的成像

#### **平行投影**

将一个立方体通过仿射变换，变为：左右在 x 轴，上下在 y 轴，远近在 z 轴。先平移，再缩放。

#### **透视投影**

平行线不再平行。

(x,y,z,1) = (xz,yz,zz,z)(z!=0)

透视投影的视角是一个四棱锥，平行投影的视角是一个长方体。直接写出透视投影的转化矩阵会比较困难，可以考虑将四棱锥投影的棱台压缩成一个一个长方体，然后再进行平行投影。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F3f5bef2a0ebdc993b1404d505dec3dcd0b842e0f.png?generation=1605580708277740\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fdf88aa8b79ea3a41daafe75dca0857654a79ab94.png?generation=1605580682744306\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fae2017e8e1ecf20454c93e246d8ace9c786d8c69.png?generation=1605580709640053\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F66f8981265ac41a9e37f7ea380a7b396861d723b.png?generation=1605580703561994\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F02aa0c9adc01058e49516b045119bd35801b58e5.png?generation=1605580709217941\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F57d985f5682e6dbf72d770c1534148ce374eee0e.png?generation=1605580710043286\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F50651e9516940fea222e68352e0b8eb389bf8846.png?generation=1605580707716794\&alt=media)

### **L5/L6 Rasterization 光栅化**

#### **屏幕**

典型的光栅成像设备

是像素的一个数组

数组的大小就是分辨率

**光栅化**：把三角形画到屏幕（像素）上的过程

**Pixel**：picture element

#### **屏幕空间**

屏幕的坐标系，左下为原点。所有的像素可以用一个坐标来表示，像素中心在方块的中心。

需要将\[-1, 1]空间映射到\[width, height]的屏幕空间。

**视口变换：**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff0fe6c0c15c712a293b83bbdc7b8c075370281e9.png?generation=1605580708515409\&alt=media)

#### **光栅显示设备**

阴极射线管 CRT

电子经过偏转，会打在不同的位置上。

隔行扫描：在一个时刻，将图像每隔一行进行绘制。奇数行绘制当前图像，偶数行绘制下一帧，利用视觉停留可以使图像看起来是连续的。可用于视频压缩，会造成画面撕裂，尤其在高速运动的画面中。

**现代显示器 Frame Buffer**

使用内存的一块区域（显存）来存储图像信息。

LCD 液晶显示器

液晶的排布可以影响光的极化（光的偏振方向），光通过液晶时可以改变光的方向。

LED 发光二极管

电子墨水屏

刷新率很低，看起来很自然。

#### **三角形的特殊性质**

三角形是最基础的多边形，任何多边形可以拆分为三角形

三角形做插值方便

三角形的边界定义很明确

三角形一定在一个平面上

#### **光栅化的重要步骤**

**像素中心点与三角形的位置关系**

采样

函数离散化

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F584e3e9ce4bde65025ccad10433a60391508c702.png?generation=1605580704590745\&alt=media)

判断点是否在三角形内

顺序叉积的符号相同

边界处理

不处理或者特殊处理

缩小屏幕点遍历区域

包围盒

**锯齿/走样**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F936afe6f9e750d6cf3c383fff31421c313992a10.png?generation=1605580675727703\&alt=media)

锯齿产生原因：采样。

采样可在空间中进行，也可在时间中进行。

**采样**

采样会产生一系列问题：锯齿，摩尔纹，车轮效应。

本质原因：信号变化太快，采样速度跟不上信号变化速度。

**抗锯齿/反走样**

先模糊，再采样

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb2a4b8bac28fa2a3977dd69dc24fc8b91c682e81.png?generation=1605580695680632\&alt=media)

**频域**

傅立叶变换可以将一个函数以 sin 和 cos 的线性组合来表示。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F584bfb590267fff89610e322796d669ddb88e9e9.png?generation=1605580678664664\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fa506243fd35415249b6485c94246d3a9faea14fd.png?generation=1605580676741346\&alt=media)

可见傅立叶级数的各项频率不同，可以理解为一个函数在各个频率上都有其分解的值，傅立叶变换就是把函数变为不同频率的段。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff3173e288d04a57f5ae1bbaaf6b50c55cdbb908d.png?generation=1605580696754333\&alt=media)

同一采样速率，频率越高，采样的准确性越低。

走样在频率上的解释：下图频率完全不同的函数使用同一个采样函数获取到了相同的结果。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F7f5d513124e1525f96cf4c6af8c7fbcbb6ee591b.png?generation=1605580709100293\&alt=media)

使用傅立叶变换可以将图片从视域变换为频域。

滤波：将特定频率的信号去掉。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F453ffe47cf3f22931f1f5a1135cebb9bb299d8b7.png?generation=1605580711420594\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ffeb71b508570e4aefa23fb1f61739b5a13bc68bd.png?generation=1605580701411444\&alt=media)

视域上的卷积等于频域上的乘积

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F5a1f11cfec665fbbb3286edec7f706958dd21bec.png?generation=1605580677780888\&alt=media)

采样：重复频域上的内容

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fcfa47911733b4d841122c0444808591d20686fa7.png?generation=1605580705189330\&alt=media)

**抗锯齿方案**

MSAA Antialiasing By SuperSampling

细化像素点，用更多的点来采样一个像素点，取点的平均值（模糊操作）作为像素的值。近似覆盖率，没有提高分辨率。

FXAA Fast Approximate AA

后期处理，先得到锯齿图形，找到图形的锯齿边界，再把边界换成没有锯齿的边界。

TAA Temporal AA

找上一帧的边界，复用上一帧的像素值。相当于 MSAA 在时间上的分布。

**超分辨率 Super resolution**

把小分辨率图拉大为大分辨率，但是不想产生锯齿。

DLSS：深度学习，根据采样猜测每个分辨率点的像素

**可见行（遮挡关系）**

**画家算法**

按照远近顺序来画：先画远处的三角形，再画近处覆盖远处三角形。排序 O(n logn)，但是有一种情况无法使用画家算法：

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F0d8ec7377b2c838f8fc2c5a64c4af695e1a4aef5.png?generation=1605580712116047\&alt=media)

**深度缓存**

在光栅化的时候，生成另一张图，图只存深度相关的信息。遍历每个三角形的每个像素，当深度小于存的值时，更新深度信息，存储更小值。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb7fe5f24e785c2dbeeba2f68556528a5a86da42f.png?generation=1605580681048639\&alt=media)

认为每个三角形都不会特别大，那么一个三角形会覆盖常数个像素。复杂度为 O(n)。

### **L7/L8/L9 Shading 着色**

当三角形画出来后，它的颜色并不是初始的颜色，人眼更愿意接受有光影效果的，明暗不一的效果。

#### **局部光照**

只看光照点，不关心阴影等。

三个方向：光照方向，法线方向，观测方向。

**Blinn-Phong 反射模型**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb4fa39ddfbc5d4a5f41c3b1109eabb824896635e.png?generation=1605580706949109\&alt=media)

**高光 Specular Highlights**

什么时候能看到高光：观测方向与光照镜面反射方向接近时---平面法向方向与半程向量接近。

半程向量：向量 v 与向量 l 的角平分线单位向量，如果 v 和 l 是单位向量，基于菱形性质，那么半程向量为

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F1804e3fc9aa5ee68a817989630972445905eb3d8.png?generation=1605580684544646\&alt=media)

如何衡量两个方向是否接近：点乘结果。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F8d4da381f55a4ca3554744f027258ee70e522502.png?generation=1605580694903057\&alt=media)

为什么有幂 p：一次函数容忍度太高，实际高光的范围不会太大。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fe9d2251f6efe18243f64624af9722a6ecd216bc1.png?generation=1605580709248981\&alt=media)

**漫反射 Diffuse refection**

光照照在平面，产生各个方向的反射。与观测方向无关。

漫反射与光照方向与平面法线的夹角有关（平面接受光照的能量）。

Lambert 理论，平面接受的光照的能量和光照方向与平面法线的夹角的余弦成正比。

平面接收的能量与点光源的距离的平方成反比。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fa2ef6615b4fbdf19416bf1353cb42df00a94225c.png?generation=1605580709949322\&alt=media)

#### **间接光照，环境光 Ambient lighting**

假设各个地方的环境光都相同，是一个常数。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff8302c30da5c6008782eaca832f8dba7204c67bf.png?generation=1605580714192556\&alt=media)

**Shading Frequencies 光照频率**

把光照点应用在一个平面 flat shading

应用在顶点，插值计算 gouraud shading

应用在每个像素，phong shading

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F4cc849499931490c6a3f84a6015163e7ba4c61cd.png?generation=1605580708526324\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F2e6a7372eb7e90d68f53c451f3820a7ea03d504c.png?generation=1605580674759248\&alt=media)

如果模型足够复杂，即三角形足够多，那么 flat shading 依然会有很好的表现，而且计算量更小。

逐顶点的法线：对点相邻的平面的法线做面积加权平均。

**图形管线（实时渲染）**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F610fb7b41c14ceeaa9235ecdb13c0c857e315c4c.png?generation=1605580706512814\&alt=media)

Shader: 顶点和像素如何着色，现代 gpu 中可编程。

顶点：Vertex Shader

像素：Fragment Shader

Compute Shader：做任何形式的计算，不局限与图形学内部，general purpose gpu => GPGPU

**纹理映射**

定义任何一个点的基本属性（如漫反射系数）。

任何一个三维物体的表面都是二维的，纹理就是一张图，把纹理蒙在一个三维物体上，就是纹理映射。

纹理坐标系，uv，u 和 v 在\[0, 1]。

纹理无缝衔接：tiled（Wang Tiled）。

先对三角形顶点应用得到纹理的 uv，利用插值获取三角形内部的像素的纹理坐标。

#### **如何在三角形内部做任意属性的插值**

为什么做插值：很多操作基于三角形顶点，希望在三角形内部得到平滑的表现。

插值可以应用于纹理坐标/颜色/三角形法线等。

**重心坐标**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F6063d91d5127059601651c5736f6c012425a0063.png?generation=1605580704365060\&alt=media)

重心坐标可以通过面积比值求出

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F9575bff7ac5864a4f75cda4da2565e600d12f1f8.png?generation=1605580693967710\&alt=media)

重心投影之后可能会改变，三维空间中的属性要在三维空间中计算，再映射到投影平面中，不能先投影再插值。

#### **纹理放大**

纹理的一个像素：texel，当纹理的分辨率小于屏幕的分辨率时，多个 pixel 会映射到同一个 texel，会拉大纹理显示。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F2f97e19e4eca19714263cb5c9c529ddbf298b40e.png?generation=1605580707568424\&alt=media)

**双线性插值 Bilinear**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F762fac1c8066a4828b4057c5af2adefa579c550c.png?generation=1605580706729999\&alt=media)

**双向三次插值 Bicubic**

取周围临近的 16 个点，再做双向插值。每次用 4 个做三次插值，非线性插值。

**纹理过大**

纹理过大时，进行映射，会出现走样问题。产生原因：屏幕一个像素覆盖一个像素，但是对应纹理上覆盖了一片区域。如果直接使用纹理上的值，相当于只用一个点标示了一片区域

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F7027cb06f30fbe4e6fdc995a3e4912fe6eb72ead.png?generation=1605580705845503\&alt=media)

使用超采样可以优化图形显示，但是开销非常大。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F9d42e5afa0eae97ff32e65ee97ce5e7842219b71.png?generation=1605580700863284\&alt=media)

点查询：给出一个点，查询像素多少。

范围查询：给出一个区域，需要查询这个区域的平均值。

**Mipmap**

允许做范围查询，快/近似/只能做方形查询。预先生成一系列图。只多了 1/3 的存储空间。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F652b2b38f45d7440517dd5e56ef33f8b006e457f.png?generation=1605580707345406\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F4db796096bd2eca57370b96f1532859e3d2dd9c7.png?generation=1605580709884632\&alt=media)

把相邻两个像素映射到纹理空间中，求出纹理空间两个点的距离可以作为正方形的边长。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff735c25b896b53b6949bceb50411a8a78ff90a4b.png?generation=1605580710887001\&alt=media)

中间层插值：三线形插值，先对相邻两层对点做双线性插值，再对层与层中间的值进行插值。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F2d2fa727ab351ee8ec0087819d8274f30699bdb9.png?generation=1605580710030756\&alt=media)

三线形差值带来了过分模糊的现象，远处的细节丢失。

**各项异性过滤 Anisotropic Filtering**

可以查询矩形区域，不限制为正方形，Mipmap 相当于取了对角线。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F3909fc61eceda46320e76aef3fac131827f00826.png?generation=1605580711203313\&alt=media)

不规则查询：多次查询，使用圆形进行覆盖。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F2f06c5f422b33821451b5d3b720f46bdac6d6953.png?generation=1605580693926169\&alt=media)

#### **纹理应用**

在现代 GPU 中，纹理就是一片内存，可以快速做点查询和范围查询。

**Environment Map**

环境光照/环境贴图。

**Spherical Environment Map**

将环境光记录在球上，但是不是一个均匀的描述，展开后两级会出现扭曲。

**Cube Map**

将环境光记录在正方形的六个面上，不会出现扭曲，但是需要额外的计算，计算在哪个面上。

**贴图会影响着色**

应用凹凸贴图，可以定义任意一个点的相对高度，高度变化，法线就会变化，因而 shading 也会变化。shading 变化导致明暗对比，人眼感知为凹凸不平。

**Bump Mapping 凹凸贴图**

把任何一个像素的法线做一个扰动

2D 法线扰动：

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff1d7389d8de98ea060d080e3f90b1c67320cf2b9.png?generation=1605580683870025\&alt=media)

3D：

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F1d6ee66b24492b7f793a71b811670704ec583c29.png?generation=1605580707546931\&alt=media)

**Displacement mapping 位移贴图**

会真实改变三角形顶点的位置，要求三角形划分足够细。动态曲面细分：根据需要进行部分三角形的划分。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Faa84e7161c5ca1e221932511f29fef820778d586.png?generation=1605580687012299\&alt=media)

**三维纹理**

定义了空间中任意一个点的值，定义了三维空间中的噪声函数。

三维纹理与体渲染。

**保留 shading 结果**

保存计算好的 shading 结果，保存为一个纹理，乘以环境光遮蔽。

### **L10/L11/L12 Geometry 几何形体**

#### **隐式几何**

把点进行归类，只要能满足某些关系，就能判断是否在几何所描述的面上。

隐式表示很难描述几何的形状，但是判断点是否在面上是非常容易的。

**Algebraic Surface**

通过代数方法表示。

**Constructive Solid Geometry CSG**

形体可以由基本几何通过运算得到。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F9c66d9bca43fc194cd7d0f72ee56b4ebf6c0b523.png?generation=1605580690788646\&alt=media)

**Distance Functions**

空间中的任意一个点到想要表述的几何形体上的任意一个点的的最小距离。对物体做 blend，就是对距离函数做 blend。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F6e020dc61dff08e3487b3e43b57d87625ca05013.png?generation=1605580688786294\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F05a7d8004c6e1005b7adbbc504e91d693b38cce0.png?generation=1605580709697096\&alt=media)

**水平集**

距离的表述描述在格子上，应用在 3D 纹理中，可以找到描述等于某个值的面。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F7e824ecdc0f61dc81958491f1521f9b73acc4d4b.png?generation=1605580710430883\&alt=media)

**分形**

相同的图形内部也有同样的图形构成，如菜花和雪花。由于变化频率太快，会产生强烈的走样。

#### **显式几何**

直接给出，或者通过参数映射从 uv 映射到 xyz。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F05450b52e6034e8d785225c05f13e9a590bc0b19.png?generation=1605580689734181\&alt=media)

**Point Cloud 点云**

表面是由各个点组成，只要表示的足够细，就能表示出面。

**多边形面**

三角形面来表示。

**The Wavefront Object File .obj**

用文本来存储顶点/法线和纹理坐标，再定义三角形的组合信息。

#### **曲线**

**贝塞尔曲线**

用控制点定义一系列曲线。

对贝塞尔曲线做仿射变换可以对控制点做仿射变换，再重新画出曲线。

贝塞尔曲线一定在所有控制点的凸包中。

凸包：包括所有点的最小多边形

**Piecewise 贝塞尔曲线**

分段，每一段使用部分控制点。

分段控制点如何保证平滑：导数连续（大小和方向）。

C0 连续：端点是另一段的控制点。

C1 连续：一阶导数连续，端点控制点比值 1:1。

**Splines 样条**

连续的曲线，由一些控制点控制

B-splines B 样条：对贝塞尔曲线的扩展，贝塞尔曲线中改变一个控制点曲线所有都会收到影响，B 样条提供局部的能力，改变一个控制点最多影响曲线一定的范围。

Nurbs：B 样条的扩展，引入了权重。

#### **曲面**

**贝塞尔曲面**

在两个方向上，分别应用贝塞尔曲线。

**曲面处理**

**Mesh Subdivision 网格细分**

细分：分出更多三角形，三角形的位置发生变化。

分出更多三角形：连接三角形边中点，可以细分出 4 个三角形。

**Loop 细分**

新老顶点分别根据不同的规则进行位置调整。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ffe342f610abad31a82853251074c68d96b377d74.png?generation=1605580704520273\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F31d577771a4275548d0b811e079ca7505ec3f107.png?generation=1605580707482278\&alt=media)

**Catmull-Clark 细分**

Loop 细分只能针对三角形网格进行细分，不能对一般网格进行细分。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F12eb6d824d97c14cd19a3c7c32c2ca7488c0eb39.png?generation=1605580693544100\&alt=media)

取面中心的一个点，和各个边的中点，然后连接起来。

细分之前的非四边形面，一次细分后，会变成一个奇异点，之后的细分奇异点不会增加。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F3739cadf2f9f9bb8478be1d2ceed3e3bf4e8a03e.png?generation=1605580687699727\&alt=media)

**Mesh Simplification 网格简化，用更少的三角形**

如果图像离得很远，不需要使用非常多的三角形来表示，而且计算能力会节省。

**Collapsing An Edge 边坍缩**

每一条边，都可以通过计算得出二次误差度量，选取最小的来进行坍缩。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ffeb18891140b5333471f984f9f0aaf25500deae1.png?generation=1605580679841723\&alt=media)

但是坍缩过程中会影响周围其他边的度量变化，需要更新其他边的度量，使用堆来表示。

使用贪心算法由局部最优解推进到全局最优解。

**Mesh regularization**

用更类似正三角形的三角形来划分。

### **L13/L14/L15/L16 Ray Tracing 光线追踪**

光栅化最大的问题：不好表示全局的效果，做阴影困难；glossy 反射（毛玻璃）；间接光照。

光栅化很快，但是质量比较差。

光栅化用来做实时，光线追踪用来做离线。

如何用光栅化做阴影：Shadow Mapping，只能处理点光源，硬阴影。核心思想：不在阴影的点能被摄像机和光源同时看到。1. 先从光源看向物体，生成一幅图，记录任何点的深度。2. 从真正摄像头出发，把点投影回光源，计算出光源与点的深度，比较两个深度是否一致（bias 解决数据精度问题）。

#### **硬阴影 vs 软阴影**

硬阴影：边界非常锐利，非可见即可见。

软阴影：光源有一定的大小，存在部分被遮挡，部分可见光源一部分的地方，根据阴影与物体之间的距离，虚化程度也不同。

#### **光线**

在实际计算中，认为：

光线沿直线传播

光线互相之间不会干扰

光线从光源出发，不断反射到人眼中

光路可逆，可认为人眼发出的光经过反射也会打到光源上。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb3a787e0f9b7ffc78eab2d1350b50c7d18dbe7ec.png?generation=1605580697105979\&alt=media)

#### **Whitted-Style Ray Tracing (Recursive)**

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F98fdf34914a4ed868954dc4c98e7e8eac985a45a.png?generation=1605580704529349\&alt=media)

**光线与物体表面的交点**

光线定义为射线，交点即在光线上，也在球上。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb8d0e13bf301c52344270d9a969ebbd0fbf2a87b.png?generation=1605580706041914\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F4c61ffc2238a97a3b76bf8844c0975e673fb315c.png?generation=1605580706866593\&alt=media)

推广到隐式表面的交点，简化为求实数正根

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F26c1ffc9611b92ba1b2bfc41cc8c8c54330a232f.png?generation=1605580711022801\&alt=media)

**在 2D/3D 中，在形状内找一点，画出一条射线，那么它和形状的交点一定是奇数个；如果在形状外，那么交点一定是偶数个。**

光线和三角形求交：简化为光线与平面求交，再判断点和三角形的关系。

平面可以通过法线+一个点来定义。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fd04ec58c9b080b54dd3dde6987e3ddab1973f3ff.png?generation=1605580707916027\&alt=media)

如何通过一次计算得出光线和三角形的交点：Moller Trumbore Algorithm 利用重心坐标

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F97957fa607ec49c9682396fe40325573347555af.png?generation=1605580706042621\&alt=media)

**光和表面求交如何加速**

最基本的实现：和场景所有的三角形进行计算

**包围盒/体积**

用规则的物体包围物体。如果光线不和包围盒有交点，那么和物体也不会有交点。包围盒可以认为是 3 对对面夹出来的。包围盒用横平竖直的 Axis-Aligned 的盒，用于加速计算 t。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fd292943b51a6e9f2207adacc065feb1005935941.png?generation=1605580699447588\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fe2e783e4740d299136df2868c04f7402baa08e59.png?generation=1605580710891561\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F47e834068a60728e01568418d4f68bd2213334ea.png?generation=1605580707888144\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F60aa9dd9bdfab2a7c3758c6c1d88f745a0299280.png?generation=1605580706189551\&alt=media)

得出包围盒后，将内部划分为格子，并判断哪些格子内有物体。

光线和格子求交比较简单，先求出光线相交的每个格子，判断格子内有没有物体，再判断光线与物体有没有相交。

如何找出相交的每个格子，一个简单的做法是判断光线方向，比如光线向右上，那么随着光线的传播，只需要判断右方或上方的格子是否和光线相交即可。

不适合格子的场景：大规模的空白和大规模的集中。

**空间划分**

Oct-Tree：八叉树，把空间划分为八个格子，每个格子继续划分，直到格子内部只含有足够少的物体。

BSP-Tree：空间的二分，每次选取一个方向，非横平竖直。

KD-Tree：八叉树在更高维度是 2 的 n 次方，KD-Tree 和维度无关。每次按某个轴进行顺序循环划分。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fde2fc3df172de7125d485c9746c0380294d31bba.png?generation=1605580700478111\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F4cf86e88407a41739e2b2bce597b6bc853f7d63f.png?generation=1605580697970389\&alt=media)

物体是否和盒子相交判断比较困难，一个物体也有可能出现在不同的 AABB 中，因此 KD-Tree 并不直观。

**物体划分**

**Bounding Volume Hierarchy BVH**

把所有物体进行分组划分，对每一组再重新计算包围盒，直到每一组剩余较少包围盒。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff70f4593fdcb6c991065be03367ee370c6849684.png?generation=1605580705574060\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fe929820aa6af8db9d104b6c943ff0130668044e2.png?generation=1605580711876171\&alt=media)

可以按照最长的轴进行划分，也可取某个轴中位数的三角形，保持树的平衡。

如何找到一堆数的第 i 大的树，O(n)可解决，快速选择算法。

#### **辐射度量学 Basic radiometry**

Radiant flux：辐射通量，单位时间的能量，功率

intensity：强度，功率除以立体角

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F20417dab3bb164b33732660731d12bbdd8629d50.png?generation=1605580711347608\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fd888371a3143686526e3dc8f52de626f932578de.png?generation=1605580709827027\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F5285f0eb9642f3bbcfc569ae938a5d087e934111.png?generation=1605580709040716\&alt=media)

irradiance：功率除以单位面积（光线垂直方向）

radiance：光沿着一条线的分布，功率在单位立体角单位面积的微分

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fe8b7cb960daece37fd6a34939359dcca58d31ae2.png?generation=1605580705523905\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff7bd9e9c380c165316230cdf12707bdfbbb14892.png?generation=1605580699245355\&alt=media)

**反射方程**

双向分布反射函数 Bidirectional Reflectance Distribution Function BRDF

某个方向的功率向各个方向的分散的功率分布。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fac9911c9860a1e80652cc697acd4a248a78d3246.png?generation=1605580706209819\&alt=media)

**渲染方程**

光不只弹射一次，出射光线也可能变为入射方向。辐射的光：反射的光+自己发的光。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F13b481ff642b89d243a51cbe5642f615aee91620.png?generation=1605580709313664\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F591ed521f53cc2900ae408e7c3ea77c3be1bbbd5.png?generation=1605580707753975\&alt=media)

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F19aa8a6d2177fcca5ae038fe819f305c30f82772.png?generation=1605580709246571\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F98059b27cc8056704af3fe12b2f7fc2e6772a0db.png?generation=1605580708139205\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F8400b3488eeb87e4286c2d70a8fa4452b9440e69.png?generation=1605580711347781\&alt=media)

**全局光照**

概率密度函数

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb75d296ca9d3d22f52ada3067cb4a45463adab32.png?generation=1605580703575791\&alt=media)

#### **蒙特卡洛积分 Monte Carlo Integration**

给定一个函数，计算 a 到 b 的定积分，得出来是一个数。如果函数比较复杂，不好计算，如何把数算出来。

在区间中取很多点，把点的 y 坐标与 b-a 相乘，认为围起来的长方形面积代表当前的积分值，只要取的点足够多，其平均值就为积分值。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F6bcc5c05b960cd58999e875e1abd46e1e8cc45f8.png?generation=1605580703716673\&alt=media)

#### **路径追踪**

Whitted-Style 光线追踪做了许多错事：Glossy(有些模糊，但也部分镜面反射)难以进行/未考虑漫反射的出射光线(color bleeding)。正确的应该是积分值--蒙特卡洛积分。

直接光照：

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F37cc9c9f191600293e64508facfc73f28baa0de3.png?generation=1605580698389307\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F11a02a6f04320702a35bbe3541b4682a67bc4a3c.png?generation=1605580706550173\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F69e99623e2018554580ab0b4f5c0ae92cf228010.png?generation=1605580710294179\&alt=media)

间接光照：

用 n=1 来做蒙斯卡洛积分，称为路径追踪。

Ray Generation

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Faf2afd0df5671ae67366e807aaef8ce29061b948.png?generation=1605580710766539\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fdfcc8e59271dab1b8d3a6592c1d7305b1b315951.png?generation=1605580708562446\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F63852f2cb50351322a983ce1b1c82dfc3b41d615.png?generation=1605580709941465\&alt=media)

但是还存在一个问题：递归不会停止。

俄罗斯轮盘赌 Russian Roulette RR：以一定的概率取消追踪，将最后的值除以概率，就能得到期望

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F06f16f3009a08088b07b1de4d9c28a6b91059afe.png?generation=1605580685726199\&alt=media)

由于路径追踪的算法在一个点上是均匀打出各个光线，那么如果一个点打出的光线少，打到光源的概率就低。如果在光源上进行采样，就可以保证光线不会浪费。把渲染方程改写成对光源上的积分。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F36a0126bbb9da2e635324f7a2565e51b7bfc30b9.png?generation=1605580706467155\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fc4e74036bc7a8ad997c65b796df53bfbeb3c8f2d.png?generation=1605580711325395\&alt=media)

把贡献分为光源（需要判断光源是否被遮挡，用一条光线做碰撞检测）和其他间接光照，光照不需要赌，间接再赌。

![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F276f16912d50acb900c18774cc7dc432869f9abc.png?generation=1605580706301800\&alt=media)![Generated](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ff0fe9bd3bda7d7f4ba5b4f8d463af9679d500a37.png?generation=1605580710983937\&alt=media)

## L17 Material and Appearance 材质与外观

材质=BRDF ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F24c6fdf4b7097810cc6307c8b9316c44eb41303c.png?generation=1606040564903954\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fad8c111343f3553c5d63df5734adb746f00546bf.png?generation=1606040562205472\&alt=media) BTDF：折射 BSDF：散射（BRDF+BTDF）

### Fresnel Reflection/Item 菲涅耳项

折射和反射的权重会和视角与法线的夹角有关，考虑车窗玻璃，旁边的玻璃可以看到外面，看前面的窗子，看到的是反射。 真实的菲涅耳项计算比较复杂，可以使用来 Schilick's approximation 简化： ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F790c79d81f0e5af48710b107f1cb60a46ad5257e.png?generation=1606040561066890\&alt=media)

### Microfacet Material 微表面模型

近看凹凸不平的材质远看也是会比较光滑，是表面的总体的状态。在一个微元下，是镜面反射，近处的几何拉远看也可以作为一种材质。PBR Physically Based Rendering ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F1e0d081a0931492d4e2a0c3190d5695e8e63046d.png?generation=1606040566464990\&alt=media)

#### Isotropic 各向同性/Anisotropic 各向异性

BRDF 可逆性：交换入射和出射方向的角色，得到的 BRDF 的值还是一样的 BRDF 能量守恒：BRDF 不会让能量变多，所以光线追踪会收敛 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Faa3277fef228b6eec97e3cdebb45d66b1f16ce08.png?generation=1606040560968398\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fac1a75db9aa6e5f173b268557855885722968cc5.png?generation=1606040559939344\&alt=media)

### BRDF 测量

菲涅耳项难以描述，遍历入射方向，然后遍历观察方向。这是四维的操作，速度很慢，但是可以加速。 各向同性可以降低为三维测量，利用 BRDF 的对称性可以减少一半的测量。

## L18 Advanced Topics in Rendering

### Advanced Light Transport

无偏：蒙特卡洛估计出来的结果期望永远是对的。 有偏：相比与正确的结果是有模糊的。如果估计的值与最后的期望不同，如果收敛到无穷是准确的，那么称为一致的

#### 无偏

* Bidirectional Path Tracing BDPT 双向路径追踪，

  光源+摄像机出发的半路径的端点连起来。适用于光源处半边比较好算的情况。难以计算，很慢。
* Metropolis Light Transport MLT

  使用 Markov Chain 采样工具（根据当前样本，生成下一个接近的样本），使得样本的分布和被积函数形状一致。给出一条路径，可以得到周围相似的路径。适合做复杂困难的光路，如水底的聚焦效果 Caustics。很难在理论上分析何时会收敛；完全局部，整体看起来会比较脏；无法做动画。

#### 有偏

* Photon Mapping 光子映射

  先从光源出发，直到光子打到 diffuse 的地方停止；从摄像机开始，打出来各条路径，直到打到漫反射的物体上；取最近的 n 个光子，做局部的密度估计（如果有无限的光子，得到的结果是正确的），光子分布越集中越亮。适合做 Caustics 和困难的路径。
* Vertex Connection and Merging VCM

  BDPT 和 Photon Mapping 的结合。结合 subpath 时，把光路认为是光子映射。
* Instant Radiosity 实时辐射度

  已经被照亮的面，可以认为是光源，用于照亮其他地方。如果两点的距离极近，有些地方会莫名其妙会发光，无法用于 glossy 材质。

### Advanced Appearance Modeling

#### 非表面模型

* 参与介质 Participating Media

  雾/云，定义在空间中。一根光线穿过，穿过冰晶会发生随机分散到各个方向，也会接收到其他方向分散的光，或者被吸收。
* 头发

  光线和曲线如何作用。

  Kajiya-Kay Model：漫反射+在圆锥体内的高光。

  Marshner Model：头发是玻璃柱。反射的高光 R+进入头发的折射再传出 TT+进入头发后内壁反射又往回走穿透 TRT。
* 动物毛发

  人体的头发髓质很小，动物更大，所以会发生更多的散射。
* Granular 颗粒材质

#### 表面模型

* Translucent 透射

  例如玉石，可以散射然后再穿出，次表面反射。对方向+面积进行积分。

  ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F156198bc93ef1db269e7b354e7a3ac0b50b7a2f2.png?generation=1606040560608992\&alt=media)

  Dipole Approximation：用上下两个光源来模拟。
* 布料 Cloth

  布料是一系列缠绕的纤维。根据编织的方法，渲染也不同。

  ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fbaaac9955d67abb0e9b69e571ad4265615624794.png?generation=1606040565001479\&alt=media)

  一个更正确的方法：看作在空间中分布的体积，划分为细小的格子，当作散射介质，就像在渲染雾一样。

  或者把纤维当作头发，按照缠绕方式，再进行渲染。
* 细节描述

  正式世界是不完美的，会有许多划痕。增加细节会让物体看起来更加真实。
* 波动光学

  BRDF 类似，但是不连续。
* 程序化生成

  不需要真正生成，可查询。噪声函数，定义在空间中。

## L19 Cameras, Lenses and Light Fields 相机/棱镜/光场

成像：光栅化/光线追踪是模拟成像 捕捉成像：相机

### 相机

快门：控制光在多少时间内进入相机 感光元件：记录 irradiance 针孔相机不会虚化。 FOV：Field Of View

### 视场（35mm 的胶片来测量）

![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F00b356d0ed2608c9b95351a0158cd871a8e6c5d1.png?generation=1606040565832100\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F3fe261017fc585a39aa565c9ea1c499bb9ef7224.png?generation=1606040565881081\&alt=media)

### Exposure 曝光度

H= T x E (time x irradiance)

### 快门 shutter speed

快门越快，曝光时间越长，曝光度越大。在快门打开的时间内，高速运动的物体会产生运动模糊。之所以会产生运动模糊，是因为在快门打开的时间内进行了多次采样，而传感器最终起到了平均的作用，展现出来的效果就是模糊。 运动模糊并不总是坏事，考虑反走样，相机可以看作对运动在时间上的一次采样，时间越长，引入模糊，采样的效果就越好，就越能表示出运动的信息。 运动模糊和景深需要 trade off

### 感光度 ISO gain

后期处理，乘以一个数，线性变化。会放大信号，同时也会放大噪声。

### 透镜

目前的手机用的都是透镜组，可以认为是一个能改变焦距的薄透镜。 Circle Of Confusion COC：一个点在经过透镜折射后会在透镜后的某一个点最清晰，如果在经过这个点之后继续传播，会在之后的平面上折射出一个圆，在这个圆上，无法判断这个圆是由哪个具体点投射而来，不同的点投射出的圆也有可能相同。COC 的大小和光圈大小/透镜大小相关。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F575d2880255860fd4d6392b417e1d07fae9a1f16.png?generation=1606040560033429\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F366e10c1019d6c527751eeeff1eea8f337463bcc.png?generation=1606040564239655\&alt=media)

### 光圈 aperture size

越大曝光度越大 F 数（f-stop）。F 数等于焦距除以光圈的直径。所以，拍清楚的物体要用小光圈。 Depth Of Field 景深: 成像清晰的一段范围。在成像平面附近 COC 足够小，所以清晰，远处的物体 COC 大，显示模糊。

### 透镜光线追踪

![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F695dace84f2a0e07670ed7cf3601be59451358d9.png?generation=1606040566094378\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F57bf9d5921f411336eba228b0b1fe06f2eb526f9.png?generation=1606040563480225\&alt=media)

### 光场 Light Field/Lumigraph

我们看到的是三维世界，如果用一个幕布完全模拟看到的景象，也不会觉得有什么区别。 全光函数 The Plenoptic Function：描述能看到的所有景象 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fdcd571068c54f1a98a5c0001f9cf40ce525e0131.png?generation=1606040565337720\&alt=media) ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fea1bf23b998036e07844744d9feac7a9b8010b11.png?generation=1606040562414726\&alt=media) ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fe3d149aaee4fda97f297612d07a092fa647f0d73.png?generation=1606040562231850\&alt=media) ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Ffd29073e0c32eafbc3bea3d06edbcf47c8a8e044.png?generation=1606040562640394\&alt=media) ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F73412940bd74d17aa2c77a54d186835773d13f15.png?generation=1606040564674049\&alt=media) 光线可以定义为 5D（起点+方向）或者 4D（不考虑起点，使用 2D 方向+2D 距离 uv） 物体表面可以定义为在所有方向上被看到的信息可以用物体的包围盒在各个方向的发光情况。 光场可以用两个平面中的各一个点连接而成的光线定义。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb0fd3c2295f3c7c6a627d960aeec73d5ae3ca19a.png?generation=1606040562245495\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F70b015fe36687c21124ab2cb49e7781834199675.png?generation=1606040560563108\&alt=media) 在 uv 上选中一点，向 st 上看各个方向，会看到一个完整的图，类似小孔成像。 在 st 上选中一点，向 uv 上看，会看到一个物体在不同方向的成像。把 irradiance 展开为 radiance。 正常摄像机获得的照片是各个方向上的光的混合结果。光场照相机采用的技术是在原先的面上使用透镜来代替，让光可以继续传播，在不远处收集到光，这样就收集到了这个点各个方向上的 radiance。 光场摄像机普遍存在分辨率不足的缺点，因为使用了一块区域来记录一个像素。

## L20 Color and Perception

### 颜色

可见光谱在 400-700 纳米之内。 Spectral Power Distribution SPD 谱功率密度：描述光在任何一个波长下分布。是线性的，可相加。 颜色：人的感知，和人有关。视网膜上有感光细胞，棒状细胞可感知光照强度，得到灰度的图，锥形细胞可用来感知颜色。锥形细胞又分为三类：S 小波长，M 中间波长，L 长波长，不同的人，三种细胞也不同。颜色=S/M/L 与 SPD 乘积在波长上的积分。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F5f08885b2acb95706566626e30c550cb3f332485.png?generation=1606040563283960\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F91acf34cfc8701a9341dee449fa71e1e562e9885.png?generation=1606040564552746\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fbae9eb66ec1520cfbc2d4057842e0d4e29c3c243.png?generation=1606040562990514\&alt=media) 同色异谱：光谱不同，最终颜色相同。

#### 加色系统

RGB 有三种原色，可使用原色之间的混合来得到不同的颜色。 如何得到一个颜色：可以通过用三种原色调整，来得到和目标颜色相同的三原色值。另一种思路，在原来的颜色上往上加，相当于另一个颜色往下减。

#### CIE RGB

![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fdd00599b159f22baa934701f509b07295d7a2a5f.png?generation=1606040560845983\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fb5553a9861baa15de752916434e0a9eee8cdf7d5.png?generation=1606040562755357\&alt=media)

#### 颜色空间

sRGB：标准 RGB，广泛用于显示设备。RGB 颜色空间的色域有限。 CIE XYZ：同样定义颜色匹配系统，RGB 为实验测得，XYZ 为人为定义。把 XYZ 归一化，x + y + z = 1，降为二维进行可视化--色域。 色域中心：白色，最不纯。最纯的颜色在边界。不同的颜色空间表示的色域不同 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F059586c159b97e0c9a31af26e3324c9c68fbbe5b.png?generation=1606040566262994\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F84de571d4ca6c50ae4ab84b3e8ee39768b1f100f.png?generation=1606040564183531\&alt=media)![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F3e11428d3c40f3169b825cd8b1783f50c438e3be.png?generation=1606040562319404\&alt=media) HSV：用于颜色拾取器。色调-饱和度（越饱和越接近纯色）-亮度。 CIELAB：L（亮度）-a（红绿之间的值）-b（黄蓝中间的值）。ab 定义为互补色的中间值。

#### 减色系统

CMYK：Cyan，Magenta，Yellow，Key（黑色，考虑印刷的成本） 减色系统：颜料，越混合越黑。

## L21/L22 Animation 动画

人眼存在暂留效应，所以不需要非常集中地处理动画。电影：24fps。视频：30fps。虚拟现实不晕：90fps。

### Keyframe 关键帧

一种插值的技术。 关键帧插值，非线性。 可用曲线来控制，关键帧与几何关系密切。

### Physical Simulation 物理仿真

物体会受力，根据牛顿定律，可以计算出加速度。 流体模拟。

#### Mass Spring System 质点弹簧系统

一系列相互连接的质点和弹簧。可用于头发模拟，布模拟。弹簧认为初始长度为 l（rest length）。 为了让运动的物体停，可以施加一个摩擦力 damping，但是表示不了内部的状况。因此，需要将 a，b 的相对速度以及投影到 ab 方向的力的影响考虑进去。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F44dcea007b4a638c6c6b64cbdb793d528c35db87.png?generation=1606040563848376\&alt=media) 模拟布时，布会抵抗切变的力，不会发生形变；抵抗 out-of-plane-bending（破坏平面结构的力）。 所以，应该将对角线的点连接起来，然后再把所有相隔一个点的点都连接起来。

### Particle System 粒子系统

描述粒子收到的各个力，可以模拟流体。 生成新粒子；考虑内部外部的力；粒子的生命周期；渲染出每一帧。 吸引力/电磁力/斥力/摩擦力/碰撞/弹簧。

### Forward Kinematics 运动学

关节：发生在平面内的/球状的/可伸长的。实现容易。 Inverse Kinematics 逆运动学：只描述最后的运动结果，然后求出角度。以及多种结果都可以满足最终的位置，如何去选择。多解和无解的情况都会出现。可以使用优化法（梯度下降）来处理。

### Rigging

对于一个形状的控制，提线木偶。 可以使用控制点来控制，然后对控制点以及影响的曲面之间进行插值。

### Motion Capture 动作捕捉

希望真人的动作反映到虚拟人物上，需要一系列的控制点。拍下真人的控制点的运动情况，再反映到虚拟人物上。能够更贴近真实。 应用最广泛的做法：光学的做法，贴一些小球作为控制点。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F9c504e4cf153f765256c645f01f525af6806a585.png?generation=1606040563726412\&alt=media)

### Single Particle Simulation

模拟一个粒子在速度场中如何运动。直到速度，给定位置，得到运动轨迹。常微分方程。

#### 欧拉方法

始终用上一时刻的数据来估计下一时刻的速度与位置，会有误差，也会有不稳定性。步长越大会迅速变得不稳定。 不稳定：向心圆里会最终运动出去；正反馈。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2F43bf68d286b7c0577d01304bebab91bc4913ca49.png?generation=1606040563686517\&alt=media) 解决不稳定：

1. Midpoint Method 中点法

   不使用计算的点，而是得到中点，然后返回起点，用中点的速度再重新计算。
2. Adaptive Step Size

   使用 T/2 的点，再跑 T/2，得到如果和首次比较，如果相差较大，那么就拆成两段跑。
3. Implicit Euler Method 隐式欧拉方法

   始终用下一时刻的加速度和速度。

如何衡量不稳定：每一步的误差与其的总和；更有意义的是将误差与步长的阶数。 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fed4920e56b9a0b99a7c72d9aacbc4ebe2c714177.png?generation=1606040562259214\&alt=media)

#### Runge-kutta Families 隆戈库塔方法

这一类方法非常擅于解 ODE（常微分方法），尤其非线性。 最广泛：RK4，4 阶 ![](https://772256576-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MF5VV7ErAwHfxPYA-uU%2Fsync%2Fdfa2168d122601cd5a5c70d611c4b16ca0d54e2b.png?generation=1606040565326224\&alt=media)

#### Position-Based / Verlet Integration

调整弹簧，使得如果发生了一点形变，立刻调整两个端点，使之可以马上恢复原长。

#### 刚体的运动

刚体的运动类似粒子的运动，需要考虑更多的物理量。

### Fluid Simulation 流体模拟

水体由很多不可压缩的小球构成。认为水体不可压缩，密度都是一样的。 任何一个时刻的密度都可以计算，如果密度和之前不同，那么就移动小球将密度修正回去。 需要计算密度对所有小球位置的导数。 两种思路：拉格朗日（由小水滴构成，模拟每个水滴）与欧拉方法（把空间分为网格，考虑网格随时间如何变化）
