首页 > 代码库 > [sig14&gdc14]crytek的《罗马之子》的渲染技术
[sig14&gdc14]crytek的《罗马之子》的渲染技术
crytek关于son of rome在gdc和siggraph都做了presentation,两者有些地方一样的,干脆一勺烩了吧:
http://advances.realtimerendering.com/s2014/crytek/Sigg14_Schulz_Mader_Ryse_Rendering_Techniques.pptx
http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf
看到一直推动行业水准前进的公司陷入财务困境属实揪心,希望crytek能更接地气的赚到钱,别趴下。
pre
ryse:son of rome是xbox one独占的游戏,xbox one硬件性能不太好,计算能力比高端pc要差,加上这个团队里面的人也比较少,所以crytek在son of rome里面也没有做更新换代式渲染技术升级,更多的是进行polish和改进,其实这种我反而更加喜欢,一些概念理解更加深刻,一些技术实用精致,很不错。
另外xbox one毕竟ram大了很多,8g的ram相比上一代的512mb,足以在很多领域较上一代产生算法级的变化,能做的事情多太多了,crytek在static shadow,large scale ao方面也是大笔一挥,2048的,8192的轮番上阵。
其实做久了,会发现革命性的东西看起来很美,我们实际收益最多的还是类似文中这些精益求精的点点滴滴,所谓以正合以奇胜吧。
Lighting&material
physical based shading
这个现在已经是标配了,大家起码在名词上都号称PhysicallyBasedShading,但是其背后在模型选择,融合以及整个程序美术团队的合作上却颇有深度,初级的(比如cod:black ops)与超级的(比如disney的动画片)有天壤之别。
son of rome被定位为xbox one上首发画面标杆,希望进一步接近电影级画质,crytek认为关键就在于进一步推进physically based的水准,并且这些从数据制作到最后的算法实现都要完整正确才行(Physically Based Shading can only work well if it gets respected inall areas)
shading model:在distributionfunction和diffuse brdf更复杂(真实)了些
*specular brdf
**macrofacet model
***distribution function : ggx(和disney的一样)
*****fresnel&visibility项是最常用的schlick approximation和schilick-smith approximation
*diffuse brdf:oren nayar模型
期间都做了些小优化。
material:
*diffuse albedo
*specular reflectance--这个根据材质的材质的折射率来制定的
*roughness--制作过程中使用反过来的,这个美术刷起来更直观
*normal
这里和早期物理光照常用的diffuse/specular color/gloss/normal也非常的接近。
deferred rendering
早期cryengine使用的是light prepass,但是在更复杂的shading model情况下,则必须要deferred rendering才行。
其中:
* normal使用的是BFN来提升8bit的精度
* 在几个通道里面会出现多种信息共享的情况
特殊光照模型的使用forward lighting
specular aliasing
非常喜欢的部分:crytek把normal和roughness(概念上接近gloss)联系起来,认为normal描述宏观上材质的粗糙程度,而roughness描述微观上的,而距离比较远的时候,normal则显得越发细致,这种情况的roughness就开始受到normal的影响。
crytek把normal存在rgb,roughness放在alpha通道,然后有一个处理过程,使用toksvig factor来矫正一次roughness,保证在sample到小mipmap的时候,如果normal方向很散的话,roughness会被提升。
这个矫正在http://blog.csdn.net/toughbro/article/details/39248549有。
材质本身但是如果一旦有潮湿等效果,改变roughness的操作的时候,这个问题就又出现了,最后又加了一个全屏的处理:
把specularcolor根据roughness的变化做了一个矫正(crytek实际实现的时候使用roughness的反,也就是smoothness来操作的,roughness美术用起来太不顺手了)
lightingattenuation
attenuation从传统的变成更加物理正确的:
间接光照
使用environment light probe来获取,每个有specular和diffuse两个部分。
采用的是手动摆放的方式,1关大约100来个。
env probe加上一个parallex correction来提升准确度。
ambient light
可以放一些专门打ambient light的光源,可以增强可以减暗,在一些室内可以用于防止全局的ambient lighting把幽暗的室内整的特别亮。
glossy realtimelocal reflection
之前一些local reflection是没有glossy信息的,用于非常光滑的表面,对于图中的比较糊的material,就需要使用到image based lighting中的glossy reflection的东西。
这里最physical correct的应该是voxel cone tracing系的,crytek也想尝试一下,但是有一个意向没有深入去搞。
最后使用的是构建了反射buffer之后进行downsample,构建一个mipmap chain出来,然后做glossy reflection。
ambient occlusion
ssdo,同时用于传统的ambientlighting和reflection occlusion(有时候也叫env occlusion..,反正就是用于做环境specular lighting部分occlusion的东东)。
加上了之后较好的处理了reflection occlusion的情况。
ao color bleeding:
传统的ao计算时候是final ambient lighting = ao * ambientlighting;
这个其实是对于真实的情况的过度简化--只是考虑到光线是从所有角度来的,如果周遭的geometry挡住了,就减少入射量,但是没有考虑到光线的多次弹射。
所以如果直接应用这个公式,那么比真实情况,或者我们觉得好的情况,会显得过黑。
把ao值做一个统一的提亮矫正,是一个可行的办法。
crytek更进一步,把diffuse gbuffer,downsample到小buffer上,
然后用这个buffer来对ao做一个矫正,一定程度上使用类似GI的方法来矫正ao,nice!
large scale ao
ssdo等只能处理屏幕空间,很小范围的ao情况,如果要到大范围情况,则无能为力,而这一块工作是非常有意义的。
相关领域,voxel cone tracing,以及spinter cell 5(http://www.realtimerendering.com/blog/update-on-splinter-cell-conviction-rendering/)里面这一块都可以做的比较好,使用的方法就是基于真实的geometry来产生ao。
crytek这里也是类似,只是在更大范围来做,个人非常喜欢,算法是:
--从上往下拍一个低分辨率的depth(1km用2048x2048),然后使用这个来以7.5m为kernel计算ao
shadows
角色shadow:
会专门有一个高精度的角色shadow,在生成shadow的时候一起计算进来。
另外在cinematic里面,crytek在cinematic工具里面加入了一个tag,指明可以在这个时候使用高精度阴影。
点光源shadow
点光源的shadow是把多个projector来在大的rendertarget里面atlas起来。
分辨率等会根据projector的重要性,覆盖面积等来管理。
static shadow
使用8192x8192来hold住一个1.3kmx1.3km的shadow map,这样远处的就不用每帧都画,节省效率。
相比之下,farcry3还是更好一些:
http://blog.csdn.net/toughbro/article/details/7941821
皮肤
specular lighting使用了ggx,crytek认为这个挺好,一般大家使用Kelemen/Szirmay-Kalos模型,各花入各眼吧。
依旧是screen space subsurface scattering,这个很gpupro上面的也没啥不同啊,crytek也讲了两页。
头发
高端离线渲染使用Marschner模型,一般实时的使用kajiya-kay,crytek也是选择的这个。
挑战最大的是头发柔和的边缘,之前crytek有使用过顺着头发tangent方向blur的方法(<gpu pro3>),这回终于决定直接alpha blending了。
过程感觉还是比较纠结:头发不写depth buffer,而是把depth记录在alpha通道,然后一个后处理来搞定。
Particles
particle会使用到场景里的light probe,所有particle会接受shadow。
会使用per vertex/per control point lighting来提升性能。
其他:
实际在x1上是900p的渲染,然后upscale到1080p,囧!!!
[sig14&gdc14]crytek的《罗马之子》的渲染技术