转篇Napoleon314 大牛的分析,排版好乱,见谅,耐心读,这是个好东西,注意看他自己的实现,是个技术狂人啊,Ogre焕发次时代的光芒啊~~~努力
-----------------------------------------------------------------------
转载自: ?tid=2870&extra=page%3D1&page=1
-----------------------------------------------------------------------
这个帖可能在这儿发比较奇怪,不过我是一个信仰黑客精神的程序员,也非常支持KlayGE的研发,希望发一些我的原创资料,和作者,以及KlayGE的作用者交流,甚至有一些麻烦的问题,也希望作者可以解答,如果KlayGE的研发能够涉及到这些东西,那就最好了。
作为一个刚从业不久的引擎开发人员,为了能快速有效地提高自己引擎的渲染质量,使用了各种办法来解析Cryengine的渲染手法。在此我将以专业的视角来与您分享我的经验和成果。如果您也是专业的图形程序员,希望与您一起讨论,解读这款令人惊叹的引擎,如果您是一个刚刚入门的新人或者爱好者,这将成为您不可多得的原创中文资料。
Cryengine是目前最难窥探的引擎没有之一,比起在中国泛滥的虚幻和GB的源代码,Cryengine也显得神秘得多,很少有人说自己有这款引擎,哪怕只有一个Eval。虽然有教育免费版,但是据我所知,也只有北大才申请到了授权。花了500W左右买了授权的好像也只有畅游和久游。但是越是如此,这款引擎的魅力越让人无法抗拒。当我有PerfHUD,PIX这样的分析工具时,我如何能不想着去拆解这个神秘又神奇的引擎呢。
Crysis所伴随的往往是最高画质的赞美和硬件杀手的批评,但是,我觉得即使这样,Cryengine仍然可以称为当今世界上优化最好,负载最大的引擎。其实引擎的设计追求的主要是负载能力,追求画面的应该是游戏。但是反过来,拥有最大的画面质量,没有引擎的强大负载,肯定是做不到的。任何引擎可以被美术用成硬件杀手,但是能在同样的情况下,跑出Crysis那样的画面的引擎肯定有着强大的负载能力。
Cryengine优化的出彩之处主要有以下几个方面:
1材质排序:从PerfHUD的结果来看,Cryengine对DXAPI的调用是最为简洁的,如此多的材质,却只有如此简洁的状态切换过程,不能不令人赞叹,相比之下,OGRE或者GB之类的三流引擎做得就要差得多。材质排序已经被做到了极至,从这里省下来的时间,成为了Crysis如此复杂的宏大场景的基础。
2技术选择:这是我最佩服Crytek的一点,如此多的次世代渲染技术,竟然每个都如此地和谐,兼顾着性能与效果。我研究了它的好多渲染手法,真是深有感触,为啥能如此恰当地选择技术呢?后来看了它们LPV的一篇Paper中有这样一个预算
这从恍然大悟。原来他们竟如此专业,预先做了这样的评估,难怪技术都被优化得如此高效,和谐。
3.瑕疵优化:这个通常被人忽略,或者被人认为是错的。很多人都觉得宁愿速度慢一点,也要求技术没有瑕疵。其实,这是不对的。瑕不掩瑜,在Crysis如此震撼的效果面前,有几个会对它技术的瑕疵非常关注,觉得不能忍受呢?但是在Cryengine中,所有的瑕疵都换来了宝贵的时间,以至它能对一个游戏添加如此多的渲染技术,以达到Crysis的效果。
有了这些与众不同,使Cryengine变得如此另类,以及怪物般的负载能力。当然有人要说,Cryengine不是最快的,因为相同速度的情况下,虚幻的画面可能更好。对,确实,虚幻的Irradiance技术提供了一个廉价的GI效果,但是,这个东西带来的限制却让虚幻完全没有能力大幅度改变场景光照,因为主光源是预先渲染好的。这个东西在Cryengine3中已经被支持了,同时候还有了LPV这个神奇的动态GI。这样说的话,Crysis所追求的全动态场景的理念其实也是逼真临场体验的一部分,当然需要更多的性能开销了。也就是因为Crysis有昼夜变化,才带来了这种前所未有的临场他体验。
接下来,我要对Crysis所使用的渲染技术进行一些细致的剖析,当然也带着一些不理解的问题,希望大牛们能给我一些建议和帮助。
Crysis是用Cryengine2制作的,Cryengine3无幸窥见,在这里,先说说确切的Cryengine2的渲染过程。
众所周知Cryengine2,没有使用DeferredShading,所以无法支持太多的光源,主要渲染围绕着阳光进行,而且使用了非常复杂的PixelShader来实现漂亮的材质,所以ZPass预渲染就变得很必要,不然会有很多无用象素被复杂的PixelShader渲染,当然这个和DeferredShading一样,无法支持Blend,所以只有两种,普通和AlphaTest。渲染ZPass为了开启PreZ,肯定要进行排序,先渲染普通物体,后渲染带AlphaTest(当然是使用Shader的Texkill来进行,没有状态切换)的物体。其实标准的ZPass应该是不需要ColorWrite的,但是Crysis利用这个机会,输出了深度到一张R32F,因为视距为八公里,乘一个0.000125映射到[0,1],天空为2。有了深度的G-Buffer,其实就已经可以做很多事了,除了光照外很多的后处理都可以用这张深度缓冲来进行。有了深度后,会先进行AO计算,然后阴影,这都是屏幕空间的计算,然后渲染每个物体都会对这两张图进行采样。AO是一张RGBA,R通道用来存SSAO的结果,G通道用来存2.5DTerrainAO的结果。然后进行一次Blur。阴影是有个Mask的,平行光一般是R,剩下三个通道,大概可以存放三个点光源或者SpotLight吧。然后就是对一张R16G16B16A16F进行HR的高范围渲染。这回DepthFunc已经是Equal了,因为深度已经完全填充。当然,为了PreZ,还是先普通后AlphaTest,然后会看到大量的碎片,因为Z检测会挡掉大量像素。所有着色像素加起来也几乎就是屏幕像素了,除非有两个三角形有点是同Depth的Fighting状态,当然可能性很低。完成后会进行Blend渲染,主要是粒子,玻璃之类的东西。结束后,就要进行HDRToneMap和HDRHighLightBloom了。完成后,接下来有一个EdgeAA,当然除此之外应该还有抗齿过程,只是调试时肯定是要关掉的。EdgeAA是个抗齿的后处理,只使用Depth来提取边缘。然后还有个Glow,大概会把火焰之类的Bloom加大吧。在这之后,就是SunShaft,来加上漂亮的Ray和Beam,最后会进行ColorGrading,完成渲染的最后一步,这样,就能看到Crysis的画面了。这样说是不是有些笼统呢?没关系,如果大家喜欢,我还会继续深入剖析Cryengine渲染的一些技术点,来解读震撼画面背后的故事。今天有点晚了先写到这儿了。
睡前再写一些看了KlayGE后的感想,KlayGE是一款我很喜欢的开源引擎。对于开源引擎来说,没有强大的资金支持,很难开发出像商业引擎那样功能强大的实用引擎。KlayGE这样研究一些新鲜的API,支持OGL3或4,DX11,以及一些好玩的技术的实现,却是真正有帮助的。它的字体算法的设计真的是非常的独到,让我非常震撼,我正在想有什么办法能使缩小时更清晰。像Ogre,Irrlicht那种引擎中既见不到强大的实用性,又没有这样的看点,我个人还是比较无爱的。KlayGE最近又出了FFT的水,对于只能看到SigGraph1999的我来说,还是非常有帮助的,记得上回Ogre有个水体插件,也做了FFT的波动,不过实时CPU刷顶点做法还是有点过了,这了新的Demo看,真的挺兴奋的。
有一点想问下作者,你的DeferredShading为啥不支持HW的AA呢,而使用一个后处理来进行?DX10开始,MRT不是已经可以AA了吗?难道还有什么障碍?
最后发张我现在自己渲染的图,虽然比Crysis差不少,但是渲染技术是差不多的。其实如果时间允许,我真是想自己操刀写个引擎,把Ogre改成这样真不是一般的麻烦,Ogre的渲染体系太古典了,不太适应现代的技术,搞得我动不动接管过来调DX,不然要么性能莫名其妙地不见,要么就是干脆无法实现。不过因为DX9,使用了DeferredShading后只能用后处理来抗齿,其实可以用超级采样,但是舍不得那性能啊。Ogre的材质系统不灵活,导致我一怒之下统一使用了线性过滤,材质糊糊的很不爽。下一步,可能就是要尝试下LPV了,毕竟GI还是很令人Happy的