| 越's profile三无之徒PhotosBlogLists | Help |
|
三无之徒April 16 Dream Engine 2 的一些事(二)最近在忙着优化游戏,除了用到的第一代引擎本身的优化外,美术也在资源制作上开始优化,减面、合并材质、模型、减关键帧、合理使用粒子模块...这些规则即使在我看来也不容易把握好,可苦了这些很感性的美术了。同时策划也尽可能做些优化工作,比如增加场景布局结构的合理性等,游戏客户端和服务器端也在优化,总之全民皆兵。可以预见到今后 CL 游戏场景将会更复杂,所以我也在积极推进美术工具的使用,以提高他们的生产效率,比如 Light Map Editor,CL 是基于静态光照来表现游戏场景的,之前都是美术在 3dsMax 中手工去调节整个场景的顶点色,费时费力,上周美术试用引擎提供的 LME 之后,提出一些反馈意见,我们也在改进之中。
说到静态光照,不得不说 DE2 的光照方案,在开始阶段我并没有确定开发 DE2 的静态光照技术,直到上个月的 GDC09,我了解到,UE3 这次的改进主要在静态光照系统:增加了称之为 LightMass 的系统,可以实现静态的全局光照,这样可以节省大量设置场景灯光的时间,使用这套系统可以可以告别以往一个 Level 要上百个光源的历史了。CryTeck 也推出了 CE3,实际上是 CE2 的低配置版,但游戏开发本身的功能也增强了。无论怎样,从这两款引擎的变化来说,引擎开发商们更务实了,渲染技术的发展也不像以前那样激进了,甚至还有些倒退,也许是考虑到金融危机的影响,PC的硬件发展将会放缓,从这方面来说是也许个正确的选择。根据这些信息,DE2 的静态光照系统也基本定型了:支持全局和局部静态光照,支持 Normaled LightMap 和普通的 Light Map,支持 Vertex LightMap 和 Texture LightMap。实际上 DE3D 早已经实现了局部静态光照,流程也已经完善,所以在此基础上开发 DE2 的静态光照系统是相对容易的。首先我实现的是 Normaled Light map,在翻阅了 HL2 渲染技术文档之后动手试了一下,基本都实现了,值得注意的是 bump basis 是在 tangant space 定义的,生成 lightmap 时要在 tangant space 生成光照信息,另外还要注意和引擎定义坐标系、Matrix 的行列优先级、旋转手相性要一致。Diffuse 光照好了,接下来是 Specular,HL2 中的静态 Specular 是通过 Envorment Map 来实现的,这种方法比较麻烦,而且需要预生成额外的纹理,我仔细研究了一下 UE3 的静态 Specular 的方式,通过简单的 Normal 和 bump basis 的 Dot 计算出 Specular 的系数,即可得到效果不错的静态 Specular,其实本质上也不算是静态,因为计算是实时的。接下来是全局光照,我希望用 Radiosity 来实现,参考了一篇 GPU 实现 Radiosity 静态光照的文章,完成了基本框架,已经交给同事去细化。
最近 Aion 挺火,我玩了一下,对其中可以生成 Alpha 物体的静态阴影很感兴趣,遂想如何实现,首先想到用 GPU 生成 LightMap 阴影,因为可以通过 texkill(clip) 过滤掉指定 alpha 值的像素。也曾想过用现在的 CPU 方式,但问题是第一是借用物理引擎的射线检测实现的阴影,当场景复杂光源较多时生成时间很长,第二就是很难生成 Alpha 物体的阴影(比如树叶),即使做到,实现上比较复杂,而且不灵活(比如无法获取美术在 Material Editor 中设定的自定义 Alpha Ref Value)。前段时间在 MSN 上和一位朋友 http://ixnehc.spaces.live.com/ 聊起这个话题,他与我分享了他的实现方案,给我很大启发:这是一种类似于 Deferred Shader 的方式,将需要光照计算的 LightMap Sampler 记录在浮点纹理上,通过 DS 方式计算光照,得到最后的 LightMap 数据,Shaow 采用和 Shadow Map 类似的方式生成,但存在精度问题,但仔细想会发现,对于方向光源,可以采用类似于分段 ShadowMap 的方式提高精度,对于点光源或者聚光灯,一般范围不会非常大,在大多数情况下也能满足要求。周一和同事们讨论了这个技术方案,认为可行,并制定了详细的技术实现细节,目前正在开发中。这样 DE2 将实现以 GPU 为主导、CPU 辅助的静态光照生成技术,将进一步提高静态光照的生成效率。另外,我们还讨论了 UE3 LightMass 系统的一些静态光照的技术细节,例如 Emmisive Lighting 等,这些也将在 DE2 中实现。
资源管理,整个三月份主要是在做这部分功能,由于之前的设计方案考虑到资源查找的优化,引入了资源ID 的概念,但这个优化增加许多复杂性,从结构到实现,从底层到高层,同时还牵扯出多人编辑资源的 ID 同步问题,以及 AutoPatch 时的 ID 同步问题,为了解决这些问题,我们还需要开发辅助的模块和工具来完成整个功能,甚至差点搞出个 C/S 结构的分布式编辑器模式。但即使这样,我们还是把整体设计方案确定了下来,包括所有的技术细节。某天晚上加班,引擎的同事问我:我们的资源管理是不是太复杂了?这让我陷入了沉思:我的初衷是什么?为什么现在会这样复杂?这样带来的性能提升和开发复杂度以及后期维护的成本是否平衡?经过一个周末的思考之后,痛定思痛,我决定去掉这个包袱,虽然性能没有提升,但是系统变得简单明了(Kiss 原则 )。周一我和同事们又仔细分析,最后决定丢弃之前的设计,轻装上阵。只是没想到这个决定得到了大家的一致认可,不约而同的都松了一口气。
逻辑编辑器,前几天我们讨论 DE2 的对象管理,讨论到最后就讨论到逻辑编辑器上来,由于之前对于网游逻辑的 Deploy 的问题一直悬而未决,使得我一直都在怀疑 Logic Editor 的实用性,因为这将改变既有的游戏开发模式,这种改变需要一段时间来适应。会议开完我的思绪仍然停不下来,抓住公司的 Server Engine 的主程序继续讨论,从开发模式的改变到实现的技术细节,我们讨论的比较深入,甚至可以肯定第一个用这种方式开发的游戏一定比传统的方式要慢,但从长远来看,是改进了游戏开发模式,提高生产率。所以,基本上确定了技术方案以及新的游戏逻辑开发模式,尽管还是有几个不确定因素。
上周把 DE2 的开发计划提交给了 CEO,这是一个粗略的计划,除了 DE2 的开发,还包含对 DE3D 的维护以及 Support 游戏项目的工作。DE2 的开发是我主动提出来的,作为公司的 CTO,我始终认为技术是游戏研发公司的核心竞争力,没有这个基础,在开发上很难走的更远。网游也在不断发展,玩家的需求会越来越多,游戏的功能也越复杂,对技术的要求也越高,虽然一款游戏的成功是多方面决定的,但是至少在技术层面,如果可以做好足够的基础保证,甚至走在业界的前端,将是保证公司持续竞争力的重要因素。
虽然,这条路难走,障碍很多,但我依然会继续前行。 February 24 Dream Engine 2 的一些事(一)从今年初 DE2 开始开发到现在已二月有余,进度还算顺利,这次除了次世代的 3D 引擎之外,我们还开始了对象引擎和逻辑引擎的开发,同时对引擎的资源管理的设计也做了进一步的改进。实际上所谓的对象引擎就是基于 RTTI 的可扩展的对象系统,游戏可以根据引擎的 RTTI 规则来扩展自己的逻辑对象,无需重新编译引擎即可在引擎编辑器和游戏中使用游戏对象,同时这套机制也作为引擎核心对象的管理和反射机制。逻辑引擎实际上是一个可扩展的游戏逻辑框架结构,它基于对象引擎,在其内部存在一个逻辑驱动核心,这个核心主要的工作就是不停的更新当前的逻辑序列--更新每个逻辑序列的状态,每个逻辑序列由一系列的逻辑片段构成,逻辑片断通过某种机制关联在一起,形成完整的游戏逻辑流程,在每个逻辑片段内部都可以实现特定的逻辑,通过结合对象引擎的 RTTI 机制可以对游戏对象进行控制,这样就可以实现大部分的游戏对象间的交互。与此同时,通过提供可视化的逻辑编辑工具代替传统的手工编写游戏脚本逻辑,可以提高游戏开发效率,缩短迭代周期。实际上这种机制并不是什么革命性的技术,从本质上来说和传统的 脚本 + CPP = 游戏逻辑 的方式没有什么区别,只不过是提供了一个可扩展的框架结构,将所有用 DE2 开发的游戏的逻辑纳入其中来驱动。但是,目前还有些问题没有完全解决,比如:对于 Online Game 的 Server 和 Client 逻辑如何编辑和部署? 众所周知,网络游戏的逻辑分散在 S/C 两端,而且还不可避免的存在时序和验证问题,如果是单机游戏这种方式可以工作得很好,但是网络游戏的情况就比较复杂。而且这里还有两个细节的问题,一个是策划如何通过逻辑编辑器决定哪部分逻辑是运行在客户端,哪部分逻辑是服务器端?第二就是性能问题,RTTI 也好,逻辑引擎也好,天下没有免费的午餐,要做到可扩展,就要付出性能的代价,高度的抽象和游戏对象的运行时动态查找以及编辑势必带来性能开销,所以,在性能和扩展性上找到平衡点也是摆在我面前的一个难题。 3D引擎方面,DE2 重新设计的渲染架构在开发的过程中感觉到比 DE1 要好许多,因为它完全不需要关心渲染核心以外的数据结构,同时 SG 也实现了在只知道很少量的渲染信息的情i况下向渲染核心发送渲染请求的功能,这样 SG 和 Render Pipeline 就被隔离开来,实际上在系统中存在一个中间层,我们称之为 Render Primitive Manager, 它负责在 SG 和 Render Pipeline 之间沟通,也就是说这个 manager 同时知道两者,但它不需要太多细节就可完成渲染数据的构建工作。为了更好的适应今后的多核心平台,多线程渲染架构也是我一开始就考虑的功能。由于在开发之前做了充足的准备,以及在去年实现的多线程资源管理的基础之上,再加上新的 Render Pipeline 和 SG 的完全分离,我大概用了 2 天左右的时间就完成了开发及测试工作。为了做到和逻辑线程完全并行,渲染线程完全是 lock-free 模式,对渲染线程数据结构的操作完全是异步方式,同时提供方便的回调机制满足特定的渲染以及渲染结果查询需求。 材质系统是变化最大的系统之一,第一代引擎的材质系统完全被废弃,为了更好的扩展性,我们重新设计了 Shader 系统,这样做的前提是整个引擎的着色机制完全基于可编程管线,只保留 D3D 10 还保留的固定管线设置,在固定管线的数据结构实现上参考了 D3D10 的架构,这样将来在迁移到 D3D10 或者后续版本会更加容易。同时我们还设计了一套 Shader 编译机制,实现了在不同着色环境下的动态 Shader 生成,而且做到了和顶点生成结构无关,在这方面我们参考了 UE3 的材质系统和材质模板。目前已经开发完成了可视化的材质编辑器,基本上做到了 UE3 能实现的材质效果我们都可以实现。 December 31 我的2008“从今天的结果来看,引擎的材质系统和核心渲染流程的调整比我们预想的要快。” “嗯,因为我们经过了详细的设计和思考,想的比较全面,所以实现起来也就比较快” “对,其实二年多的引擎开发过程也积累了很多经验教训,为这次第二代引擎的开发打下基础,虽然之前走了不少弯路,但也并不白做。” 以上是我和引擎开发组的同事在2008年12月31日晚上10点钟的对话,今天我们加班,明后天还要加班,加班的目的是尽快完成Dream Engine 2的材质系统和渲染核心,为全面开展第二代引擎的开发铺平道路。正是公司的新的游戏项目促进了第二代引擎的开发,次世代游戏的标准对引擎提出了更高的要求,由于第一代引擎兼容固定管线和低配置硬件,如果继续在其上开发次世代引擎,结构上会变得很复杂,实现上也很复杂,实际上从十月份开始的次世代渲染技术的尝试过程中已经显现出这一点,同时实现针对更高硬件平台特性的功能,比如新的图形硬件架构、多核架构等,原有的引擎更加难以适应。其实在几个月前我就已经有开发下一代引擎的想法,只是没有想到会这样快。实际上Dream Engine 2将是一款游戏引擎,图形引擎只是其中一部分,它将包含网络、物理、脚本等网络游戏开发相关的内容,它还会集成更多的可视化编辑工具,为游戏开发提供便利,成为次世代网络游戏的集成开发环境。程序同事们对开发次世代引擎是热情高涨,美术和策划同事们也希望能使用更强大的引擎编辑器来制作游戏,公司希望能制作出顶级的游戏,我也希望再一次挑战自己的极限,这些是我们的希望和期盼,是2009年的最重要的工作之一,这次的开发时间会很长,还有许多的技术需要研究和探索,我非常荣幸能有机会开发这样一款引擎,我相信我们能再一次超越自己,走向更加精彩的2009年! August 27 青.花.瓷 素胚勾勒出青花笔锋浓转淡
瓶身描绘的牡丹一如你初妆
冉冉檀香透过窗心事我了然
宣纸上走笔至此搁一半
釉色渲染仕女图韵味被私藏
而你嫣然的一笑如含苞开放
你的美一缕飘散
去到我去不了的地方
月色被打捞起云开了结局 如传世的青花瓷自顾自美丽 你眼带笑意 临摹宋体落款时却惦记着你 你隐藏在窑烧里千年的秘密 极细腻犹如绣花针落地 帘外芭蕉惹骤雨门环惹铜绿 而我路过那江南小镇惹了你 在泼墨山水画里 你从墨色深处被隐去 炊烟袅袅升起隔江千万里 在瓶底书刻隶仿前朝的飘逸 就当我为遇见你伏笔 天青色等烟雨而我在等你 月色被打捞起云开了结局 如传世的青花瓷自顾自美丽你眼带笑意 炊烟袅袅升起隔江千万里 在瓶底书刻隶仿前朝的飘逸 就当我为遇见你伏笔 天青色等烟雨而我在等你 月色被打捞起云开了结局 如传世的青花瓷自顾自美丽你眼带笑意 July 08 生活 & 工作睡梦中被女儿的哭声惊醒,一阵安抚后,女儿睡去,抬头看已经快凌晨 5 点了,睡意竟全无。于是打开 blog,随便写点什么吧。
生活:
我有些时候选择性失明或者失聪,一方面不想让无谓的事情妨碍自己前进的脚步,另一方面其实也是无可奈何。其实这样没有什么不好,什么事情都较真才是和自己过不去,尤其是自己无法控制的事情。我选择引擎开发而非游戏开发也许就是在这种指导思想下的一个反映吧。回首引擎开发 2 年中,真是什么滋味都尝过了,从怀疑、质疑到信任、赞许这个过程我是历历在目、百感交集。不过,我认为这是非常正常的,人们在接受一个新事物(人)的时候都要有个心理路程,每个人都是如此,尤其在自己已经有了思维定势之后更是如此。前几天跟 CEO 吃饭时我对他说:我不在意职位,我在意我做的事情。其实职位只是个 Position,重要的是能否在所做的事情过程当中提升自己,超越自己。CTO 也好,程序员也罢,本质上都是要写程序的,都要以程序的思维去思考工作中的问题,在这一点上两者没有任何差别。一直到现在,我仍以程序员的标准来要求自己,而且我的情绪依然会受到程序的影响,不过另一方面作为管理者的角色,自我控制力也比以前强了许多,但是内心中的波澜还会被程序所控制,这一点我自己非常清楚。其实我多少有些抵触管理上的工作,琐碎、繁杂,而且难于控制,这一点我在7年前第一次做项目经理的时候就体会到了,但是也有好处,它会迫使你从纷繁复杂而又非常理性的程序中跳出来去解决一个完全不同领域的问题,看似无关其实也有些内在联系,这使得我在程序上很少走死路,尽可能尝试其他方法,在面对新知识的框架体系时不会慌乱不知所措,而是跳出来从整体的高度来审视自己面对的问题,这种时候往往能得到意外的收获。其实,最近一年最重要的是我的女儿,无论我面对多么头痛的问题,每当我回到家里坐在椅子上愁眉苦脸的思考时,女儿往往会站在书房的门口,拿着她心爱的“宝贝”朝我微笑,那天使般的笑容完全化解了我心中所有的烦恼和忧愁,我觉得那是世上最美好的事物,而那些所谓的问题也经常在女儿的笑容背后被我一一干掉了。也许同事们很奇怪我经常在早晨上班时兴奋的给大家讲开发上的新想法,其实他们不知道我有这样一个秘密武器。:)
工作:
拥有次世代渲染效果的引擎就是次世代引擎吗?回答当然是否定的。6月份我调整了 3D 引擎的开发计划,决定实现一些所谓的次世代渲染效果,从完成情况上看基本符合我的预期,另一方面也是让引擎组的开发人员认识到这样一个道理:写 shader 容易,整合难。事实确实如此,从调研实现方案到在引擎中实现出来2个研发小组总计花去了不到3周的时间,而整合这些渲染特效到引擎中并提供良好的使用接口则直到现在也没有完全结束,更别提优化了。一个不了解 3D 引擎开发的程序员往往会很羡慕引擎开发的工作,他以为做引擎开发天天接触的都是图形、shader、华丽的渲染特效,但事实上并不是这样。不妨举个例子,一个去年进入引擎开发的新人,在引擎开发的一年多的时间里参与了如下的开发工作:字体绘制、文件系统、序列化系统、粒子系统及编辑器、特效系统及编辑器、纹理管理、异步资源管理,在这个过程中他学到了 win32 编程、GUI 框架(wxWidget)、windows File System Management、粒子系统逻辑、特效逻辑、多线程、纹理格式解析等等。可以看出这些知识覆盖面比较广,每一个部分精通都不容易,都需要时间和经验,而这些其实就是引擎的本质,是引擎的基础,没有这些就不能称之为引擎,没有这些引擎也无法工作。在这背后他所学到的更多的是对软件开发的理解,这包括:如何设计人性化的编辑器UI?如何提供良好的使用接口?如何保证开发过程中系统结构的可扩展性?如何解决原有系统和新功能之间的冲突?如何用最简便的方式来实现功能?如何解决 bug?如何修改一个 bug 而不会因此产生新的 bug?如何多人协作开?如何与其他成员沟通交流?如何最大化的表达自己的想法而尽可能的减少信息丢失?这些是软件开发本身的东西,无论开发哪种领域的软件都要面临这些问题,但是这些确实非常重要的,会写 shader,会点图形学知识是远远不够的,3D 引擎是众多开发技术的混合体,这是个庞大的体系结构,图形渲染是上层结构,是最后的数据呈现,而驱动这些数据的却是那些底层的基础功能,没有这些基础功能的保驾护航,单单一个渲染 API 是没有任何意义的。
在开发中另一个头痛的问题是如何选择的问题,很多时候已经找到了解决之道,但存在着多种解决方案,如何选择就成为了一个难点,因为开发者都希望做出最优的决定,但系统在没有实现和被应用之前是很难判断出选择的对错。这时需要的就是经验的判断和对未来的假设,如果缺少了这一步所作的决定是比较危险的,当然,可以通过后期的重构来不断调整,但是重构并不是推翻重来,重构是基于原有系统的局部修改,使原有系统尽可能的适应新的变化需求。这几乎已经是一个固定的要求了。而且当系统本身被大量的使用的情况下,即使推翻重来也是需要决策的勇气的。我经常被困扰的就是选择的难题,现在我已经形成了习惯,在头脑中自己和自己辩论,看哪边更有说服力,最后做出一个决定。其实我更希望和别人去讨论,因为自己的思维也是有局限性的,不同的思考方式往往使自己辛辛苦苦建立起的思维体系有所变化,也许是更加完善,也许是完全推翻。即使自己被推翻也没关系,重要的是最后会得出一个结论,而这个结论在大多数情况下会更加接近真实。 |
|||
|
|