egret3d开源项目初探

背景知识:

        以前写过格斗猎人的2D战斗逻辑引擎,算是极其简单的2D逻辑了,真实逻辑大概也就几百上千行。

        而这个3D引擎目前才开发到1.3版本,很多功能还没有实现,就有2、3w行代码了。3D引擎复杂程度果然是最难等级的,更别提后续可能的各种图形学新技术新优化,都加上以后感觉这个项目奔着10w行js代码去了。

        看了一段时间,结合之前对于渲染的简单了解,有点心得,记录一下。未来的道路还很漫长,继续加油。

egret3d引擎周边:

        egret3d引擎可以理解为两个大的部分,一部分是浏览器提供的webgl api调用opengl的渲染部分;另外一部分则是这个开源库所实现的3d引擎逻辑功能部分,这部分egret引擎组将其设计为两块,分别包装在egret3d和paper两个命名空间中。

        【egret3d 命名空间用于处理三维游戏相关内容,包含模型、纹理、材质、灯光、碰撞等常用功能。

        paper 命名空间用于实现与具体游戏引擎(无论是2D 或 3D)无关的组件实体系统框架,用于维护对象的生命周期以及开发模型。】

        宏观来看设计非常清晰,和整个现有的egret框架是一个逐渐融合的关系。非常支持这种商业化技术理念,既独立开来以保障快速开发,又在宏观层面和现有系统建立联系。接下去就是项目组的一个快速迭代的实践过程。

        egret采用了Typescript语言作为主语言。ts是微软所写,看着就像是C#进化版,呵呵。关于ts语言的设计初衷,我非常理解,动态脚本语言(js)设计大型项目的缺点很多,必须要用好的外围工具来约束它,统筹规划它。这样才能在不断地开发维护中保证项目的可控性、可维护性。比如我们公司全lua的unity3d项目,我就明确要求了一点,当你使用lua的目的不再只是修bug,热更新,而是作为整个项目的主要语言时,它的灵活可能就是缺点,需要用明确的规则/工具管控起来。

egret3d引擎初探:

入口和运行时:

        index.html中调用egret3d.runEgret,进入RunEgret.ts模块的runEgret方法。引擎启动了。

        在整个运行时,主要是ECS:

        Entity 实体:BaseObject,GameObject、Asset、Scene、BaseComponent等

        Component 组件:BaseComponent,一个组件实现一方面的功能,包含数据

        System 系统:BaseSystem,一个生命周期系统处理该生命周期的所有脚本和组件的数据,其他功能系统类

        此ECS非Unity2018中提到的能大幅优化并发性能、增加Cache命中的ECS(反正js都是单线程 h5开发必看)。但是概念上比较接近。通过各个单例管理类维护状态数据,各个组件“组成”功能,各个系统进行各方面功能的调度。完成了3d引擎的几乎所有功能部分。

egret3d项目结构分析:

图片看不了的点击链接:egret3d文件夹结构

egret3d文件夹结构

        asset:资源定义,如Mesh、Material、Texture、Shader、GLTF。

        components:各个实际的功能,animation、audio、camera、collision、Egret2DRenderer、light、MeshFilter、MeshRenderer、particles、singletons、SkinnedMeshRenderer、Transform。

        esc:如上述分析。

        editor:编辑器功能,和以前看过U3d实现编辑器的设计类似,实现undo、redo、serialize、deserialize这几个主要接口。

        math:实现了3D引擎的各种数学库,以后碰到类似的疑惑可以回来参考。

PS:

        GameObject的全局单例组件管理值得借鉴,采取的单例基类的应用方式下次自己试试。

        常见的处理流程:单例组件类Component先收集待处理实体,最后再由对应的System统一处理。

egret3d引擎的脚本组件及生命周期顺序如下:

​ * 脚本组件。

​ * 生命周期的顺序。

​ * - onAwake(); //组件被初始化时调用。在整个生命周期中只执行一次。

​ * - onReset();

​ * - onEnable(); //组件被激活或实体被激活时调用。

​ * - onStart(); //组件开始运行时调用。在整个生命周期中只执行一次。

​ * - onFixedUpdate();

​ * - onUpdate(); //程序每帧调用。

​ * - onLateUpdate(); //程序每帧调用。

​ * - onDisable(); //组件被禁用或实体被禁用时调用。

​ * - onDestroy();

个别名词解释:

WebGL:通过浏览器提供的接口,直接和底层的OpenGL库打交道。

GLTF:3D图形界的JPEG,2015年10月发布,面向实时渲染应用的,尽量提供可以直接传输给图形API的数据形式,不再需要二次转换。

WebAssembly:是一种新的适合于编译到Web的,可移植的,大小和加载时间高效的格式,是一种新的字节码格式。可用它将大型的C和C++代码库比如游戏、物理引擎甚至是桌面应用程序导入Web平台。windows 2000通过WebAssembly编译

展望与总结:

        多嘴一句,egret引擎组主体全是基于Typescript语言开发,c层面的东西很少,这样的隐患就是完全把性能交给了js语言。万幸最近这些年webgl、gltf、webassembly等等提高性能的技术不断出现。个人认为接下去egret的性能命脉就彻底交到了webassembly手中,这个技术到底能发展成啥样,工业化到什么程度呢,拭目以待。egret、cocos、laya到底谁会胜出?还是以后可能入场的底蕴深厚的腾讯、网易呢?我不知道答案啊,但是有鹅选鹅,有猪选猪,总不会错。

        对3d引擎的构成有了个简单的了解,对以前计算机图形学课程的理解又深刻了不少,呵呵,以后继续参考其他开源3d引擎的实现。多理解其他大牛已有的实践工作,尽快应用于实际项目中。多看多学多练。另外对于初学者,强烈推荐《Unity Shader入门精要》。

随想(胡言乱语,可略):

        如果是我来主导h5的3d引擎开发,我会怎么快速开发出这几万行代码呢?

        0、支持webgl的浏览器以便实测,熟悉webgl的api接口,阅读理解《游戏引擎架构》、《Unity Shader入门精要》,参考市面上成熟的开源3d引擎项目。

        1、尽快写出最初版的3d最小原型,自测通过。最小原型实现以下功能:基本数学库、网格、材质、贴图、默认Shader。读取3d数据,调用webgl,可在浏览器上展示3d效果。

        2、在最小原型的基础上开始确定架构图,各个模块之间的关联。

        3、并行开发完善各个模块,各自自测,引入测试,测试所用的3D数据可以先通过其他工具生成。

        4、最后处理各种额外功能、3D编辑器、性能优化等。