参考视频https://www.bilibili.com/video/BV1X7411F744课件https://sites.cs.ucsb.edu/~lingqi/teaching/games101.html笔记https://zhuanlan.zhihu.com/p/394932478https://www.notion.so/GAMES101-b0e27c856cde429b8672671a54c34817内容图形学应用场景电子游戏、PBR、卡通渲染、电影、动画、设计、可视化、数码插画、GUI图形用户接口、字体设计等领域计算机图形学与计算机视觉图形学不是计算机视觉。计算机视觉猜测、预测、分析处理计算机视觉是理解这个世界计算机图形学是创造这个世界线性代数复习图形学主要使用列向量默认右手坐标系点乘AB|A||B|cosθ作用点乘主要应用于求两个单位向量的夹角.cosθ AB/|A||B|观察两个向量之间是同向、垂直还是反向可以观察两个向量的接近若两个向量的点乘接近1则离得很近若接近0则离得很远利用投影可将一个向量分解成两个多个向量和x轴投影和y轴投影的向量和叉乘AxB -BxA判定左右内外若AxB为正则b在A的左侧若点P在点A、B、C内则ABXAPBCxBP,CAxCP结果都为正定义坐标系要求单位向量互相垂直(向量的叉乘得到垂直两向量的第三向量)可以获得任意一个向量分解为多个投影矩阵MxNNxPMxP矩阵没有交换律只有结合律转置(AB)TBTAT单位矩阵I对角阵I可以算出矩阵A-1可以用于返回变换前的结果向量的点乘、叉乘都可以转换为矩阵相乘点乘A·BATB叉乘1.叉乘化为矩阵axbA*b2.行列式计算叉乘变换2D 变换缩放X’SXYSYX轴翻转X’-XY’Y切变旋转这里可以理解为坐标基变换齐次坐标引入矩阵是为了更好的做线性变换却带来了平移的不便(直接用向量计算平移十分方便却不好线性变换)所以多出一个维度来存储平移的量就叫齐次坐标利用其次坐标为0或者1来表示点或者向量可以模拟出点在平移过程中位置会发生变化向量由于是0则平移不会发生变换。而且在点和向量进行加减也能完美匹配其定义矩阵没有交换律同时需要平移和线性变换的时候需要先线性变换再平移仿射变换线性变换平移3D 变换齐次坐标3D点(x,y,z,1)T3D向量(x,y,z,0)T旋转向量与欧拉角RXYZ(αβγ)RX(α)Ry(β)Rz(γ)利用右手螺旋定则这里的旋转矩阵很好理解首先按照人的习惯我们希望绕轴逆时针旋转为正绕x轴逆时针旋转(y-z)根据右手螺旋定则得到的方向和x轴一致则旋转角正方向和我们所希望的旋转角正方向一致绕z轴逆时针旋转(x-y),根据右手螺旋定则得到的方向和z轴一致则旋转角正方向和我们所希望的旋转角正方向一致绕y轴逆时针旋转(x--z),根据右手螺旋定则得到的方向和y轴一致发现只有从x向-z旋转某角度才是我们希望的正方向而向z旋转是我们认为的反方向旋转某角度。所以为了不改变传入的角度的情况下将旋转方向调转我们另旋转矩阵乘以一个负单位矩阵使传入正角则按照坐标轴反向旋转达到我们习惯认知中为正的效果罗德里格旋转公式绕任意轴旋转任意角度视图变换什么是视图变换视图想想如何拍一张照片model-view-project(mvp矩阵变换)找一个好的地方并安排好拍照的人模型变换找一个好角度并放好相机视图变化茄子投影变换定义相机position相机在哪elook-at/gaze direction朝哪个方向gup direction向上方向:控制歪斜t同时相机默认的向上方向为Y。永远朝着-Z方向看永远在原点上。把任意点相机移到默认点先平移再旋转利用逆矩阵的性质先算从原点到任意点再转置过来矩阵的三条列向量就是三条坐标系相当于将标准坐标系转化为相机坐标系的过程。由于旋转是正交矩阵所以转置和逆相同从而利用转置直接拿到将相机坐标系转化为标准坐标系的矩阵投影变换正交投影一种简单的理解方式把z轴去掉相机位于原点看向-Z轴向上为Y轴将生成的矩形平移并缩放为[-11]²标准方式将任意矩形坐标系转换到标准立方体坐标系下。透视投影如何做透视投影将视锥体压扁成立方体做正交变换投影操作利用相似三角形求出y轴的位置同理可以得到x‘(n/z)xx,y的变化是很好求的但是z的压缩不太好求由于是透视投影其远近需要被压缩到z对于中间的点z值被压缩后是会像远截面接近的而近截面上的点以及远截面的中心点z是不会发生变化的通过这个性质求得z的变化矩阵以此得到AnB n²同时z轴在远平面上的数值并不会改变因此得到AfB f²通过解上面两个方程得到A nfB -nf因此矩阵的Z轴一行为(0,0,nf,-nf)光栅化如何定义视椎体宽高比和垂直可视角度fov垂直可视角度t在y轴的高度n近平面上的z轴上的点tanfov/2 t/|n|r:中心点到右边的距离宽高比aspect 2r/2t r/t如何将投射完成的标准立方体显示到屏幕上什么是屏幕1.二维数组2.每个元素是一个像素3.一种经典的光栅成像设备光栅化在屏幕上绘画像素在屏幕上最小单位的小方块由红绿蓝三原色混合而成屏幕空间像素都是以x,y的形式表示其中x、y都是整数像素的范围从00到宽度-1长度-1像素的中心在x0.5y0.5屏幕覆盖范围为(0, 0) 到 (宽, 高)视口变换Z轴被忽略将原本【-11】²的正方体变换为【0宽】x【0高】视口变换视口变换矩阵光栅显示设备阴极射线管隔行扫描方法CRT显示器示波器帧缓冲器平板显示设备LCD液晶显示器OLEDLED发光二极管电子墨水屏三角形-基本形状单元由于我们需要将不定形状的东西 绘制出来需要统一做成基础形状便于传递数据这里我们将图像分成若干个三角形因为三角形有以下优点最基础的多边形任何多边形都可以转化为三角形独特的性质除非折成两个三角形否则永远是一个面三角形的内外很明确可以利用重心插值进行三角形顶点插值采样在某个点对函数求值就是采样我们通过采样将函数离散化。Inside函数inside(tri,x,y)1point(x,y)在三角形内0其余情况遍历所有点判断所有点是否在像素内for(intx0;xxmax;x){for(inty0;yymax;y){image[x][y]inside(tri,x0.5,y0.5);}}通过叉乘计算出见叉乘在图形学的应用点是否在三角形内如果碰巧点在三角形的边界本课程中不做处理也可以特殊处理如何优化效率包围盒优化利用包围盒(Bounding Box)对一定不会包含三角形的像素进行优化窄长的三角形的包围盒就不太友好有点低效率采样的走样介绍遇到的问题锯齿通过inside函数渲染出来的三角形有明显锯齿抗锯齿是图形学中重要的难题通过对原本三角形做模糊处理再进行采样可以抗锯齿反走样不能先采样再做模糊之所以会出现锯齿走样是因为出现了频谱混叠后面有讲摩尔纹车轮效应车轮倒转信号时间变化太快以至于采样跟不上变化的速度时域与频域(引入观察问题本质的数学模型)频域是描述信号在频率方面特性时用到的一种坐标系时域是描述数学函数或物理信号对时间的关系的一种坐标系。傅里叶级数展开(需要用到的数学手段)傅里叶变换会将时域转化为频域将函数表示为正弦余弦的加权和随着展开式越来越多越来越接近我们想要表达的函数如果采样的频率不够还原过来的函数就会越来越不精准频域和时域可以通过傅里叶变换和逆变换互相转换傅里叶频域图(需要分析问题使用的数学手段)可见光的颜色是由光的频率不同而产生的所以对图片进行采样在颜色剧烈变化边界的地方为高频信号。一般都是中间频率低的比较多外围频率高的较少而白色的十字架是因为使用图片连接模拟周期函数导致图片连接处出现剧烈变化高频。滤波删除特定的频率被称之为滤波高通滤波只显示高频信息只显示边界-锐化将低频信息盖住低通滤波只显示低频滤波画面变模糊将高频信息盖住卷积滤波卷积平均简化的定义结果为相邻数的平均值定理时域的卷积等于频域的乘积频谱混叠(问题的本质)由于采样稀疏因此出现频谱混叠从而出现锯齿走样如果屏幕中像素非常多密集的采样就不容易出现走样。因此使用分辨率高的显示器频谱的搬移间隔大不容易出现频谱混叠。同时将信息进行低通采样再进行采样即可反走样。反走样抗锯齿从上面的数学分析我们大概了解了问题的本质1.我们为了分析抗锯齿将图片的颜色作为值每一个像素作为时间构成时域函数图以便进行数学分析2.为了更直观我们进行了傅里叶变换将时域图转化为频域图进行分析3.颜色是值那么值的变化越慢频率越低所以数学上需要低通滤波来留下低频信号4.引入低通滤波使低频保留颜色变化趋于平缓5.应用图片中也引入低通滤波及对周围的像素取平均解决方法通过将每个像素进行模糊卷积fx,y卷积滤波平均然后再对灭个像素的中心取样在光栅化一个三角形时像素颜色的平均值fx,y 三角形的覆盖像素的面积超采样抗锯齿(MSAA)MSAA: Antialiasing By Supersampling这是一种对反走样的近似将每个像素的内部多增加采样点再进行模糊卷积MSAA X4缺点增加了很多的计算量其他的抗锯齿方法FXAA (Fast Approximate AA)快速近似抗锯齿图像的快速处理TAA (Temporal AA)对上一帧进行处理超分辨率从低分辨率处理成高分辨率与反走样类似也是解决了样本不足的问题目前可使用DLSS深度学习的方法进行超分辨率处理画家算法先画远的再画近的去覆盖远的问题难以确定谁在前谁在后深度缓冲Z-Buffer深度图-储存每个像素对应的最浅的深度结果图-储存最终的结果//默认深度为无限远foreach triangle T{for(eachsample(x,y,z)in T)//遍历任意一个三角形中的任意一个像素{if(zzbuffer[x,y])//如果此时的深度小于之前记录好的深度{framebuffer[x,y]rgb;//三角形着色zbuffer[x,y]z;//更新小的深度}else{//...}}}着色定义对不同的物体应用不同的材质Blinn-Phong反射模型高光Specular highlights漫反射Diffuse reflection间接/环境光照Ambient lighting漫反射余弦定理确定接受的能量亮度光照衰减I_1I_0/r²I光线强度朗伯着色器Kd颜色扩散系数Ld漫反射反射光漫反射只和物体本身与光线有关与观察方向v无关引入max0n·l是因为若点乘小于0说明是从下面射过来的没有意义。若两个向量的点乘接近1则离得很近若接近0则离得很远。得到公式高光Ls高光反射光Ks镜面反射系数通常认为是白色的引入半程向量h如果镜面反射方向与观察点接近则半程向量h与法线方向n接近Blinn-Phong反射模型是对Phong反射模型得改进引入半程向量h比使用镜面反射方向r计算量更小由于cosα的容忍度太大导致高光太大所以引入p次幂一般使用100-200次幂环境光照环境光与入射方向、法线方向、观察方向无关是一个常数(模拟自然不是这样)最终结果着色频率着色频率不同着色效果也不同以顶点法线为单位着色Gouraud shading以三角形平面为单位着色Flat shading以像素为单位着色Phong shading求顶点法线从一个球来获取法线方向是容易的复杂的模型通过将相邻的四个面进行对面积的加权平均得到四个面的平均法向量。逐像素着色通过顶点法线的重心插值来实现实时渲染管线简化的流程输入空间中一系列的点顶点处理三角形处理光栅化着色片段像素处理帧缓冲区处理输出Shader编程利用GLSL对顶点着色器和片段着色器进行编程。片段着色器对每个片段都执行一次。以下是一个GLSL片段着色器的程序代码uniform sampler2D myTexture;// 获取纹理 uniform是全局变量uniform vec3 lightDir;//获取光照方向varying vec2 uv;//获取uv坐标varying vec3 norm;//获取法线坐标voiddiffuseShader(){vec3 kd;//获取kd系数kdtexture2d(myTexture,uv);kd*clamp(dot(–lightDir,norm),0.0,1.0);//Phong模型漫反射gl_FragColorvec4(kd,1.0);//输出该像素的颜色}纹理映射纹理映射就是定义任意点的基本属性。每个三维的模型上的任意点都能对应在uv坐标上的某个点上这个对应应该是美术来做。纹理可以被重复使用插值插值就是为了取得平滑的过度在不平滑的部分中间插入平滑值重心坐标这里不是质心概念三角形上的任意一个点都可以用AB,C三个顶点的线性组合表示出来αAβBγC.表示这个点的α、β、γ就是这个点的重心坐标注意:需要满足αβγ1的条件。若αβγ均非负数则x,y点一定在三角形内。αβγ1之所以需要等于1是因为需要和三角形在同一平面内。α、β大则γ小。点被限制在平面内移动。若是可以超过1那么α、β、γ将有无穷多组解。满足条件(x,y)的解会构成一条直线。作用有了重心坐标就可以将三个顶点的属性插值在需要的点缺点值得注意的是在投影下不能保证坐标不变所以要线插值再进行投影。插值应用可以对纹理颜色等进行插值以纹理为例1.在着色期间 对某一个纹理采样点像素进行着色时可以通过纹理采样点的坐标得到其所在三角形再以三角形顶点的纹理u,v坐标(纹理坐标定义在三角形的顶点上)进行插值得到采样点的uv将这个u,v作为漫反射系数Kd从而影响颜色。达到视觉上颜色形成纹理的效果问题1纹理太小了怎么办-双线性插值取周围4个点进行两次线性插值可以先对上下两条线进行线性插值得到两个点再进行一次就可以得到目标点的插值问题2纹理太大怎么办-Mipmap会出现摩尔纹(走样)与前面的反走样一样出现的原因是因为一个像素(内信息变化频率过高接受信息的像素却不够高频率。导致多个纹理采样点使用同一个像素的颜色例如远处的像素就覆盖了更多的纹理面积形成走样。可以通过读取周围众多采样点的颜色做插值来缓解但是消耗大所以用mipmap来解决这个问题mipmaplevel0是原始图像每提高一个level分辨率小一倍利用相邻的四个像素的rgb做平均操作。做mipmap比会增加原本图像1/3的额外存储量。(空间换时间)在屏幕空间中取当前像素相邻的像素带你并查询其对应的uv坐标。计算出当前像素点与其他像素点距离其他像素点的最大值L。根据最大值L通过上面公式计算得到该点所处的层数D。比如获取周围四个像素点的均值。那么L长度近似2取第一层也就是缩小一倍像素的u,v坐标图进行采样就不需要计算像素插值了提前插好了至于取哪个坐标拿u,v除以层数就可以得到u,v在该图的对应u,v过渡不平滑-三线性插值如果算出来的D值是一个小数这会造成图片Mipmap做错不平滑的问题。对该D值分别进行向下和向上取整。如D1.2Z则取1和2对两个D值分别进行双线性插值见纹理太小。对两个插值的结果再做一次线性插值如0.8xD10.2xD2过度模糊-各向异性过滤如果只使用Mipmap则远处会出现过度模糊的问题完全糊成一块。原因是左边屏幕的一个像素如果只是使用mipmap对应到右边取得是一块近似方形区域的插值而实际像素应该显示的是如上图一样的长条形的区域的像素插值才合理而各向异性过滤就是如下图一样保留了被x,y压缩后的纹理可以直接取压缩后纹理上的像素点但是对于x,y都同时压缩的情况无法得到解决解决斜向的纹理-EWA过滤。通过多次圆形的采样来解决过度模糊的问题。纹理映射的应用纹理内存范围查询例如mipmap纹理是GPU上的一块内存我们可以对内存做范围查询。环境映射Environment Map球面环境映射Spherical Environment Map将环境光反射在球上就可以获得该场景的环境光。球面映射Spherical Map将球面环境映射可以展开为一张图但是上下会被扭曲类似世界地图立方体映射CubeMap为了解决球面扭曲的问题使用立方体来进行环境光照的纹理映射。凹凸/法线贴图Bump/Normal Map根据高度改变发现达到凹凸不平的视觉效果其最大的意义是为了表现相对高度来展示凹凸效果减少面数。凹凸、法线贴图仅表示凹凸效果不会改变几何形体。计算法线贴图一维假设下图中的蓝点为p点p点原来的法线朝上即n§ (0, 1)下图蓝色曲线为使用法线贴图后的效果。通过dp (c[h(p1) - h§])/1求出两点的高度差。其中c为常数表示凹凸贴图的影响程度h为高度p点、p1点对应高度。因此切线可表示为(1,dp)。切线与法线为垂直的关系因此n§ (-dp, 1)计算法线贴图二维二维的情况下有u、v两个方向的变换。实际情况下法线方向不一定朝上这里的例子是基于一个局部坐标系确定的。n§ (0, 0,1)dp/du c1 * [h(u1) - h(u)]dp/dv c2 * [h(v1) - h(v)]n (-dp/du, -dp/dv, 1)位移贴图Displacement mapping真正的改变模型高度但是需要采样点小于纹理变化所以对性能要求高三维纹理利用三维空间中的噪声函数进行纹理映射例如Perlin Noise预先进行环境光遮蔽计算模型阴影体渲染通过三维纹理记录信息然后进行渲染几何几何表示方法的分类隐式可以通过一个函数来表示的几何体。例如圆可以表示为fxyz0优点可以很容易判断某个点是否在几何体上缺点难以通过函数判断出几何体的真实形状显式通过参数映射表示的几何体uv坐标转换为xyz坐标参数映射通过某个带有uv的函数分别表示出xyz的坐标直接给出几何体缺点难以表示出某个点是否在几何体上。优点容易看出来几何体的真实形状隐式表示对于复杂的几何体十分不友好。