《奥日与精灵意志》是如何完成近乎不可能的Switch移植任务的?
发布时间:2020-10-04 23:21:48来源:GameRes游资网
作者:托比亚,会音乐和游戏设计的TA里最帅的那位
本文首发知乎:https://zhuanlan.zhihu.com/p/260116904
一直很好奇Moonsstudios究竟是如何在远程合作的状态下保持高度的生产力并完成如此优秀的游戏的,他们甚至在近期完成了近乎不可能的任务:让Ori在Switch上在对画面质量不怎么做出妥协的情况下让游戏稳定60fps,真的好想一窥他们的Workflow是怎么搭建的。
Switch与XboxOne的画面比较,不仅差异十分的小,还稳定维持在了60fps
终于DigitalFoundary回应了我的期待!他们在前几天发布了个视频,就是关于MoonsStudios在针对Switch上面的开发优化上做了哪些努力,并多少分享了他们的Workflow!于是兴奋的我反复看了视频数遍后草草记录下了重点。
游戏引擎采用的是自定义的Unity游戏引擎,并取名Moonity,是个完全围绕Ori游戏类型和渲染方式特别定制工作流及渲染管线的自定义引擎。
他们完全采用了PainterAlgorithm的方案(由后往前绘制),结合Early-zprepass规避Overdraw,并根据结果渲染成6张layers的RT,再与3D角色的RTlayerblend在一起(不过由于层级的深度排序几乎是固定的,似乎做了些离线操作减少了early-z的gpu压力,至今没搞明白具体做了什么)。除了角色层以外,每个RT代表的layers都可以单独设置分辨率,不仅可以做出景深(Depthoffield)的效果,还能降低GPU的负担。
所有的场景都是由6层场景layers加上3d角色的layer,一共7层构成的,每一层都会渲染成一张独立的RT
蓝色的部分是early-z的结果,目的大概是在生成不同layer的RenderTexture的时候可以直接cull掉重叠的像素
除了角色层以外,所有的layers都可以单独控制分辨率,从而形成DoF的效果,并提高了渲染效率
由于玩家在进行操作精度高且快节奏的游戏时,视角基本只会集中在角色身上,因此游戏就能通过视觉焦点的位置去切不同频率(Frequency)的贴图资源。大体操纵方法是:视觉焦点的周遭选高频率的贴图,其他地方就能替换成低频率压缩(LowFrequencyCompressions)的贴图从从而减少显存的负担。
距离角色近,也就是视觉焦点的附近选择高频率的贴图,反之选择低频率压缩后的贴图
他们还进一步在每个场景设置了上百个摄像机的位置节点,来预计算并储存每个场景物件对该镜头位置的贡献度,这样在游戏中就能动态隐藏对镜头贡献不足的物体了。
对该镜头节点贡献度不足阈值的物体会被动态隐藏
接下来我们聊聊对Ori画面质量提升最大的自定义光照,其中分为了静态光照及动态光照,先从相对简单的静态光照开始。
静态光照是手动画上去的,美术可以直接在Unity中将光照画在一个低频率独立的GILayer上面,并且可以依据情况在游戏中切换成低分辨率的版本。
美术可以直接在引擎内绘制静态光照信息
而动态光照就比较Charming了,大体使用了两个方法。首先美术会绘制角色6个不同面的受光信息(前后上下左右),并把其烘焙到rgb里(应该会是个atlas),根据光的位置与距离去进行插值,这也不算什么新技术了,不过最终呈现的效果还是很赞的。
美术绘制了不同方向的光照信息
根据光源的位置去进行插值
而光照的着色则是借鉴于Doom2016中的ParticleLighting的技巧,Moonsstudio称之为Tilelightcalling,大体是将不同深度及优先级的光照信息写入一张TileAtlas,再生成对应的Tileindices来索引和混合光照的颜色。相比于Xbox通过ComputeBuffer计算并存储Indices的方案,Switch则采用了一张低分辨率的2D贴图来记录indices,结果上来说对画质并没有造成多大的损伤。
光照信息的画面,可以隐约看到不同通道的光照范围是如何混合的
可能是团队借鉴的技术,截取自Doom2016的分享。idsoftware发现由于画面中各别的粒子效果对画面的贡献程度是不同的,想到了根据距离及重要度等信息将个别生成的光照信息输出成Atlas,并在绘制完粒子特效后重新叠加光照效果的方法,从而实现了高效优质的渲染效果,并且其渲染质量与屏幕分辨率无关
有趣的是,所有的layers都是做的前向渲染,只有3d的角色layer采用的是延迟渲染。按照原视频的说法,没有统一使用延迟渲染的主要原因是延迟渲染会丢失真实的深度信息,在逐Fragment计算Tilelightcalling时可能造成潜在的artifact。虽然没有详细说明,不过由于延迟渲染中,位置信息会存储在Fragment阶段后所产生的MRT中的32位Float位置贴图里,是有信息丢失的可能。
只有3D角色是延迟光照
游戏中的SoftPhysics是直接在Unity中绘制的,省去了从其他DCC软件频繁导出的烦恼,并且整个过程是Undestructive的
在Unity中直接制作SoftPhysics
Godrays则采用了对多个帧做StochasticSampling+Blur,StochasticSampling是一种结合PoissonDisc(均匀采样)+抖动的随机采样方法,从最终的画面效果来说也是可圈可点的。
优秀的2DGodRays将画面的氛围档次进一步提高了
Ori的发光拖影其实就是一堆从顶点拖拽出的发光片,这里借鉴了Keijiro大神的vertexbasedskinner方案,具体可以看https://github.com/keijiro/Skinner
拖影是一堆从顶点拖拽出的发光片
借鉴了Keijiro大神的Skinner
无处不在的拖影效果
Profiling就更好玩了,他们首先定制了完整的In-GameProfiler工具,并且可以记录足够长时间的侦测结果,以客观地量化当前的优化进度。
可自由拖动的In-GameProfiler
记录多日的Profiling,从图中可见游戏效率随着日子推移逐渐趋近于稳定
接下来,他们还制作了可以记录每个场景当玩家处于不同位置的渲染时间,并分别记录了各别场景的渲染峰值。由于Switch上的目标帧数是60fps,所以当渲染峰值高于15ms的时候,就会在场景上标记出来,这对开发人员侦测渲染效率的帮助是不言而喻的。
可以将每个场景及路径渲染峰值记录下来的Profiler
绿色表示的是玩家经过的路径,除了记录了QATest的信息外,他们还搞了个快速跑关的测试工具来重复并快速地检测问题点。
飞起来吧Ori!给我查找问题去!
为了方便对比XBox和PC平台的画面效果,他们顺手拍下了各别平台针对该峰值区域的截图,并根据日期排序,以方便横向对比优化前后及不同版本之间各平台的显示差异。
选择显示平台及日期的操作界面
切换不同平台对比显示效果
最后的最后,来聊聊Ori的场景无缝衔接解决方案吧。首先游戏会缓存相邻场景间相关信息,以便于在游戏中实时计算玩家与相邻场景的距离,并预测玩家即将到达和远离的场景来动态读取或释放游戏场景。
计算玩家位置并预测需要预读取或撤销的场景
由于Ori是个快节奏高难度的动作游戏,为了保证死亡能够快速重启,Ori的每个Checkpoint也会预缓存周遭区域的资源,并在达到下个Checkpoint以前始终保存在内存里,也就造成了能够记录关卡信息的内存就更少了,所以游戏开始时候就需要做一些预缓存来小心处理资源读取可能存在的问题,不过这也就造成了开始游戏的读取时间会特别的长。结果上来说的确保证了游戏的顺畅性及场景无缝衔接的体验,所以这种妥协肯定是值得的。
团队正在通过放大摄影机的可视范围及可视化SafeZone来观察资源的加载情况
经常觉得周遭的开发者朋友们都在用苦瘪的方式来开发游戏,近期一直在寻找着能愉快地开发游戏并方便自动化地检测问题的workflow,MoonsStudios的远程合作方案的确给我带来了很多的启发,真心希望哪天我也能在家里使用如此畅快淋漓的workflow来远程开发我热爱的游戏呐!
原视频地址:https%3A//www.youtube.com/watch%3Fv%3DkH6wTpIObxE%26t%3D650s
投稿邮箱:news@GameRes.com
商务合作:Amber(微信:lcxk6876767)
其他合作:老林(微信:sea_bug)