借题发挥一下吧。
最近浅墨的离去,对游戏圈,尤其是游戏引擎圈,是一个巨大的损失,但人死不能复生,除了唏嘘惋惜之外,我想说:“希望各位年青一代的程序员继承浅墨的志向,勇敢的向游戏引擎的技术高峰发起挑战。”
上世纪末,有幸偶然学会五笔打字和GBASIC,在中学时期就对编程产生了浓厚兴趣,二十年前在大学读到《DOOM启示录》,我就把卡马克当作偶像,一头扎进《WINDOWS程序设计》和DirectDraw中,并立志于开发游戏引擎。
在那个为理想做游戏的时代,咱们跟本就不知道做游戏还能赚钱,纯粹就是狂爱,因为行业也刚刚起步,相知的人甚少,也只能独自摸索着前进,当时找了份网站开发的工作,为了结交志同道合的人,从“金点时空”的论坛到GameRes论坛,天天泡在里面,甚至为此自已做游戏编程网站,聚集了一批开发者,为了人气还举办了几期游戏编程比赛,自已出钱为开发者做证书并发奖金。为了学3D编程,自学VC++,D3D,OPENGL,图形学的资料,啃DXSDK里面的Samples,看NeHe的OpenGL教程,琢磨矩阵和线代。
在那个时期,一切都需要靠自学,最开心的事,莫过于苦思冥想几天后,搞定了一个图形算法,或者是模型动画,或者是地表混合,或者是光照处理。为此,我辞去当时已经做到薪水不错的工作,在郑州郊区的民房里租了个地儿自学,我给自已定下近乎严苛的自学课程表,从早到晚,上午8点到12点VC++和WIN程设,MFC的学习和练习,下午2点到晚上进行DX,OPENGL的学习和写游戏DEMO,还记得郑州阴冷的冬天,裹着厚棉衣,坐在电脑前,手发着抖敲代码的那段“快乐”时光,就那样坚持了近一年 。当然,回报也是巨大的。04年尝试写了一个3D的《红孩儿3D俄罗斯方块》(百度可以找到),参加当时数码天晴的中国游戏开发者大赛《天晴杯》并获了个入围奖。哈,上面可真是有不少后来的大牛人。
那时候行业刚刚走向商业化市场化,一下诞生了大量岗位需求,薪水在当时也算很好。突然发现爱好能赚到钱,就更加热爱和努力。
再后来随着游戏行业发展,到北京工作,除了日常工作外,每天习惯性早晨5点半起,写2小时再去上班,晚上回来做研究,熬夜到1点左右睡,也整整坚持了将近十年。即便是现在,每天也仍然习惯性的早上6点多叫醒孩子后,坐在电脑前继续写到8点出发,晚上回来写到12点。
做引擎,除了努力和热情,也还需要天赋。
在最开始阶段,C++是来说必须要熟练掌握的,因为中国游戏行业一路发展过来,太多的技术精粹是基于C++了,如果你不能对C++有一个很熟练的掌握,基本上你不可能真正深入到图形引擎底层。
然后,最好是你能学一下工具开发的知识,比如MFC或QT,现在说MFC是有点过时了,但很多工具化的东西,还是需要的,就比如我前几天发的一篇文章,基于Spine动画的AVATAR换装系统优化, 为了研究和验证一些东西,你必须要能通过工具化的方式来进行。而且在图形引擎这条路上,常规的编辑器开发也是必要的技能,比如我们常说的三大编辑器,用于看模型动画和表现的模型观察器,用于编辑特效和技能的技能编辑器,用于编辑场景的场景编辑器,是引擎不可或缺的组成部分,还有其它大大小小的工具软件,如界面编辑器,材质编辑器等等。
那然后就是高数中的线代部分了,这块结合图形学来看,网上有专门讲解游戏开发中的图形学和数学物理的书,少不了要花点精力来啃的,因为没有这个基础,你无法理解3D的矩阵,四元数和一些计算公式。但要说学到多深才够用,我感觉这个方面如果你只是想做个能跑起来的引擎,在不涉及到真实感之前还是实用为主,基础部分熟练,后面用到再参阅吧。
好,现在算是有个基础了。开始学DX或OPENGL,现在来说随着移动互联网兴起,DX的市场已经大不如前,所以只学OPENGL即可,自然包括WEBGL和OPENGL ES作为练习。
一般来说,最先还是画画点,线,面。在我看来,一生二,二生三,三生万物,点,线,面虽简单,但是基础中的基础,是复杂模型的本质。通过点、线、面尝试结合结点系统做个小框架,能update,能render,跑出一些基于时间帧的动画,进而理解精灵,层,场景的关系。
然后是纹理和材质的学习,掌握多纹理和ALPHA混合,比如法线、高光贴图+遮罩贴图的材质效果,基于这些做粒子特效,开始写一些简单的Shader.这里面还包括各类图片文件格式的研究,了解像素的压缩和显存占用评估,能够自由的写一些帧动画格式,并通过工具对各类图片的像素处理做手脚。比如写一个工具把目录下所有图片中的透明空白区做裁剪后重新保存。以及尝试着写一个粒子编辑器调整各个参数导出。
三角面有了纹理,也就可以来做一些复杂的模型表现了,之后就是研究模型动画,包括顶点动画和骨骼动画,动作混合和融合,多人同屏,骨骼动画的LOD,合批优化,那这一块就要深入研究一下常见的模型文件格式,能读取并显示。同时要自已去尝试着为3dsmax导出插件写模型动画导出文件格式,并读取渲染起来。
如果你能完成自已写3dsmax导出插件并渲染骨骼动画模型,你对3D模型数据的看法就不再流于表面了,这时候格式和模型数据的外在形式已经不太重要了,你可以开始写一个自已的模型观察器,查看子模型,材质,换装,绑定武器装备,动画效果,碰撞盒,动作混合和融合效果,关键帧编辑,这部分就花了我三年时间才弄明白。
好,模型这一关过了,现在开始做场景,学写大地表,地表需要了解的知识也比较多,网格区域优化、多纹理混合、模型摆放、区域镂空、高度图,阴影烘焙,因为大地表这块涉及到的顶点和三角面规模巨大,所以优化会成问题,即包括面数优化,也包括像素填充率优化,这部分是有一定难度的,需要了解顶点格式数据压缩,LOD,像素深度剔除,AO,ShadowMap和烘焙,还有导航网格生成,寻路算法,水体渲染,草体渲染,太阳光晕和辉光,天气系统,静物批次优化等等。这些技术需要通过开发场景编辑器来最终完成all in one的编辑工作。
好吧,这一块也花了我三年研究,而且幸好遇到了一些技术大咖指导得以反复推翻重来。
嗯,基本到这里,算是对引擎涉及到的很多知识有了较深入的了解了。再后面就是所谓的次世代效果了,也就是各种基于物理的材质表现了,锦上添花。
但实际上,走到这一步,才算是对引擎有了理论层面较深入的理解,具备个基本功罢了。因为上面的东西,在现在这个时间点,已经落伍了,现在拼的不是这些,而是更加真实的画面。
真正要像做一个有好的画面表现的引擎,还有大量的文献要读,覆盖所有要表现的物体的细节,这时候英语和大量的数学物理知识匮乏会让你寸步难行。学历的底子显得是如此重要。
在这一步,我停下了。
再仰望一下毛星云读过的文献列表和识知图谱。
我深知,走到如此地步之付出,太需要坚持下去的勇气和自律,以及对于图形引擎深刻的爱该有那份无敌的纯粹!
在这个过程中,也有极大的收获,收获了职务,收获了粉丝,收获了认可,最大的收获就是一份自信心,站在引擎的高峰,自信可以从零开始达到梦想,自信可以从弱到强帮助他人,自信可以不惧困难挑战世界,自信到爆炸 。但太自信的问题就是诱惑和现实面前,能持续不为所动太难啦。
不客气的说,从那个自研引擎风起云涌的时代,咱们是和做自主芯片一样的感觉,憋着一口气要把国产引擎做好,但是走着走着,人越来越少。
我们梦想如飞翔鸟一样的在天空和太阳之间穿行,但结局,终归还是逐渐没落沉入地下了。
背弃了理想,
谁人都可以,
哪会怕有一天只你共我!
毛星云,放心走吧,我们一定会努力达到你眼中的世界。
最后,再次欢迎加入到游戏引擎开发的世界里来~
追更一下:自己尝试去写一个完整的引擎吧!
首先,理解基本的图形渲染管线,从基本的图形点线面开始做起,涉及到顶点xyzw与xyz的区别理解,法线,顶点色,纹理坐标,投影变换与反变换,射线拾取处理。
实践:尝试写一个简单的图形渲染器,支持不同顶点信息拆分与组合的shader管理和表现。
【Cocos2d-x2.0 -- 从点,线,面学起_火云洞红孩儿的博客-CSDN博客_cocos2d-2.0】https://blog.csdn.net/honghaier/article/details/7973078
2)学习GUI系统设计,通过自己的结构设计写一套完整的UI界面架构。
【礼物:《红孩儿引擎内功心法修练与Cocos2d-x》之结点系统(场景,层,精灵)_火云洞红孩儿的博客-CSDN博客】https://blog.csdn.net/honghaier/article/details/8760124
(看完这篇,基本对于简单的节点系统设计就算理解了,可以自己开始动手写传统的引擎架子了)。
在这个领域,也有大量的知识点,比如文字的渲染,涉及到对于字图的理解,
实践:可以自己写一套字体生产工具,并实现一下字图的效果处理,比如边缘线,各种彩虹色彩变幻。然后尝试以工具化的方式提供编辑器。
实践:手动基于一个基本控件派生出无数个复合控件,实现常用的GUI控件体系。并通过开发工具进行拖拽设计和界面代码生成。
这里有一个知识点,就是纹理批次的优化,因为界面里细碎的东西太多,还涉及图文混排,如何以最好的效率渲染,是个可以深究的问题。
首先要理解图片的格式(png,jpg,pvr,tga,dds等格式及其压缩格式),涉及对于1.加载解压速度2.内存显存占用,3.纹理填充率4.纹理通道的字节长度使用效率等方面的知识。
【Cocos2dx纹理优化的一些方案 - 走看看】http://t.zoukankan.com/lancidie-p-3019658.html
实践:写一个图片格式转换器,带图片拼合和空白切除,支持90度旋转,可导出自定义的信息文件。
(学完这些,基本上,多纹理的理解就不再是图片,只是一层信息而已)
3)然后是到静态模型结构设计与渲染,主流建模工具导出插件与文件导出与加载。
【3ds max 导出插件开发后记_火云洞红孩儿的博客-CSDN博客】https://blog.csdn.net/honghaier/article/details/4729112
写导出插件的意义是更加深层次的理解模型体信息构成,同时通过对于主流建模软件的学习,理解各种信息转换(坐标系)和拆解(复合材质拆分)等。
这部分要学会封装模型和子模型,这里涉及材质解析与shader表现,骨骼动画的计算与渲染(动作列表,上下半身的动作混合,多动作的融合,骨骼移动,乳摇,遮罩贴图对局部皮肤的换色),再到自己设计模型观察器去方便的观察。
ps.也不能只研究3D,其实2D骨骼动画也应该熟练掌握。
特别是spine的优化。
4)好,现在模型基本能力有了,开始写点场景吧。
来来来,地形编辑器!
2D部分:涉及横屏,纵屏,斜视角多种的场景网格结构设计。
实践:写一个编辑器去生产不同的地形并导出到tmx格式,让tiledmap也能兼容。
另外,场景图的素材组织管理要考虑效率,做优化!
3D部分:3D地表也是网格,但是信息维度就复杂的多了,还涉及1.地表的纹理混合材质表现,2.地图分块与组合,LOD。
实践:自己写个读高度图的地标网格,实现多种地表纹理混合。
其实LOD的优化也分很多种方式,老书上的计算型网格拆分组合算法,个人觉得过时了。
实际上,我2012年设计这块时,一次性把顶点缓冲创建好,然后对索引缓冲根据距离直接取LOD的地型分层索引缓冲,而不进行顶点LOD计算。顶点LOD因为不需要uv坐标,xyz和法线也可以使用byte进行压缩,很小的!
然后是场景模型,包括树木和建筑,这里面主要研究批次优化和加载优化。
批次优化要考虑大场景内的多类型模型渲染需求,比如无alpha,有单通道ahpha镂空,有alphablend的,还涉及到植被的alpha排序错误处理,摇动处理。
如果要想渲染堆在一起有交叉的alphablend。需要利用z开关进行二次渲染,涉及到多pass,第一遍写深度不写颜色,第二遍不写深度写颜色。
多模型的场景加载,涉及到模型体的打包优化,多线程加载。如何秒进场景。
5)模型和场景搞的差不多了,可以开始做一下场景特效。
自己手动写一下粒子系统,实现喷射器和影响器。
然后是面片,模型,粒子,条带的组合。
实践:写一个特效编辑器组合出一些简单的效果。
不要分2D,3D,统统都写就好了。
6)进行到这一步,再说下shader效果上的事。
首先,2D部分,把ps效果滤镜都shader一遍。
【Shader开发从入门到精通-卞安-专题视频课程_火云洞红孩儿的博客-CSDN博客】https://blog.csdn.net/honghaier/article/details/83551343
然后,3D部分,先是写一下法线贴图,然后是实现雾效(理解顶点雾和像素雾,然后写一下算法实现高度雾和区域雾)和光照(太阳光,点光,聚光灯)。
做完就是后处理了,先把rendertarger的纹理搞定,然后算是开了一扇门,基于rendertarger,做镜子效果,做水面,做shadowmap,景深,Bloom,HDR和一大堆后处理效果。
水面涉及凹凸,菲涅尔。
shadowmap涉及级联影子的平滑与模糊。
7)有了模型,有了场景,有了光影,有了特效,然后是真实感强化,AO,全局光照,BPR这些,进一步提升真实感。这时候你会发现,一切才刚刚开始~
刚刚开始~
PS:打算基于Python重零起建立一个新的图形引擎,主要面向图形学初学者和并做一些教学,感兴趣的同学可以加Q群:275220292。