很早以前就被人推荐了闫令琪老师的Games101《现代计算机图形学入门》课程,之前抽空断断续续看了一部分,前面还比较顺畅,后面稍微有点吃力,就放下了,最近又拾起来看了一遍,发现比之前要理解的更好一些,想到自己也确实很久没有更新自己的技术博客了,故而觉得有必要写篇学习笔记记录一下。
我相信很多人开始劝退图形学的第一个地方是看到矩阵和一些数学公式的时候开始觉得难了,这在后来看来其实并不是最难的,因为仔细理解后,矩阵只是经过一系列变换得到的一组数据而已,因为每个变换都可以写成一个矩阵形式,所以那种复杂变换都是由许多变换的矩阵相乘而来,而矩阵又满足结合律,但是不满足交换律。知道这些就不会再惧怕看到矩阵了,因为本来一些矩阵就是推导而来,除非是非常简单的变换,否则矩阵本来就不是单纯让人看就能看明白的一堆数,这听上去有点像四元数一样,前期知道作用即可。这次看完课程最大的感悟是:理解了很多之前不清楚的为什么要这么做的原因。举几个例子,很早前我见到过一个坐标被写成(x,y,z,w)的形式,对于一个三维坐标而言,x,y,z三个数就够了,我一直不明白为什么后面还有一位w,当时搜索之下也只了解到齐次坐标这个名词,但是它具体的作用和为什么引入了这个数没有深究,直到看完课程后,我深感当初想到这个方式的人有多了不起,因为真的太精妙了,这个后面我会说。再比如以前看一些Unity的shader代码里,总会mul一个MVP的矩阵,也不懂是为啥,甚至后面被Unity封装成了一个API叫UnityObjectToClipPos,直到看完课程,才发觉原来这不就是把物体渲染到一个平面上必须经过的三个变换嘛,正如前面所说,任何变换都可以写成一个矩阵形式,所以是M、V、P三个矩阵。
接下来就详细记录下目前学习到的知识吧。首先从渲染管线的概念开始,渲染管线其实就是把3D的场景或者物体,最终输出到一个屏幕上的过程,它要经过好几个过程,所以就像流水线一样,一步一步的,而闫老师一开始讲的点乘,叉乘还有变换都是基础概念,因为这些都会在渲染管线中使用,而对于物体的任意一个点的变换前面提到都可以写成一个矩阵乘以一个坐标点的形式,但是这不绝对,只有像缩放,旋转等线性变换才可以,而有一个平移的变换不包含在内,它一开始需要写成一个矩阵乘完以后再加一个矩阵的形式。这就和前面的处理起来不一致,而为了解决处理不一致的问题,所以引入了齐次坐标的概念,也就是在3维坐标后面再加一位,其中加的这一位,1代表点,0代表向量。这个并不是随便定义的,因为刚好两个点相减的话代表的是一个向量,而减完后刚好最后一位就是0了,恰好就是前面所说的0代表向量,而如果一个点加上一个向量,代表这个先沿着这个向量移动后的位置,那对于最后一位来说1+0 = 1,刚好还是代表一个点。所以我才说佩服当初想到齐次坐标这个方案的人,真的很精妙。而引入了齐次坐标后,对于3D的平移变换也就可以写成一个矩阵形式了。那么结合前面的缩放和旋转等可以描述成一个矩阵的变换就得到了一个名词:仿射变换。学习变换的目的就是因为把物体渲染到屏幕上一开始要做的事情就是变换,假如有一个摄像机,和一个摆放好的模型,对于模型而言本身上面的点都是局部坐标,那么第一个就是要把他们转换成世界坐标,也就是Model变换,然后要做的就是把他们通过平移和旋转,使得相机在原点位置并朝向Z轴的负方向(这里是和Z轴同向还是反方向要根据左手系坐标和右手洗坐标不同,对于右手系是Z轴的负方向),也就是View变换,最后再进行一个投影变换最终得到要渲染的这张2维图像,但是最后的投影变换根据相机的类型不同,也略有不同,需要区分正交相机还是透视相机。对于透视相机,其实就是先把视锥挤压成和正交相机一样的类似长方体的描述,这就和正交相机差不多了,然后再对它做一次和正交投影即可,本质也是为了使两种变换都有相同处理的地方,简化不同点。如课程视频里的图:
这里说一下shader,其实shader就是把整个渲染流水线的一部分拿出来可以通过编程的方式来进行自定义,比如前面提到的变换主要就是shader里的Vertex函数,主要用来处理顶点的变换的。而与之对应的片元函数Fragment函数,主要就是处理部分光栅化流程,对像素的着色处理。
碍于图形学是一个相当庞大的学科,所以我的第一篇主要还是记录变换相关的学习。光栅化打算留待后面再说。顺带说些题外话,真的非常感谢闫令琪博士的视频,更佩服老师的为人,做技术多年,见过形形色色的同事也好,网上的所谓大佬也好,说真的,能有闫老是这样的成就,又虚心和和蔼的人真的很少见,在当下的社会环境中,充斥着各种没有真才实学,只知道点皮毛就冒充大神,还与人交流态度傲慢的人非常多,所以生活中,我对这样的人嗤之以鼻,也不会选择和这样的人深交,如果不是必须解除,我会直接选择不再和这样的人接触。而我觉得真正值得让人尊敬的就是像闫令琪老师这样的人,不仅有真才实学,最最关键的是他真的想要教会别人,而且讲解的过程真的达到了深入浅出,可能会把一个很复杂的东西,以很简单的方式逐步的告诉你原因。这让我想起年轻时问一些人问题,你从他们口中永远只能听到两个技术名词,要么就是:这不很简单嘛,但是你真问他具体怎么做,他就闪烁其词了。所以后面我学习东西喜欢去搜索文章和别人分享的东西来看,几乎很少直接和别人探讨技术问题了, 现在的话,得益于ChatGPT的出现,我有了更好的老师,那就是AI,我觉得它的回答比大多数人都要实用和靠谱,它将会是往后我学习技术的一位好老师,而现实里,只有像闫令琪老师这样的人,才值得我们去交流学习和探讨。