01 Overview of Computer Graphics
插图风格 电影特效 动画 设计渲染图 可视化 VR 数字绘画 模拟/仿真 GUI图形用户接口 Typography字体
投影/曲线/表面中的数学 光线和阴影中的物理 3D图形的表示 动画/模拟 球的弹跳
- 光栅化 Rasterization 三维几何体投影到屏幕 实时/离线的概念
- Curves and Meshes
- 光追 Ray Tracing
- Animation / Simulation
OpenGL 只是API,其使用不是课程内容 建模、游戏引擎也不是课程内容 CV不是课程内容,其注重理解、推断等
虎书:Fundamentals of Computer Graphics
geek一词来自英语方言,意思是“傻瓜”或“怪胎”。含有贬义。另一方面它又有智力超群和努力的含义,通常被用于形容对计算机和网络技术有狂热兴趣并投入大量时间钻研的人。所以俗称发烧友或怪杰。
02 Review of Linear Algebra
图形学用到的一些基础学科知识:线性代数、微积分、统计、光学、力学、信号处理…
向量的投影与向量分解的关系
向量内积可以确定前后方向
回顾向量外积 右手定则(有两种) https://zhuanlan.zhihu.com/p/342679387
等价于坐标系是右手系(三个向量指的是坐标轴正方向)
小知识:unity用的是左手系
向量外积可以确定左右/内外
,其中u,v,w为右手系的x,y,z轴方向向量
内积外积都可以写成矩阵运算的形式。 内积的我们很熟悉了。 外积的我还是第一次见。 又仔细想了想根本不是第一次见。 这不就是行列式算外积的那个式子的变式嘛。
03 Transformation
分为Modeling和Viewing的Transformation 光栅化成像使用投影transformation
-
Scale
-
Reflection 以左右反转为例,上面Scale中即可
-
Shear(切变) 以水平切变为例,纵坐标不变,横坐标平移多少与纵坐标线性相关
-
Rotate
以上变换均为线性变换
- translation(平移) 就是加了个常数坐标向量 不属于线性变换
为了方便讨论此变换,我们引入:齐次坐标
2D point表示为 2D vector表示为 则线性变换可以用如下方法表示:
思考,为什么点和向量的表示又不再一样了?希望向量有平移不变性。还可以怎么理解?点和向量好像也可以区别开来。点-点=向量。向量+向量=向量。点+向量=点。这真是完美的表示!
但还有一个问题!
点+点,新增的第三维成了2?
我们规定:
和表示的是同一个点! 这不就体现齐次性了吗!太妙了!!!
现在把线性变换和平移统一考虑【被称为仿射变换】,在齐次坐标下即为:
逆变换与逆矩阵
ez
复合变换与矩阵乘法
ez 有个好的例子:绕非原点的中心旋转
拓展到三维变换
ez
旋转变换这里稍微复杂一些,绕某个轴旋转?更一般的旋转?
“Euler angles”
“Rodrigues’s Rotation Formula” 其中是旋转角度,是旋转轴(默认轴过原点)(如果不过原点,还记得怎么做吗?联想二维?)
感想:自己学过仿射变换,又学过线代,把它们联系起来应该是非常trival的,但自己却没有学习到这一点。
04 Transformation Cont.
挖坑。四元数?解决旋转矩阵不方便插值的问题。
拍照M(model)V(view)P(projection)三步走:位置?角度?投影!
view/camera transformation
需要确定的参数: position Look at direction Up direction
规定在原点,看-Z方向的物体!Up direction则为+Y轴方向。 所有物体需要跟着相机进行平移与旋转! 旋转矩阵可以先求其逆矩阵(也是转置矩阵,毕竟正交)
projection transformation
- orthographic projection 正交投影
- perspective projection 透视投影
我靠这个我竟然只看这两个名字就很轻松地理解了!我之前也考虑过这个问题hhh
正交投影
正交投影似乎十分简单,即丢掉Z轴。注意,还规定缩放到-1到1的矩形中。
正交投影变换(Orthographic Projection Transformation)定义一个立方体的左右,下上,远近。先平移,再缩放,成一个标准立方体(canonical cube)
思考:为什么远的一面的z值,大于近的一面的z值?
透视投影
近平面、远平面,但远的平面大一些。四棱锥的尖被削掉了。这个形状叫Frustum(视锥体)
观察这个东西和长方体的区别,就能理解透视投影和正交投影的区别。
规定,近平面不会发生任何变化,远平面的z值也就是f也不会变化,中心点不会发生变化。直白说,就是把远平面往中心挤压成近平面大小。
考虑齐次坐标下,再加上z值不变的假设,已经足以确定这个“挤压”变换矩阵了
哎呀!真的太妙啦!!!
再进行正交投影,即为透视投影的全过程!
思考:中间一个点的z值怎么变?
05 rasterization 1(Triangles)
Frustum的宽高比、垂直可视角度
定义screen,像素的二维数组,一种典型的光栅化成像设备 定义屏幕坐标系
Pixel(X, Y) is centered at(x + 0.5, y + 0.5)
视口变换
到底什么是光栅化 Raster Scan 隔行扫描 成像设备
- LCD(Liquid Crystal Display)
- LED(发光二极管)
- …
先只考虑三角形!
- Sampling方法 需要inside函数判断,前面提到过的叉乘法 bounding box对光栅化加速
Bayer pattern
06 rasterization 2(Antialiasing and Z-buffing)
抗锯齿(aliasing)/反走样
Artifact 一切看上去不太对的东西
- 锯齿(aliasing)?
- 摩尔纹:忽略奇数行奇数列?
- 视错觉?
方案:filter,滤波器进行模糊
问题的关键:采样频率
傅里叶展开与傅里叶变换
采样频率要和函数本身频率关系很大
滤波就是去掉一些频率的波
傅里叶变换让我们看到频谱
经过High-pass filter【高通滤波】,发现剩下的是原图像的边界
经过Low-pass filter【低通滤波】,发现得到了一张模糊的图
滤波与卷积与平均之间的关系
两个信号的卷积,对应到两个信号频域上,是它们的乘积。 (反过来,时域上的乘积也对应频域上的卷积)
滤波器去做卷积,等价于滤波器和信号经过傅里叶变换后相乘,再逆傅里叶变换。
box filter就是低通滤波器
采样就是在重复原始信号的频谱 采样就是时域上原信号与一系列冲激函数的乘积,对应到频域实际上是信号的复制粘贴。
近似方法MSAA 近似了模糊操作
其他抗锯齿前沿方法 FXAA TAA(Temporal AA)
超分辨率与抗锯齿的关系? DLSS法
07 Shading 1 (Illumination, Shading and Graphics Pipeline)
Painter’s Algorithm 先画远处物体,再用近处物体覆盖。 但这无法解决覆盖关系成环的情况!
Z-Buffer
深度缓存! 存储并不断更新深度图 Depth / Z buffer 最后输出 Frame buffer
很直白的想法! 此算法对不同物品输入顺序没有要求。
这个算法可以和MSAA结合。
Shading(着色)
对不同物品应用不同材质的过程。
- Blinn-Phong Reflectance Model
高光、漫反射、环境光照
定义 Viewer direction / Surface normal / Light direction / Surface parameters
Shading is local 如不考虑桌子上其他物体的影子
漫反射,不同角度,光照亮度不同,余弦定律
点光源到固定距离的能量 平方反比
表示 diffuse coefficient(color)
漫反射从哪里看都一样
08 Shading 2(Shading, Pipeline and Texture Mapping)
考虑高光(镜面反射)情况。 Blinn-Phong Reflection Model 只需考察“半程向量”和平面法线的接近程度: 经验性地,p一般比1大(100-200),使得高光更加集中。
关于环境光: 规定,是一个常数
着色频率 Shading Frequencies flat shading 对每个三角形着色 gouraud shading 对顶点计算着色 Phong shading 对每个像素着色
怎么求顶点的法线?加权平均法,权是三角形面积。 怎么求点之间位置的法线?重心坐标法
图形管线/实时渲染管线 Pipeline shader:控制着色方式 以OpenGL为例 对每个对象执行shader
- vertex shader
- fragment/pixel shader
网站:shadertoy
有很多着色器:geometry shader、compute shader…
纹理映射 Texture Mapping 本质是调整物体的不同部位的不同属性,如漫反射系数 怎么形成映射呢?
想到了GTA罪恶都市的那个skin
Texture coordinate(u,v),[0,1]内的正方形 无缝贴图 tiled texture Wang Tiled
09 Shading 3 (Texture Mapping Cont.)
关于重心坐标:在三角形内部插值都要用,很多属性都要用
(共面条件)
我靠,数竞学的平几又用上了!
注意一点:不能在投影之后的三角形做插值!重心坐标在这个过程中不是不变量!!!三维空间中的属性,就要在三维空间中做插值。
进而实现了纹理的实际操作
但会有一些问题
-
纹理的放大 高清图,纹理却像素很低 纹理上的像素称为texel 这样的话,多个pixel都会对应到同一个texel上去,或者说这些pixel在找对应的texel时,得到的是texel序数非整数。效果就很不好。 解决办法:双线性插值Bilinear,进而还有双三次插值Bicubic
-
纹理太大了 摩尔纹、锯齿现象 远处的pixel会覆盖很大一片纹理,再用像素中心采样就会走样 当然可以MSAA,但代价很大 希望把Point Query转化为 Avg. Range Query,这是一个算法问题。希望输入区域得到均值。而不是输入点得到点的值再做操作。 解决办法:Mipmap(fast, approx, square range query) 一张纹理图缩小分辨率生成一系列纹理,仅仅需要多33%的存储 算出对应到纹理的边长,然后小正方形近似 但Mipmap层数是整数,做不到连续变化 没关系!双线性插值后,在层与层之间再次插值。三线性插值! 现在无论什么区域我都能查询了! 但还会出现问题。Overblur问题。 改进:Anisotropic Filtering 各向异性过滤 改变了长宽比的也预计算!喵啊!也就是说,正方形推广到了长方形!但还有问题!斜着的区域不行! 开销是3倍。 再改进:EWA过滤 拆成多个圆形,多次查询
Texturing还可以用来做什么? 可以理解成一切用到范围查询的
环境光照,用Texture实现 假设环境光照来自无穷远处 环境光用球面记录 Spherical Environment Map 扭曲问题?Cube Map!
凹凸贴图/法线贴图 Texture改变高度 橘子皮例子 具体计算:算梯度,写出切线方向,进而算出法线方向
位移贴图 顶点的位置真的动了 需要三角形足够大(采样率足够大)但太大也不行,direct x提供了动态的,根据需要决定。 推广到3D.
10 Geometry 1 (Introduction)
我靠!数学建模?
分为Implicit Geometry 和 Explicit Geometry 后者判断点在不在内部变难了
隐式的例子 CSG,Constructive Solid Geometry 利用布尔运算 Distance Fuctions, blend操作,怎么恢复,水平集方法
Fractals(分型)(Implicit)
11 Geometry 2(Curves and Surfaces)
Point Cloud (Explicit) 字面意思,就是一大堆点 点云如何转化为面,是重要的研究
Polygon Mesh (Explicit) 最广泛应用 三角形面
.obj Format v/vn/vt/f
贝塞尔曲线
de Casteljau Algorithm
妙啊! 怎么代数表示? Bernstein Polynomials! 妙啊! 贝塞尔曲线的基本性质 关于仿射变换的不变性 凸包性质
分段贝塞尔曲线
更好控制 通常使用piecewise cubic Bezier(四个控制点) 关于连续性
其他曲线 样条曲线spline B-splines 贝塞尔曲线的扩展 局部性更好 非常复杂 NURBS 更加复杂
贝塞尔曲面
4×4个控制点
欢迎学习胡事民老师的课程
12 Geometry 3
会逐渐接触到 Ed Catmull 和 Pat Hanrahan 两个图灵奖获得者的工作。
Mesh Operations
1. Mesh subdivision 分两步:引入更多三角形、调整它们的位置 以Loop Subdivision为例介绍算法
其实还是很像插值
另一种算法可以不止用在三角形面上: Catmull-Clark Subdivision (General Mesh) 定义 quad face、Non-quad face、Extraordinary vertex(degree != 4) 每次在每个face上取一点,再在每一边上取中点,然后把这些新的点相连 发现face上取的点一定是奇异点,具体度的大小取决于之前face有几条边。 在这之后,奇异点的数目不可能再增加了!因为上一步之后已经没有non-quad face了。 点取完了,再调整位置。
2. Mesh simplification
很多时候没必要太细节 一种方法:Edge Collapse 边坍缩 怎么决定坍缩成的点的位置呢?Quadric Error Metrics二次误差度量!优化问题。 实际坍缩的过程。也是根据这个度量选择坍缩哪条边。但是这涉及贪心算法不最优的问题!一个边坍缩会引起其他边变化! 最小堆?确实解决了最小值不断更新的问题,不用每次排序了。但这还是没有解决我说的那个最优性问题啊!一个边坍缩会引起其他边变化啊!不能贪心算法啊! 经过实践,我们决定忽视这个问题。。。。
3. Mesh regularization
略
关于阴影! 着色解决不了这个问题。 提出 Shadow mapping! 核心思想:阴影说明光源看不到这个点。光源和相机同时看到的点则不是阴影点。 【只能处理点光源】【硬阴影】 第一步,从光源看向场景。回忆zbuffer,得到深度图。 第二步,从摄像机出发,看到的点,投影回去,与之前记录的深度比较。 但这个深度比较的过程中会涉及浮点数比较误差的问题。。。。实际操作时会用bias等方式缓解这些问题。但不能真正解决。shadow map的分辨率也是个问题(游戏设置里的 阴影质量)
然后考察软阴影。本质是因为光源有大小。有的地方能看到部分光源。
13 Ray Tracing 1
去解决光栅化不能解决的一些 global effects 的问题:
- Soft shadows
- Glossy reflection 粗糙面的光泽
- Indirect illumination 间接光照,多次反射
Ray Tracing更加accurate但非常慢,因此更多是非实时场景下应用。
定义Light Rays:沿直线传播,无碰撞,光路可逆。
Ray Casting:找到光路 具体有eye ray、shadow ray
Recursive (Whitted-Style) Ray Tracing 无数次的反射与折射 着色时都加到像平面对应像素上去 primary ray、secondary ray、shadow ray
第一步,求光线和物体表面的交点
谁家解析几何 其实就是求解
光线和Triangle Mesh的交点又该怎么求? 分为两步,先看光线和三角形所在平面的交点,再判断点是否在三角形内(前面学的用上了) 平面可以由一个点和一根法线确定。进而写出平面方程。 和光线方程联立解得 再判断点是否在三角形内即可
不满意。希望找到一步到位的算法。 Moller Trumbore Algorithm 找交点其实就是解一个线性方程组
还有一个问题,一个模型那么多三角形,要一个个去判断,太慢了,如何加速?
Bounding Volumes 找一个东西把物品包起来,得到的叫包围盒 如果碰不到包围盒,那么一定也碰不到物品
有种放缩的感觉
取长方体包围盒。长方体本质是三对半平面形成的交集。 而且,这个包围盒还要取轴对齐包围盒(AABB,Axis-Aligned Bounding Box),即与坐标轴平行的。【方便计算】
思考。光线和长方体各对平面相交的时刻已经能求了。我们只需对这些区间求交集。就能判断什么时候光线进入了盒子。 具体到算法上,,去看是否有 当然还要记得考虑,以及光源在盒子里的特殊情况
弹幕有人说算法题,感觉这个问题确实很适合出OJ题
总之,ray和AABB相交当且仅当
Lecture 14 Ray Tracing 2
具体如何使用AABB加速光线和物品求交点?
Uniform Spatial Partitions
Uniform Grids步骤 1.Finding bounding box 2.Create grid 3.Store each object in overlapping cells 4.看光线是否和box相交,也即是否通过被标记的cell,如果是,则去判断一下和物品是否相交
在这里有个小问题,是光线和cell的相交是怎么判断的。这个和直线的光栅化问题很相似。
cell划分不能太稀疏也不能太密集 这样的分割有时会出大问题,即不同物品大小不太均匀的时候
下面才是认真的Uniform Spatial Partitions Oct-Tree 八叉树 KD-Tree 每次只砍一刀多出来一块空间,横竖交替(二叉树?) BSP-Tree 可以斜着砍,但不好算
以KD-Tree为例讲解。很直白。
还有一个问题,怎么判定box和物品是不是相交呢。暂且不表。
还有一个劣势,一个物品很容易和很多Box都有交集。这会大大降低效率。
Object Partitions & Bounding Volume Hierarchy (BVH)
把物品们分成两堆,分别求box,不断划分下去,也是用KD-Tree的办法,这样一个物品只可能出现在一个box里
这会引起一个新问题,不同的Box可能相交。但这个问题并不大。
问题:具体如何划成两堆?
- Always choose the longest axis in node
- Split node at location of median object 涉及快速选择算法 ~ O(n)
问题:划分到什么程度? node包括的elements足够少的时候。
BVH的遍历。
Basic radiometry(辐射度量学)
对光和物品的作用有更加精确的描述。
新名词
Radiant energy 单位:Joule Radiant flux / power 单位:Watt/lumen Radiant Intensity 即单位时间单位立体角上的能量 单位: 什么是立体角? 球面坐标系 微分立体角
Lecture 15 Ray Tracing 3
Irradiance 单位:lm/m^2 = lux 引入这个概念后可以解释 Irradiance随距离的平方衰减
Radiance
BRDF(Bidirectional Reflectance Distribution Function)
用于研究不同方向反射光线的分布
问题:光线反复反射,产生递归
The Rendering Equation
补上了“自己产生的光”
进而,考虑上多光源、面光源
进而考虑其他物体
最后转化为解方程问题
得到全局光照的概念
怎么解下节课再说,要用到概率论的方法
Lecture 16 Ray Tracing 4
Monte Carlo Integration
Path Tracing 解决Whitted-Style Ray Tracing的一些问题。漫反射不能不考虑。 specular or glossy
经典The Utah teapot、The Cornell box模型 color bleeding现象…
就是我的随机变量 用蒙特卡洛积分,直接光照很容易就解出来了 稍加修改(考虑其他物品反射来的光线),就成全局光照的算法了
问题1:光线数量爆炸。可以只打出一条光线!n=1!这就叫路径追踪! 妙啊!把无限种路径的问题,转化成无数次试验但确定路径的问题
问题2:递归无限深度啊! Russian Roulette(RR)法! 给定概率p发射光线最后结果再除以p,以1-p的概率不发出光线。期望不变。
问题3: not really efficient SPP(samples per pixels)低的时候效果很不好 均匀采样的话,有很多path被浪费了!能不能换一种采样方法? 我只在光源上进行采样! 但这和积分域不一样了啊! 去改渲染方程! 剩下非光源的部分还是用原方法
问题4:直接光照的时候有无遮挡
点光源怎么办?太难了。。。在此不表。
思考:采样这一点是怎么实现的?怎么采样最好?随机数low discrepancy sequences?Mutiple important sampling?pixel reconstruction filter?Radiance怎么转化成color?(Gamma校正,curves, color space)
FEAR THE SCIENCE
Lecture 17 Materials and Appearances
最强的渲染器也只支持40种材质,靠美工
图形学中如何定义materials?渲染方程中是如何体现出来的?BRDF!
Material == BRDF
假设是漫反射,入射和反射都是均匀的 根据能量守恒: ,得到,其中是反射率,也即代表颜色,如果物品是白色的不吸收光,
还有其他材质… Glossy material BRDF Perfect Specular Reflection BRDF 反射角的计算
caustics 如海底的条状高光现象
斯涅尔定律 全反射现象
snell’s window / circle 现象
涉及折射的是BTDF,和BRDF合称BSDF 菲涅尔项:解释多少能量发生了反射,多少发生了折射(垂直的时候折射多,反之反射多),有公式,和两个折射率和夹角有关 算起来很麻烦,所以有一个Schlick’s approximation
Microfacet Material 离得很远的时候,细节看不到的,假设物品粗糙,但是是平的 但在microsurface层面,是有很多起伏的,但是完全镜面反射的
全都向上,镜面反射 有些材质法线大都朝上,glossy的 各方向都有,diffuse的
所以用法线分布来量化材质! 计算BRDF时。用到菲涅尔项。查询多少法线方向和half vecotr方向一致,用到法线分布。还要用到一个shadowing-masking term,考虑microsurface的互相遮挡,自遮挡自投影,在光线和平面夹角很小的时候会出现,这叫grazing angle。 用到这套思想的都可以叫微表面模型。
isotropic / Anisotropic Materials (BRDFs) 各向同性材质 / 各向异性材质 例子:电梯间的奇怪高光 即微表面法线分布的方向性 也可以从BRDF角度考虑 例子:天鹅绒
BRDF的性质 非负性 线性 可逆性 能量守恒 如果各向同性,四维变三维,而且方位角不用考虑正负
Measuring BRDF 测量算法、加速算法、存储算法、压缩算法… 经典库:MERL,测量了很多材质的BRDF
Lecture 18 Advanced Topics in Rendering
Advanced Light Transport
Unbiased light transport methods
- Bidirectional Path Tracing (BDPT) 半路径的连接 双向路径追踪
- Metropolis Light Transport (MLT) 马尔科夫链(MCMC)生成一系列样本去符合PDF 一个局部的方法,适合做复杂场景 很难估计收敛速度 比较dirty,不能保证不同像素以相同速度收敛
Biased, but consistent
- Photon Mapping 光子映射 适合caustics场景、SDS(specular-diffuse-specular) 介绍一种实现方法 从光源出发,光子打到difuse的物品时,光子停住,记录好 然后从摄像机开始打subpath,直到diffuse 计算local density estimation k近邻。k越大越好嘛?会变糊。biased!有偏估计。 光子趋于无限多,才能无偏。
- Vertex Connection and Merging, VCM 把BDPT和Phonton Mapping结合。
- Instant Radiosity, IR 认为subpath停住的地方全都看成新的光源
Advanced Appearance Modeling
Non-surface models
- Participating Media 例子:云,可能发生emission和absorbtion 怎么表现散射?相位函数!Phase Function
- Hair Appearance 有色高光? Kajiya-kay Model是一个经典头发的模型 Marschner Model 更加真实 还有多次散射的模拟。。。 动物毛发模型?Hair vs. Fur 髓质的作用 Double Cylinder Model Yan佬的工作
- Granular Material 颗粒材质
Surface models
- Translucent Mateirial 如玉石、水母 进去之后大量散射,从其他面穿出 这叫次表面反射 BRDF -> BSSRDF 一个延申 渲染方程也要进行更改 近似: Dipole Approximation 比如手指+手电就好像手指里面多了个光源
- Cloth fibers - ply - yarn woven or knitted 空间划分?渲染每根纤维?都可以
- 真实世界的特殊效果 划痕? 回忆微表面模型,考虑法线更加复杂的分布
太慢了!
各种p-NDFS
考虑光的波动性
Procedural Appearance 定义在空间中 noise function 随用随取不存储而是现算
Lecture 19 Cameras, Lenses and Light Fields
Imaging = Synthesis + Capture 光线追踪、光栅化都属于Synthesis,拍照则属于Capture
Camera Shutter 快门 控制光能否进入 Sensor
为什么物品直接放在光传感器前上不会成像?相当于记录irradiance。
Pinhole Camera 无景深
Field of View (FOV) 视场 h是传感器高度,f是焦距(pinhole和sensor之间的距离) h通常认为是35mm-format film,所以焦距就能决定视场 手机说的是等效焦距
Exposure 曝光
光圈就是挡光用的,f-stop来调节大小, ISO gain 感光度 相当于一个后期处理,直接往结果上乘,越大越亮,但是噪声也更大了 F后面的数越小,光圈越大。这个F数就是直径的倒数。 快门速度 运动模糊 某种程度可以看出一种反走样 rolling shutter问题 螺旋桨的扭曲 高速摄影 or 长曝光摄影 大光圈产生景深
Lens 研究理想化的薄棱镜 三角形相似,很好证明 Defocus Blur Computing Circle of Confusion (COC) Size 弥散圆 其大小和透镜大小成正比!
Ray Tracing Ideal thin lens
Depth of Field
Light Field / Lumigraph