王建华
(四川大学计算机学院,成都 610065)
游戏引擎[1],是经过精心设计,可以对游戏进行基础支持的一系列实时处理模块的有机结合,是游戏的核心程序。在游戏中,玩家所体验到的场景的运行速度、绚丽的特效,真实的渲染效果等各方面都是由游戏引擎决定的。3D游戏引擎是游戏引擎中的一个难点,是为3D游戏量身定做的一系列工具的总和,要比2D环境下的引擎的设计复杂得多。
3D游戏引擎是很复杂的,实现一个完整的3D游戏引擎不是一件易事,为了简化项目复杂度并且保证引擎能进行正常的工作,只实现3D游戏引擎的基础图形部分。因为这个部分可以将游戏的输入数据转化为输出图形,并在屏幕上进行显示,人们所能接收的经过处理的信息就是显示在屏幕上的图形,这个部分的好坏直接影响到了使用该3D图形渲染引擎开发的游戏的体验。
由于包含着色器的3D渲染引擎的实现比较复杂,不便于初学者理解,本文采用比较容易实现的固定管线,虽然固定管线的渲染效果比着色器的渲染效果差,但是其工作流程十分清晰,原理也比较容易理解,便于初学者掌握,并激发其在这个方向上继续研究下去的动力。管线最终的流程如图1所示。
图1
(1)顶点缓冲区
用于存储用户输入顶点的位置数据,颜色数据,法线数据,并存储各顶点在摄相机坐标系下的深度值,为三角形绘制时的插值计算提供必须的深度值。顶点缓冲区还应提供复制的功能,以及能对顶点进行变换的接口。
(2)索引缓冲区
用于存储由顶点所构成的平面的面数据(为了便于计算,统一采用三角形平面)这些数据有:构成三角形的三个顶点的序号,三角形的顶点的卷绕方式,三角形平面的面颜色,三角形平面的纹理以及其各顶点的纹理坐标。索引缓冲区还应提供平面的背面剪裁功能,及时剔除不需要进行绘制的平面,减少不必要的计算开销,提升引擎的渲染效率。
(3)屏幕缓冲区
用于存储屏幕某点最终应该显示的颜色,对于有多个3D空间中的点都会变换到同一屏幕上的点的情况,为了简化问题,认为所有的平面都是不透明的,不进行颜色遮罩处理,而是简单地选取距离摄相机最近的点的颜色作为此点的最终色,在一次绘制完成后,清空屏幕缓冲区,然后进行下一次绘制。
(4)几何变换中的基本工具
为固定管线提供基本的功能支持,这些工具包括,三维向量,四维向量,三阶矩阵,四阶矩阵,摄相机,管线中经常要使用这些工具,例如,可用其进行所需的各种变换,将3D空间中的点映射到屏幕空间上。
(5)图片采样器
用于读取资源图片,并生成MipMap所需的减采样后的纹理,并负责对图片的存储结构进行分析,得到所需要的像素的颜色,在图片使用完后,负责资源的释放工作,防止内存资源过于紧张。
(6)场景图
用于处理多对象之间有层次关系的情境,只需对顶层实体进行变换,即可实现对其子实体的级连变换,很大程度上简化了使用此3D图形渲染引擎的游戏开发者的工作,使其将更多的精力投入到游戏其他方面的设计与制作中,提升开发游戏的效率,缩短游戏的开发周期。
(1)世界空间变换
在3D图形程序中,有些物体的位置在整个程序运行期间都不会变化(相对于游戏世界),我们称其为静态对象;而有些物体不是静止不动的,而是需要根据输入的参数或根据自身的运行状态进行动态调整的,我们称其为动态对象。对于后者,我们应提供一些必要的动态变换功能,例如对象的平移和旋转,有了这个功能以后,用户就可以很方便地对动态对象进行控制,使对象能按设定的模式进行工作,而不用在每帧更新时输入对象在新位置的数据,因为其在新位置的数据会自动计算,在很在程度上减少了用户的工作量。
(2)视点空间变换
我们需要通过模拟人眼观察物体的过程或模拟照相机摄像的过程来实现较为真实的渲染,因此需要将全部对象转换到视点坐标系下,在这个坐标系下,摄相机处在原点位置,摄相机的朝向向量,摄相机的俯仰程度向量,以及一个侧向向量构成了此坐标系的三个基向量,这样做符合人们的日常生活经验,便于人们理解和接受。在摄相机空间中,我们需要进行平面的背面剪裁,及时剔除无需考虑的内容,提升系统的效率。
(3)剪裁空间变换
对视角空间进行进一步的变换,将由近平面,远平面,左平面,右平面,上平面和下平面组成的一个平头视锥体转化为一个立方体,由于对立方体的剪裁效率要远远大于不规则形体的剪裁效率[4],所以通过这个变换,降低了后续的视椎体剪裁操作的计算量,减少了资源的消耗。
(4)标准空间变换
将剪裁空间的非标准立方体转化为一个标准立方体,标准化的好处是可以更好地表现出各点的位置关系,并且为后续工作的进行奠定了基础。
(5)屏幕空间变换
将标准空间中的点变换到屏幕空间中用以显示,这个过程的一个非常重要的任务是进行相应的左右手系的变换以便正确显示计算结果。
在此示例中,存在一个天空盒,天空盒[5]实际上是在立方体的内部观察立方体,并且将图片贴在立方体内侧而形成的。在立方体的中心放置了一个摄相机用于观察,摄相机会不停地进行水平旋转,因此可见内容会随着时间而出现周期性变化,实验总共使用了3张图片用来进行贴图操作,其中,一张用于地面贴图,一张用于天空贴图,还有一张用于四周景色的贴图。在此示例中采用透视投影,因此会出现近大远小的感觉,距离摄相机近的贴图会有明显的拉伸感,见图2:从中可以看出,总体渲染效果能满足一般的3D图形程序的要求,但是由于浮点数的误差,在两个平面的交接处,有可能会出现一点黑色的缝隙。
图2
本文利用C++语言[3]和Visual Studio 2015开发工具,实现了3D游戏引擎中的渲染部分,并通过对图形渲染部分的详细说明,使读者对3D游戏引擎中的渲染部分有了更深入的了解。
当前完成的3D渲染引擎实现了进行3D渲染时所用的基本功能,还可以完成一些较为高级的功能,但是这仅仅是一个示例性质的引擎,并没有诸如资源管理、配套的开发工具和与硬件良好结合等在商业用的高端引擎中存在的一些特性,因此这个引擎是不完善的,有着很大的改进空间,但是此示范性引擎的优点在于以通俗易懂的方式向读者阐明了3D渲染引擎的一种实现方式,达到了便于理解和掌握这一目的。
参考文献:
[1]David.H.Eberly.3D游戏引擎设计,实时计算机图形学的应用方法[M].北京:清华大学出版社,2013.
[2]王长波,高岩.3D计算机图形学[M].北京:机械工业出版社,2010:10-90.
[3]Charles.Petzold著.Windows程序设计.方敏,张胜等译.北京:清华大学出版社,2010:506-642.
[4]David.F.Rogers著.计算机图形算法基础[M].石教英,彭群生等译.北京:机械工业出版社,2005.
[5]石教英.虚拟现实基础及使用算法[M].北京:科学出版社,2002.