作者:姜雪伟,创业公司技术合伙人,畅销书作者。CSDN社区专家,资深3D游戏引擎开发者,IT高级讲师,计算机图形学方向研究生。
本文为姜雪伟原创文章,未经允许不得转载, 点此查看作者有关《【系列直播】算法与游戏实战技术》经验分享
前言
作为一个在IT行业工作十五年的老兵,笔者在这里将自己多年的学习游戏算法经验分享给读者,希望能够帮助那些想学习算法提升自己的读者。算法是IT产品研发的核心,在IT的任何领域都离不开算法,目前比较流行的IT领域有:大数据,人工智能,深度学习,游戏开发,虚拟现实,增强现实等,这些领域的核心都是算法,可见算法在IT领域的重要性。本文主要聚焦游戏算法,游戏开发不外乎3D引擎接口调用和游戏逻辑编写,3D游戏引擎的主要功能是渲染,渲染使用的是图形学算法针对GPU编程的。客户端逻辑的编写也会用到一些算法,比如抛物线算法,曲线插值算法,A*寻路算法等等。算法的优势主要体现在游戏核心功能和效率优化上面,作为IT程序员来说,如果对算法不精通,或者不知道如何在程序中使用算法,随着时间的推移会逐步被行业淘汰。当然大家也不必为此担心,笔者在此总结了学习算法必经之路的三个主要阶段。
第一阶段 基础篇
对于初始学习算法的读者,首先要把基础算法学好,也就是把大厦的地基要打牢,毛泽东说过“理论联系实际”,学习算法先要把理论知识学好,给读者推荐的学习资料是大学的经典课程《数据结构与算法》,涉及到的主要知识点有:快速排序,二叉树排序,二分查找,哈希表,二叉树等。掌握这些数据结构并能运用它们解决实际问题,千万不要死记硬背,亲自动手将算法书写一遍,编程的过程就是要反复的练习。另外,还要学习一些关于矩阵、向量运算的知识点,这些知识点也是游戏开发必备的。给读者推荐的资料是大学课程《线性代数》。掌握这些知识的方法就是读者都要动手将它们逐行代码敲一遍并且用脑子反复琢磨领会贯通。
以二叉树为例,介绍其在游戏开发中使用的案例,二叉树在图论中是这样定义的:二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。它在游戏中应用案例给读者介绍一下,在游戏开发中经常使用图集,就是把多张小图片合成一张大的图片一次性加载到内存中,优化了内存加载效率,生成图集的算法就是用二叉树算法实现的,算法流程就是首先生成一块内存用于存储大图片,然后新建一个空的二叉树,把小图片看作是二叉树的子节点,依次去挂载到二叉树的叶子节点上,挂接的顺序采用的是先序遍历的思想,这样一张图集就生成了。如果本阶段的知识点读者已经掌握了可以直接略过,接下来进入第二阶段进阶篇。
第二阶段 进阶篇
在进阶篇阶段是学习一些相对基础篇比较复杂的算法,进阶篇的算法主要包括:A*算法,八叉树算法,Perlin噪音等,笔者建议学习的资料是关于游戏编程方面的书籍《游戏编程大师技巧》(上下册)这两本书非常经典,虽然其接口有些旧,但里面的编程理论非常适用游戏开发,笔者利用它的编程思想编写了一本适合初学者学习的《手把手教你架构3D游戏引擎》一书。
下面以八叉树算法为例给读者介绍其应用,八叉树(octree)是三维空间划分的数据结构之一,它用于加速空间查询, Octree的实现原理主要分为六步:
- 第一步、设定最大递归深度;
- 第二步、找出场景的最大尺寸,并以此尺寸建立第一个立方体;
- 第三步、依序将单位元素丢入能被包含且没有子节点的立方体
- 第四步、若没有达到最大递归深度,就进行细分八等份,再将该立方体所装的单位元元素全部分担给八个子立方体;
- 第五步、若发现子立方体所分配到的单位元元素数量不为零且跟父立方体是一样的,则该子立方体停止细分,因为跟据空间分割理论,细分的空间所得到的分配必定较少,若是一样数目,则再怎么切数目还是一样,会造成无穷切割的情形;
- 第六步、重复3步骤,直到达到最大递归深度;
给读者举个游戏案例,假设:我们有一个大的房间,房间里某个角落站了一只小动物,我们想很快的把小动物找出来,该如何做?我们可以把房间当成一个立方体,先切成八个小立方体,?然后排除掉没有放任何东西的小立方体,再把有可能藏小动物的小立方体继续切八?等份….如此下去,平均在Log8(房间内的所有物品数)的时间内就可找到小动物。?因此,八叉树就是用在3D空间中的场景管理,可以很快地知道物体在3D场景中的位置,或侦测与其它物体是否有碰撞以及是否在可视范围内。进而八叉树的应用场景可以推广到解决如下技术问题:
- 一、用其加速用于可见性判断的视锥裁剪;
- 二、加速射线投射,如用作视线判断或枪击判定;
- 三、邻近查询,如查询玩家角色某半径范围内的敌方NPC;
- 四、碰撞检测的粗略阶段,找出潜在可能碰撞的物体对;
实现的八叉树效果图展示如下所示:
第三阶段 提高篇
掌握了第二阶段的学习后,接下来到了真正的提高篇,也就是“武林秘籍”的最高境界。提高篇主要是学习图形学算法编程,推荐给读者学习的书籍是:
《Mathematics for 3D Game Programming and Computer Graphics》和《Real-Time
Rendering》这两本书相对来说比较难。但是写的非常好,有助于提升技术水平。市面上比较知名的引擎都使用了GPU编程技术,这些技术算法主要包含:PSSM算法、SSAO算法、Bloom算法、Blur算法、HDR算法、Deferred算法等,它们也是引擎的核心算法。
点此查看作者有关《【系列直播】算法与游戏实战技术》经验分享
以PSSM算法为例,给读者分享一下应用案例,如何在游戏中使用,首先要了解其原理:PSSM全称 Parallel-Split Shadow Map
PSSM算法的核心就是把视椎体进行分割,然后分别渲染组合。语言讲解不如看图直观,先通过视锥体分割说起。效果如下图所示:
视锥体分割效果图
PSSM实时阴影的绘制首先需要灯光,在现实生活中,白天只有太阳出来了才可以看到影子。在虚拟世界中也是一样的,场景使用的是Directional(平行光)相当于现实世界的太阳光。上图左边部分显示的是视景体的投影,利用PSSM算法将其平行的分割成多个部分,然后对每个部分进行渲染,分割成的块数是可以自己设置的。右半部分是顶视角观看的分割效果,把物体分成三块进行实时阴影的渲染。渲染的计算是GPU中执行的,在GPU中执行的流程如下图所示:
渲染分解效果图
上图的处理流程首先是场景中的灯光照射到需要投影的物体上,接下来程序对投影的物体顶点进行矩阵变换将其转换到投影空间中,再转换到裁剪空间进行视口的平行分割,最后将其分别渲染出来。原理清楚了代码编写就很简单了,具体代码读者可以查看《手把手教你架构3D游戏引擎》一书,下面给读者展示效果图如下所示:
下面笔者分享一下学习算法的感受,刚踏入IT行业时也不会算法编程,对算法有一种恐惧感,总感觉算法很神秘,更不知道如何使用,自己为此也苦恼过。刚入职公司的时候跟大多数程序员一样写写逻辑,两年后,自己感觉水平也比较牛了。为此,自己申请加入到公司核心部门引擎部,初衷就是看看引擎组都做些什么事情,当然也是想学习一些知识为了跳槽涨工资。
加入引擎组后,经历了一件事情彻底改变了我,更让我认识到算法的重要性。事情是这样的,端游中实现的刀光拖尾算法,功能包括:取样插值并且实现材质的扭曲效果,当时接到任务一下子就懵了,在网上不停的翻资料,那时网上没有这方面的技术实现,最后只能硬着头皮自己动手写了,经过一周的折腾,选择了B样条曲线插值算法,再经过一周将其实现了出来,最后一周的时间,度日如年,晚上基本上都没睡好,做梦都想着如何实现算法。有时自己都想离职走人了,感觉压力太大了,但是最终还是实现出来了。经历过这段刻骨宁心的经历,让我明白了算法是如何与游戏开发相结合的,也让我明白了自己算法知识的薄弱,需要从头开始把算法学好,最终我也是按照上面这三个阶段学习的。在学习算法的过程中痛并快乐着,学习算法首先要明白其原理,然后再用代码敲一遍实现出来,切记眼高手低。
后来笔者独立写过几款3D引擎包括:3D渲染引擎,海水渲染引擎,物理引擎等。现将实现的效果给读者展示如下:
海水渲染反射折射效果
实时航行轨迹模果
最后给读者一个建议:学习算法关键是我们要有一个正确的学习方法再结合着实战项目就可以快速的提升自己的技战水平。算法的学习不是一朝一夕的,只要找对学习方法,分阶段学习,持之以恒,相信随着经验的积累将来在IT“武林“真的可以独步天下,以此文与读者共勉。
点此查看作者有关《【系列直播】算法与游戏实战技术》经验分享