设计一个3D游戏引擎

最近学习了一些计算机图形学的知识,重新点燃了自己想要学习游戏开发的热情。但是,计算机图形学与游戏开发还是有很大区别的。计算机图形学关心的是如何高质量的还原真实世界的视觉效果,而游戏开发则要求一个可编程性更强的系统。因此游戏引擎,首先是为开发服务的。

游戏引擎,应该允许游戏开发者,轻松的定义实体,操控这些实体的位置、模型、滤镜,最终通过渲染引擎渲染到屏幕上。甚至要提供一些易用的图形化制作工具,比如关卡编辑器,地图编辑器,实体编辑器,脚本语言,配置表,这些输出成数据文件。这些数据将被加载到内存,通过渲染引擎输出到屏幕。

[制作工具]–>静态数据–>[用户输入处理、AI update、物理引擎]–>动态数据–>[渲染引擎]–>最终画面。

游戏引擎=制作工具+程序API+渲染引擎。

而游戏引擎的关键,就在于处理数据。

哪怕一个最简单的终端贪食蛇游戏(这是我11岁的儿子写的)也需要符合这个标准。这个终端游戏制作工具不需要,他的素材是一些终端字符,google担任了这个制作工具的角色。程序API更新贪食蛇的动态数据,然后渲染引擎将动态数据映射成特定的终端字符打印在屏幕上。

开发一个3D游戏,数据结构更加复杂一些。理清了这个结构之后,3D游戏可能比2D游戏更容易开发一些,因为3D数据结构毕竟更接近真实世界。我们将整个待渲染的世界,称为【场景】,场景中摆放着各种【模型】。对于物理引擎部分,只需要模型的数据就可以了,而对于渲染引擎,则还需要【光源】和【摄像机】。

物理引擎

一个粒子由*位置position、速度velocity、质量mass、力force(加速度acceleration)、阻尼damping(简化一个物体在一个环境中的摩擦力如0.999)等属性,还需要考虑地心引力gravity的影响。

用反质量invertMass模拟无限质量?

位置更新公式:$$ p’=p+dot p t + 1/2 ddot p t^2 $$ 其中,$dot p$表示速度,$ddot p$表示加速度。在30fps时,t=0.033 后一项可以忽略。简化为 $$ p’=p+dot p t$$

速度更新公式: $$ dot p’ = dot p d^t + ddot p t $$ d为阻尼,

以上模拟对于慢速物体没有问题,但对于子弹、炮弹这种高速物体则不适用,因为可能在一帧之内子弹已穿过物体,无法与目标发生碰撞。因此对于这种情况,我们则需要将子弹想象为一个激光(或抛物线)。对于目标所受到的冲击,则需要通过动量守恒、能量守恒公式进行计算(TODO)。

重力是恒定的,但还有很多其他的力是动态生成的,爆炸、发射、风。因此我们要创造一个『力生成器』在每一帧执行它的updateForce方法,来设定物体受到的外力。

弹簧是一种普遍的模型,那些柔软的材质都可以抽象为大量的弹簧。根据胡克定理$$f=-k Delta l$$,我们可以写一个弹簧力生成器。

除了弹簧系统外,还有一类硬约束是紧密连接的对象,比如铁链、四肢。他们的关键在于连接点的速度是一致的。

然后我们要将所有的东西整合到一起成为一个物理引擎,在每一帧updatePhysics()

我们要将物理引擎从点升级到体,刚体的碰撞盒与他的质点。刚体的旋转。

碰撞检测(TODO)

参考:

《Game Physics Engine Development》2nd Edition by Ian Millington