作者:HexUp
来源:HexUp(微信号:knowforfun)
计算机图形学,Computer Graphics,是利用计算机来生成图像的学科。咱们喜欢打游戏、看电影的小伙伴一定不陌生,因为游戏中的画面和电影中的特效都是需要依靠CG技术来生成的。不过游戏开发不等于计算机图形学,这一期视频我会聚焦于图形学本身,也就是如何让计算机绘制图像这件事情,下一期我再来介绍游戏引擎开发相关的学习路线。
这门学科很有意思,但也比较复杂,即便是看起来很简单的问题也需要涉及多个学科的知识,例如为了生成逼真的图像,尤其是模拟真实光线的视觉效果,真实感渲染技术需要研究数学和物理理论;想要让绘制的图像好看,还需要研究色彩科学和人类的视觉感知体系;最后,想要把这些算法在计算机中付诸实践,就需要扎实的编程技巧,由于CG的计算通常都非常耗时,还需要有一定的硬件知识来完成优化。
这个学习路线将会从理论侧开始介绍到编程侧。理论侧主要是CG需要的数学理论,CG本身的算法,视觉感知的理论等等。编程侧主要是编程语言,图形学的API和硬件知识。图形学本身是一个非常注重实践的过程,你需要不断去编程实现这些算法,而且比较好的地方在于,这些算法给的反馈非常直接,你可以看到自己渲染的结果,这就非常适合我们去学习。
图形学的方向有很多:渲染、几何、动画、建模、物理、仿真等等。下面我们挑一些具有代表性的讲一讲。
首先,数学是学习图形学的基础,主要是微积分、线性代数和几何学。渲染方程告诉了人们渲染是什么,而渲染方程就是一个积分公式,这个公式看起来复杂,但其实想法很简单,就是将所有射到某个点的光线叠加起来,只是准确地描述这个叠加需要用到微积分来表示。想要理解和计算这个方程自然需要理解微积分的知识。
图形学模拟3D环境的时候需要计算物体的3d坐标和位置变换,这个时候就需要用到几何学和线性代数。实际上,现代的几何学跟线性代数密不可分,几何学的基本量都是由代数概念来描述的,比如向量用来描述点的坐标,方程用来描述曲线,矩阵用来表示线性变换,比如物体的平移、旋转等几何变换。
另外图形学还需要大量处理形状和曲线,计算这些东西的时候也少不了会用微积分和线性代数。
所以说,数学是计算机图形学的入门基础。那学习图形学需要把数学学到什么程度呢?其实入门的话并不需要特别难的数学知识,比如微积分,能理解积分的概念、计算简单的导数和积分就可以;线性代数和几何学,则需要知道向量、矩阵的概念,能够会计算三维空间中的坐标变换。这些知识足以应付图形学入门了,而这些知识的体量基本上大一的数学课完全能覆盖。
而随着学习的深入,当你想要模拟更真实的世界的时候,你还会遇到更高深的数学,例如图形学里面有一个分支是物理引擎,也就是模拟现实世界中的物理规律,例如物体的碰撞、液体的流动等等。大名鼎鼎的纳维尔-斯托克斯方程就是用来建模流体运动的一组偏微分方程,求解这个方程仍然是一个非常困难的问题。像这种细分方向可能就会需要更深入的数学知识,到时候再有选择性和针对性的学习即可。
渲染是图形学的核心问题之一。渲染就是绘制图像的过程,其中有些概念你可能已经听过,比如光线追踪。我们讲的游戏画面很好,通常就是渲染这一部分完成的。渲染大致可以分为真实感渲染和风格化渲染。真实感渲染也叫做基于物理的渲染,风格化渲染则更多受到绘画艺术的影响,可以提供不同的艺术观感,比如塞尔达、原神、无主之地这类游戏近似于动漫的画风就是风格化的渲染。
下面我们主要讲真实感渲染。
其实真实感渲染的核心算法思想并不困难,就是光线追踪,而这个计算过程可以在数学上用一个渲染方程建模。渲染方程本身就是一个积分,这个积分项主要就是各种光线的叠加,但是如何快速、准确地计算这个积分中的组成项,就成了科学家和工程师需要绞尽脑汁解决的问题了。当然,上面渲染方程只考虑了自发光和反射,其他光线的路径(比如空气散射等)可以额外扩展,整体思路是一致的。
有了渲染方程,那么实现渲染基本可以分为三个问题:
1. 如何计算这个积分,经典的方法有蒙特卡洛积分法,可以对被积函数采样求值计算;
2. 如何计算各种光线在各个物体表面的散射,通常我们用BSDF这个概念来概括,全称bidirectional scattering distribution function. BSDF囊括了反射和折射,分别是BRDF和BTDF,其实这个概念还可以扩展,也就是BSSRDF,用来建模光线更复杂的散射行为,比如次表面散射。
3. 如何判定光线跟踪算法递归的中止?可以设定一个最大递归次数,也可以使用经典的俄罗斯轮盘算法。
除了以上核心内容之外,一个渲染系统还包括了:相机参数、可见性判定、光源的性质等等,所以这些知识也需要具备。
说到这里,相机的成像和投影原理在图形学中也十分重要,这部分有大量的矩阵变换和三维几何学运算。而且学习这一部分知识是非常有用的,不光图形学需要这个,计算机视觉也需要。更具体一点是三维视觉,比如自动驾驶需要的三维地图重建。
材质和纹理。在真实感渲染中,我们不可避免地需要用到材质和纹理。材质就是描述一个物体如何跟光交互的属性,比如金属的光泽、玻璃的透明,这些都是材质属性,上面提到的BxDF就是材质的参数。纹理主要就是增加物体表面的细节的,常见的纹理就是图片纹理,比如砖块贴图。在实际应用中,你还需要掌握纹理映射等概念,然后你还需要懂得一些纹理抗锯齿的知识,这样选择合理的抗锯齿方法可以大大增加程序的效率。
可见性的判别。这个是图形学中最基础的算法之一。任何图形学算法如果不做区分渲染出每一个物体,那么计算量会瞬间爆炸,所以人们就会设计出可见性的判别算法来判断哪些物体和像素是可见的,这样只计算这一部分就会轻松很多。
说到这里,我们再聊聊渲染管线。光线追踪是按照像素来渲染的,另外一种常见的渲染方法是光栅化渲染,他是根据物体的几何信息(通常是三角形网格)来计算会影响哪些最终输出的像素。这种方法的好处就是计算效率很高,工业应用很喜欢用这种渲染管线。一个典型的渲染管线的例子包含顶点处理、光栅化、片元处理和最后的混合。顶点着色器和片元着色器是我们可以编程控制的部分。其他部分通常交给GPU自行完成。
你还需要了解图像的表示和处理,比如像素、图像格式、合成和压缩方法;关于图像处理,你至少要明白什么是卷积操作和滤波器,采样理论和傅里叶变换也是需要了解的内容。
动画,大致可以分为两类,一类是动作动画,一类是程序化生成的动画。前者主要是制作人物、角色的动作动画,后者是依赖某种规律去演化生成动画。对于动画,你需要学习关键帧技术,骨骼绑定、重定向等等,如果你希望制作的动作动画非常自然,还需要研究一下人体的构造,以模拟肢体做动作的时候表面纹理产生的变化。如果是程序化生成动画,比如物理现象的模拟,这个时候就需要去进行数学建模然后写程序实现这个模型。
色彩学和视觉感知。由于图形学生成的画面最终是给人看的,那么我们少不了要研究人眼的视觉系统和色彩本身。色彩和光线的行为是非常复杂的,有很多门道。比如早期简化的数学模型在计算颜色值的时候会对光线强度线性相加,但实际上这个过程不是线性的。再比如,颜色的搭配也是一门技艺,好的搭配赏心悦目,丑的搭配让人嫌弃。人眼的感知系统也很有特色,比如在不同环境光下人眼对颜色和光线的感知是不同的。想要绘制出看起来很舒服的画面,我们也需要研究这些内容。
下面我们来聊聊编程侧的内容。
图形API、计算机硬件。C++仍然是图形学的通行语言,这是最主流的、不可能绕开的语言,所以一定要比较熟悉。常见的图形学API有OpenGL、微软的DirectX、苹果的Metal和开源的Vulkan。在学习图形学的时候自己造轮子不依赖这些API实现渲染器是可行的,但是在真正的工业应用中,我们都需要依赖这些API才能适配目标平台、充分发挥硬件性能、降低开发难度。因为图形学的计算量一般都很大,所以了解计算机硬件的原理也是有必要的,这样才能榨干硬件的性能。
OK,我们的入门路线就介绍到这里,由于图形学的知识实在是过于复杂、覆盖面太广,这一个路线肯定不能覆盖到方方面面,但是如果你对上述概念都有所掌握的话,一定能够实现很多有意思的东西了,这之后就可以按照自己的兴趣再找一个领域深入钻研。
本文转自:微信公众号HexUp,转载此文目的在于传递更多信息,版权归原作者所有,如需转载请联系原作者HexUp。