《奥日与精灵意志》如何完成近乎不可能的Switch移植任务?

本文授权转载自知乎用户——托比亚

未经允许请勿二次转载

一直很好奇Moons studios究竟是如何在远程合作的状态下保持高度的生产力并完成如此优秀的游戏的,他们甚至在近期完成了近乎不可能的任务:让Ori在Switch上在对画面质量不怎么做出妥协的情况下让游戏稳定60fps,真的好想一窥他们的Workflow是怎么搭建的。

Switch与Xbox One的画面比较,不仅差异十分的小,还稳定维持在了60fps

终于Digital Foundary回应了我的期待!他们在前几天发布了个视频,就是关于Moons Studios在针对Switch上面的开发优化上做了哪些努力,并多少分享了他们的Workflow!于是兴奋的我反复看了视频数遍后草草记录下了重点。

游戏引擎采用的是自定义的unity游戏引擎,并取名Moonity,是个完全围绕Ori游戏类型和渲染方式特别定制工作流及渲染管线的自定义引擎。

他们完全采用了Painter Algorithm的方案(由后往前绘制),结合Early-z pre pass规避Overdraw,并根据结果渲染成6张layers的RT,再与3D角色的RT layer blend在一起(不过由于层级的深度排序几乎是固定的,似乎做了些离线操作减少了early-z的gpu压力,至今没搞明白具体做了什么)。除了角色层以外,每个RT代表的layers都可以单独设置分辨率,不仅可以做出景深(Depth of field)的效果,还能降低gpu的负担

所有的场景都是由6层场景layers加上3d角色的layer,一共7层构成的,每一层都会渲染成一张独立的RT

蓝色的部分是early-z的结果,目的大概是在生成不同layer的RenderTexture的时候可以直接cull掉重叠的像素

除了角色层以外,所有的layers都可以单独控制分辨率,从而形成DoF的效果,并提高了渲染效率

由于玩家在进行操作精度高且快节奏的游戏时,视角基本只会集中在角色身上,因此游戏就能通过视觉焦点的位置去切不同频率(Frequency)的贴图资源。大体操纵方法是:视觉焦点的周遭选高频率的贴图,其他地方就能替换成低频率压缩(Low Frequency Compressions)的贴图从从而减少显存的负担。

距离角色近,也就是视觉焦点的附近选择高频率的贴图,反之选择低频率压缩后的贴图

他们还进一步在每个场景设置了上百个摄像机的位置节点,来预计算并储存每个场景物件对该镜头位置的贡献度,这样在游戏中就能动态隐藏对镜头贡献不足的物体了。

对该镜头节点贡献度不足阈值的物体会被动态隐藏

接下来我们聊聊对Ori画面质量提升最大的自定义光照,其中分为了静态光照及动态光照,先从相对简单的静态光照开始。

静态光照是手动画上去的,美术可以直接在Unity中将光照画在一个低频率独立的GI Layer上面,并且可以依据情况在游戏中切换成低分辨率的版本。

美术可以直接在引擎内绘制静态光照信息

而动态光照就比较Charming了,大体使用了两个方法。首先美术会绘制角色6个不同面的受光信息(前后上下左右),并把其烘焙到rgb里(应该会是个atlas),根据光的位置与距离去进行插值,这也不算什么新技术了,不过最终呈现的效果还是很赞的。

美术绘制了不同方向的光照信息

根据光源的位置去进行插值

而光照的着色则是借鉴于Doom 2016中的Particle Lighting的技巧,Moons studio称之为Tile light calling,大体是将不同深度及优先级的光照信息写入一张Tile Atlas,再生成对应的Tile indices来索引和混合光照的颜色。相比于Xbox通过Compute Buffer计算并存储Indices的方案,Switch则采用了一张低分辨率的2D贴图来记录indices,结果上来说对画质并没有造成多大的损伤。

光照信息的画面,可以隐约看到不同通道的光照范围是如何混合的

可能是团队借鉴的技术,截取自Doom 2016的分享。id software发现由于画面中各别的粒子效果对画面的贡献程度是不同的,想到了根据距离及重要度等信息将个别生成的光照信息输出成Atlas,并在绘制完粒子特效后重新叠加光照效果的方法,从而实现了高效优质的渲染效果,并且其渲染质量与屏幕分辨率无关

有趣的是,所有的layers都是做的前向渲染,只有3d的角色layer采用的是延迟渲染。按照原视频的说法,没有统一使用延迟渲染的主要原因是延迟渲染会丢失真实的深度信息,在逐Fragment计算Tile light calling时可能造成潜在的artifact。

虽然没有详细说明,不过由于延迟渲染中,位置信息会存储在Fragment阶段后所产生的MRT中的32位Float位置贴图里,是有信息丢失的可能。

只有3D角色是延迟光照

游戏中的Soft Physics是直接在Unity中绘制的,省去了从其他DCC软件频繁导出的烦恼,并且整个过程是Undestructive的

God rays则采用了对多个帧做Stochastic Sampling + Blur,Stochastic Sampling是一种结合Poisson Disc(均匀采样) + 抖动的随机采样方法,从最终的画面效果来说也是可圈可点的。

优秀的2D God Rays将画面的氛围档次进一步提高了

Ori的发光拖影其实就是一堆从顶点拖拽出的发光片,这里借鉴了Keijiro大神的vertex based skinner方案,具体可以看https://github.com/keijiro/Skinner。

拖影是一堆从顶点拖拽出的发光片

无处不在的拖影效果

Profiling 就更好玩了,他们首先定制了完整的In-Game Profiler工具,并且可以记录足够长时间的侦测结果,以客观地量化当前的优化进度。

记录多日的Profiling,从图中可见游戏效率随着日子推移逐渐趋近于稳定

接下来,他们还制作了可以记录每个场景当玩家处于不同位置的渲染时间,并分别记录了各别场景的渲染峰值。由于Switch上的目标帧数是60fps,所以当渲染峰值高于15ms的时候,就会在场景上标记出来,这对开发人员侦测渲染效率的帮助是不言而喻的。

可以将每个场景及路径渲染峰值记录下来的Profiler

绿色表示的是玩家经过的路径,除了记录了QA Test的信息外,他们还搞了个快速跑关的测试工具来重复并快速地检测问题点。

飞起来吧Ori!给我查找问题去!

为了方便对比XBox和PC平台的画面效果,他们顺手拍下了各别平台针对该峰值区域的截图,并根据日期排序,以方便横向对比优化前后及不同版本之间各平台的显示差异。

选择显示平台及日期的操作界面

切换不同平台对比显示效果

最后的最后,来聊聊Ori的场景无缝衔接解决方案吧。首先游戏会缓存相邻场景间相关信息,以便于在游戏中实时计算玩家与相邻场景的距离,并预测玩家即将到达和远离的场景来动态读取或释放游戏场景。

计算玩家位置并预测需要预读取或撤销的场景

由于Ori是个快节奏高难度的动作游戏,为了保证死亡能够快速重启,Ori的每个Checkpoint也会预缓存周遭区域的资源,并在达到下个Checkpoint以前始终保存在内存里,也就造成了能够记录关卡信息的内存就更少了,所以游戏开始时候就需要做一些预缓存来小心处理资源读取可能存在的问题,不过这也就造成了开始游戏的读取时间会特别的长。结果上来说的确保证了游戏的顺畅性及场景无缝衔接的体验,所以这种妥协肯定是值得的。

团队正在通过放大摄影机的可视范围及可视化Safe Zone来观察资源的加载情况

经常觉得周遭的开发者朋友们都在用苦瘪的方式来开发游戏,近期一直在寻找着能愉快地开发游戏并方便自动化地检测问题的workflow,Moons Studios的远程合作方案的确给我带来了很多的启发,真心希望哪天我也能在家里使用如此畅快淋漓的workflow来远程开发我热爱的游戏呐!

原视频地址:www.youtube.com/watch%3Fv%3DkH6wTpIObxE%26t%3D650s

本文来源:知乎-托比亚
如无授权请勿二次使用

游戏

《天外世界》即将结束Epic独占,于10月23日登录Steam平台

2020-10-10 12:03:54

游戏

亚马逊游戏工作室关闭其第一款游戏《Crucible》

2020-10-10 14:03:56

搜索