在游戏开发领域,3D游戏引擎是构建复杂游戏世界的核心工具之一。本文将介绍3D游戏引擎的基本概念,包括渲染技术、纹理映射、光线处理等,旨在帮助初学者和中级开发者了解3D游戏引擎的构建过程。
游戏编程是一个涵盖多种技术技能的广泛领域,不仅仅是特定编程语言的编程。本文将尽量简洁,专注于主题,不涉及声音、音乐、物理、游戏UI、游戏脚本等其他内容。
开发游戏是编程中有趣的一部分。程序员在编写不同类型的应用程序时,经常会问自己(或更经常是其他人问)是否能够编写游戏。虽然由精灵组成的2D游戏可以在短时间内编写完成,但完整的3D游戏引擎并不是一个容易的话题。它需要时间,时间,时间来完成。
认为,单个开发者很难处理商业质量3D游戏引擎的所有主要子系统,而更倾向于处理他们最擅长的部分。因此,除了需要时间之外,还需要一个团队。
此外,还需要良好的数学和物理知识。
有人会问,为什么不使用现有的引擎,而是从头开始编写自己的引擎呢?这是一样的,或者几乎是一样的。但是,编写自己的游戏引擎,可以学习和练习快速编码,对吗?
还需要一本好书来开始学习游戏引擎。再次推荐Andre Lamothe的技术书籍(《3D游戏编程大师技巧》)。这位作者有一系列专门讨论这个话题的书籍。也许它不是现代游戏编程的最新技术,但对于初学者和中级游戏开发者来说,作为基本来源已经足够了。这是一个很好的开始阅读和学习的地方。
本文将尝试传达从阅读这本书中获得的经验。
所有3D图形都是由简单的多边形(称为三角形)创建的。所有现代图形卡只处理这些简单的多边形。
例如,请看上面的图像。这个简单的立方体由12个三角形组成。这个3D模型恰好有8个顶点和12个定义的多边形(三角形)。因此,要渲染3D立方体,必须渲染它由多边形组成的部分,所以基本上只处理三角形。如果知道如何绘制三角形,就能渲染任何形状的3D对象,甚至是最复杂的。
将要介绍的第一部分是线框绘制。这是一种简单的渲染技术,只绘制三角形的边缘,但不填充颜色。需要一个好的(或任何可用的)线绘制算法,比如Bresenham算法。可以在这里找到它,有所有的解释。
在下面的图像中,可以看到这个算法是如何工作的:
Slope = dy / dx = m = (y1 - y0) / (x1 - x0)
基本上,计算线斜率,并从起点到终点进行插值。
在下一个图像中,可以看到在运行线框模式时,演示应用程序是什么样子:
现在3D模型完全可见。但是,可能会问,立方体的侧面不可见(背面)发生了什么。它们没有在这个场景中渲染,以避免给观众带来太多细节,尽管在线框模式下,通常也会显示它们。
所有3D对象都有一定的体积。在线框模式下,可能无法清楚地看到它。然后,需要用某种颜色填充这些三角形。现在,让假设所有三角形都有相同的颜色。现在,如何填充三角形?它并不比绘制它更难。只是,应该将一般三角形转换为更容易处理的东西。
在下面的图像中,可以看到如何将一般三角形分割成两个简单的三角形,这些三角形更容易使用基本的扫描线光栅化器进行光栅化。
对于这个扫描线光栅化器的实现,请看下面的图像:
扫描线光栅化器计算两条线(如果处理的是平底三角形)的斜率。类似于绘制线条时,从顶点到底部填充内部像素。对于平顶三角形,情况也是如此,只是从底顶点到三角形的顶部。
现在可以看到演示应用程序在单色模式下运行的屏幕截图:
立方体现在看起来更有趣了,对吧?它应该在3D世界中占据一定的空间。
现在是时候提一下光线了。现实世界中有光线,所以3D世界中也应该有光线。由于光线数学可能相当复杂,不会深入讨论,而是会展示一些基本的光线建模算法,以及它如何反映到单色渲染中。
有几种类型的光线:
所谓的平面着色考虑了表面(三角形)法线,并将不同光源的影响平均到相应的表面(三角形)。
在下面的图像中,可以看到:
在下一个图像中,可以看到在运行平面着色模式时,演示应用程序的屏幕截图:
现在立方体看起来更真实了。所以,之前的三角形光栅化算法在这里没有改变,它只是考虑了每个表面(三角形)的不同颜色。
这种着色类型为3D世界带来了更多的现实感。这是渐变类型的着色。为此,需要每个顶点的法线,而不仅仅是表面(三角形)法线。
使用Gouraud着色进行三角形光栅化的算法如下:
因此,当绘制三角形时,颜色在顶点之间进行插值。下面的图像显示了在运行Gouraud着色模式时,演示应用程序的屏幕截图:
由于显示了立方体表面如何对光线做出反应的平滑渐变,这个3D立方体现在看起来更好了。
为了让3D对象具有某种材料或纹理,以增加它们所代表的现实印象,图像(纹理)在这里发挥作用。但是,如何将它们应用到表面(三角形)上呢?
让在这里说有两种类型的纹理:仿射和透视。下面的图像显示了差异:
在下一个图像中,显示了纹理映射的设置:
这里的关键是将图像(纹理)的区域转移到表面(三角形)上。由于已经在Gouraud着色部分介绍了颜色插值,这里使用了同样的事情。在这里插值图像坐标,而不是颜色。
在下面的图像中,可以看到在纹理模式下运行的演示应用程序的屏幕截图(没有应用着色):
现在,这看起来非常好,非常真实,不是吗?
这是灯光和应用纹理的简单组合。在插值过程中,当光栅化三角形时,混合表面(三角形)的最终颜色和应用的纹理。很容易将表面(三角形)的默认颜色设置为纯白色,然后应用照明,然后结合计算出的像素值和纹理像素。
在下面的图像中,可以看到:
这几乎足够真实了。
在这里,使用Gouraud着色而不是平面着色,并将其与应用的纹理混合。
在下面的图像中,可以看到:
现在,这对来说已经足够好了。怎么看?
到目前为止,肯定理解了如何使用自己的软件渲染器以不同的模式渲染3D模型。然而,这只是系列文章的第一部分,该系列文章将涵盖设计的3D软件渲染器。就本文而言,可以自由地测试技能,构建自己的光栅器。在下一篇文章中,将展示每个3D游戏引擎的基础知识:3D模型、投影、相机系统、纹理过滤、游戏物理等。
下一篇文章还将涵盖可以进行的优化,以便软件渲染器不必像最初假设的那样慢。