基于Ogre的DeferredShading(延迟渲染)的实现以及应用

发表于2015-07-21
评论0 904浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594

三年前开始接触ogre引擎,由于工作需要一直进行图形方面的研发和尝试,随着引擎技术的进步,ogre的与Cryengine3、Unreal3等一线图形引擎在画面上的差距越来越大,主要原因在于ogre目前的设计趋于一套开放性的架构,并不着眼于细节的完善,也就是说盖一栋别墅,如果你要住进去就要自己去装修....软件开发都说魔鬼是藏在细节里面,这样的开放式框架也给项目使用者带来很大门槛,更多的时间花在了完善ogre的功能上。

在图形方面,ogre的默认图形架构属于最传统的方式,当今次时代引擎无一不进入延时渲染时代(Deferred Shading),这种渲染架构既保证了渲染效率又带来了新的渲染效果,Ogre例子里虽然也涉及DeferredShading的例子,但是并不实用(显然只是开发者用来告诉使用者Deferred Shading这个都东西可以有),针对这一点,基于ogre1.65(已经升级到1.75)我重新设计了一套Deferred Shading框架,接下来就由这个框架来简单介绍一下Deferred Shading(根据读者需求我会针对单个的技术写文章)。
首先,来几张DeferredShading框架下的Demo截图,该相关信息也将会发布在ogre Froums上,敬请期待。




上传到优酷的Demo视频 :


很多人对森林那部分场景感兴趣,我简单做了下技术解析,主要针对渲染架构下的数据信息输出,以及各种渲染技术叠加所产生的效果,并包含一些单个技术的解析。

一下是我使用的渲染流程图表:

包含深度数据以及法线数据,深度数据可以还原成每个像素的位置数据,有了这个信息我们实现了SSAO、Fog、Light shaft、Dof等众多效果。发线图除了应用于光照,对SSAO或者以后将要有的SSGI都有一定的贡献,我相信在将来的一段时间的图形新技术也免不了要依赖于G-Buffer,该图表充分反应了G-Buffer的重要性,而且提供了更广泛的扩展性。

上图是要说明的是各个效果之间的相互作用与叠加对图像产生的影响,我想表明的观点是,任何效果只有在相互融合的情况下才能发挥出应有的作用甚至超乎自己的想象,这需要你对场景特点的解读以及对自然界细心的观察,并经过反复的调整,对于美术人员来说,需要充分对这些效果进行透彻的理解(这点比较困难,美术人员理解方式与技术人员有较大不同),然后把心里所想的场景氛围一层层的剖析分解,再使用现有技术进行调整。

接下来我将做一些单个技术的解析:


光源

在渲染场景物体的时候,我讲透明和非透明物体分开进行渲染,这是因为DeferredShading的先天性对Alpha测试处理的缺陷,只能使用前向渲染来处理里半透明物体,从另一个角度上来说半透明物体失去了DeferredShading光照的优势,所以DeferredShaing对处理写实场景具有很大优势。

在光源处理上,将太阳光进行了单独的处理,在美术的角度上,要想获得模型较好的光照效果,普遍使用三角光源来渲染模型样板,其实仔细的对自然光的观察,也可以将自然光拆分成三个光源,我姑且先起名为:(太阳)直射光,逆射光,天光。

直射光描述太阳产生的方向光,让物体产生立体感,这个最容易理解。逆射光与方向光的方向相反,主要表现太阳光照射在物体上的反射光线,突出暗部边缘和于正面光源颜色的互补。天光则是描述阳光在空气中的散射,以垂直向下的方向光进行模拟,但是因为空气散射是四面八方没有固定的方向,我们可以修改一下phone模型的公式,将光照范围扩大一倍,这样混合的光感就更接近自然。

(从左到右依次添加了方向光、逆光、天光)

VSM/PSSM(阴影)
阴影是提升场景物体存在感和厚重感的重要手段,但阴影所带来的巨大的开销是最让人头痛的一件事,Cryengine和Unreal无一不在阴影上下足了功夫。为了保障效率,在Deferred Shading插件针对有无光源变化使用了两种解决方案:VSM、PSSM。
在光源无变化的场景中的静态物体使用VSM技术和LightMap混合的方式,在一定范围内才是很正的阴影,超出之歌范围则自动过渡到LightMap烘焙的阴影部分,这样阴影的计算量就小了很多。在诸如有日夜变化的场景中,显然烘焙的阴影不能达到要求,这就需要所有物体都进行产生真实的阴影,也就是使用开销很大的PSSM技术,该技术有也是有很多优化空间,但是总体来说还是需要使用者心中权衡利弊。

半透明物体
这里所说的半透明物体并非使用alpha mask的物体(比如叶片),而是想使用alpha blend的物体(玻璃,水面),因为Deferred Shading天生对处理alpha物体的光照有缺陷(如果半透明物体需要关照也是单独完成),所以要使用 front shading做单独处理,然后再与Deferred Shading进行Depth Test和Alpha Blend,也就是所化框架图的颜色混合那一步骤。
游戏中使用的最多的半透明物体就是水,自然界中的水会对水面以下的东西进行扰动,这一点上Deferred Shading可以发挥作用,在光照阶段将不透明的物体均渲染得到的纹理Buffer,我称为LightColorBuffer,将LightColorBuffer作为纹理贴在水面上,再根据法线对该纹理进行扰动,这样我们就得到一个廉价又美观的折射效果,再配合方向光的光照(主要是Specular)就得到一个不错的水面效果,另外还可以通过获得G-Buffer中的高度数据来实现水面的自动深度,今后我会做一个专题文章。

水的效果

水晶材质


SSAO(全场景光线遮蔽)

光线在空气中以光粒子的形态传播,会受到各种物质的反射和干扰,可以看到在现实生活中一面墙壁的角落会比其他地方更暗一些,也就是说传统的phone模型光照是以射线的方式来进行计算光照,无法模拟出空气已经物体对光的反射和折射关系。SSAO全名问全屏(幕光线遮蔽),最早是由cryengine2的研发人员设计并真正应用的一项技术,目前已经目前次时代作品普遍使用的一项技术。SSAO可以模仿出上述这种光线在传播的效果(只是模仿而已),通过G-Buffer中获取的深度图计算当前像素和周围像素之间的位置关系,进而得到该像素点是否处于光线比较难以到达的位置。

该项在该技术发明之前许多游戏工作者已经发现AO对场景存在感有着质的提升,所以很多老游戏都采用使用美术手段在3D软件中烘焙LightMap(光照图)的方式(最早使用者是大名鼎鼎的卡马克),这种方法仍然沿用至今,甚至有LightMap和SSAO混合是用的例子(Unreal Engine3)。



Glow(自发光)

很多游戏中存在一些细小且不规则的发光物体,想一些发光的符文,这些细小特别的发光物体使用灯光物体是不需要使用真正的光源,Glow效果在此处就有了用武之地。

我们将发光信息存储在模型的纹理中,如图:在渲染物体时将该信息提取并做为一个(或者三个)通道存储在Buffer中,这样在后期再从Buffer中得到这个发光信息,通过高斯模糊处理再与原Color重叠即可得到Glow的效果。Glow并不能照亮环境中的其他景物,是一种视觉欺骗,不管如何我要的效果是达到了。(图形学里面充满各种视觉欺骗...)



Fog(雾效)

雾化效果在游戏中是最常见的一种特效,以摄像机距离来计算雾的浓度,在传统渲染模式中已经运用很成熟。在次时代游戏里对雾化又有新的需求,就是高度雾。雾本身是粒子状漂浮在空气中的水珠,应该具有一定的沉积性,也就是根据高度来计算雾的浓度。从G-Buffer中获得DepthMap,将深度数据转换为高度数据,剩下的就容易多了,自己设置一下相关参数,调整一下OK,如图:


DOF(景深)
景深这个术语来自摄影和摄像,模拟人眼聚焦一个物体时对聚焦之外物体的虚化模糊的一种效果,在游戏中,这种技术往往出现在一些交代剧情的过场上,给人一种影视化的感觉。
首先对当前渲染得到的画面(map)进行高斯模糊(类似PS中的滤镜)另存在一张纹理(blurmap)上,在获取depthmap,根据要聚焦的位置参数将得到一张遮罩图(maskmap),再使maskmap使blurmap与map进行混合,就得到了下图中的效果,在实现这个技术上我的做法相对简单,效果也算不错,当然也有更好地方式,但实现起来也相对复杂,这里不再细说。


Light Shaft(体积光)
空气中有很多杂质离子,光线在通过时多少会有些被折射或反射,就可以看到光柱一样的效果,这个就是我们所说的体积光。早期的3D游戏中,是依靠美术来制作体积光,在透光处添加使用alpha blend固定的面片,这个方式在封闭的场景中也可以达到不错的效果,例如教堂、山洞等场景,但是对于开放性场景和不断变化的场景却是无能为力,例如森林、流动的云层。
这项技术的实现手法跟DOF很类似,同样要用到DepthMap,根据参数得到maskmap,根据太阳的位置对maskmap进行径向模糊(参考PS的滤镜),最后调整好光的颜色以及与场景的混合方式就OK了。


HDR(高动态光照渲染)
人的眼睛对光的感应区间要远远大于普通显示器所提供的颜色,为了模拟渲染画面的真实感,根据人眼对光强弱时瞳孔和眼皮对入射光的控制,图形工作者发明了HDR技术,(该项技术在摄影和摄像中也是最基本的技术),让画面亮度动态的根据场景亮度改变。这个就好似你拍了一张照片,在PS里面处理一样,要想得到完美效果,仅仅更改画面亮度是远远不够的,还要调整整体的对比度和饱和度,对一些写实的游戏来说,这样可以使画面变得厚重和真实。具体的调整方式各不一样,卡通也好,写实也好,明亮也好,灰暗也好,没有统一的计算公式,但是不变的都是要根据色彩搭配的原理和对人眼感光的模拟。

Color Control(颜色控制)
整个渲染的最后一步就是颜色控制,主要是用作后期的整体画面调整,这些调整往往是带有个人风格而非真实性的调整,如果我们留意的话,可以发现绝大多数好莱坞大片在根据剧情不同的时期的色调都会发生变化。
首先在场景中截图,这个就要利用PS工具,在PS里的曲线工具中调整,直到我们满意的颜色,保存调整后的曲线数据,导出数据图,在shader中使用就OK了,更像我们平时修改照片,甭管照的时候有多么歪瓜裂枣,有些娃们总能P出一张“非主流”色调调


颜色控制基本算是所有技术中最简单的一项技术,但是却是非常实用,最早出自GPU精粹1。


结语
往往一项图形技术的产生都是由感性思维到理性思维的转变过程,是感性和理性碰撞的结晶,如果你是一名理工科出身(尤其是计算机专业)的图形工作者,首先,图形学底子一定要扎实,这是你立足的根本。其次,你需要培养的是自身的审美能力和观察能力,适当的学习一下绘画和建模,这点让你在同行中出类拔萃。最后,找一家真正想把游戏做好的公司,能够给你一个施展才华的空间。
图形固然重要,就像女人的外衣和化妆品,可以让一个游戏光鲜照人,但是确不能掩盖品质的恶劣低俗,如果美术的品质低下,再好的图形技术也无力回天。作为一个图形技术人员,应该做到与美术的交流力度大于程序,在表现层面上和美术人员进行讨论,在技术层面对美术人员进行指导,互相促进。另外补充一句,图形技术要用的恰到好处,不同的场景采用不同的图形解决方案,切忌不要滥用!
终于完成了这篇文章,这算是对我这三年来所热衷的事业做一次总结吧,以后的我也将不再从事图形引擎的研发工作,上述技术也不是什么新鲜的东西,希望这篇文章和我的图形插件能帮助到更多的朋友。

后记

    这篇文章写于两年半前,作为我在这的第一篇文章吧。写完这篇文章之后我就和几个朋友一起创业,带着技术人员的偏执和单纯,折腾了1年左右最终以失败告终,而如今的我是一家创业公司的主城,使用的引擎已经是Unity,可能有人会问我你之前的积累不是白费了吗? 我自己觉得并不是这样,Ogre 是个很好的学习参考,通过Ogre我深刻理解了引擎底层的机制,这让我对很多引擎都能比较轻松的掌控,万变不离其宗就是这个道理,希望如今新入行的朋友们,不要只被各种引擎花哨的效果迷了双眼,事事多追本溯源会对你今后的发展有非常大的帮助。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台