游戏开发论坛

 找回密码
 立即注册
搜索
查看: 5214|回复: 0

90帧高质量写实手游的程序实现与美术设计【GDC2023干货】

[复制链接]

4万

主题

4万

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
83198
发表于 2023-5-6 09:32:16 | 显示全部楼层 |阅读模式
用手机开90FPS的赛车?高度写实的场景下,如何平衡美术质量和资源消耗,打造体验感堪比PC游戏的画面呢?

在GDC2023的核心会场(Core concept)中,来自网易游戏王牌竞速项目组的游戏程序员蛋蛋和技术美术师Baoyong分享了手游《王牌竞速》是如何通过车辆优化、场景优化、纹理压缩,在较低的资源消耗下实现90帧的高质量手游体验的。

微信图片_20230506092116.jpg

以下是演讲实录(基于英文演讲内容翻译整理):

大家好,非常高兴可以跟大家进行分享,今天我们要谈谈我们的游戏《王牌竞速》,并分享我们是如何打造90帧高质量写实手游的。

《王牌竞速》是一款写实的休闲赛车游戏。我们有许多高度写实的车辆,也很多自己设计的特色车辆。

游戏的不同之处在于,每辆车都有一个特殊的技能,附带不同的技能效果,玩家将组队进行 3V3 比赛,通过不同的车辆搭配与技能组合来赢得比赛。

我们基于世界各地的特色场景,建造了很多赛道;也打造了一些现实中并不存在的科幻风赛道。

微信图片_20230506092121.JPG
现实场景赛道

微信图片_20230506092122.JPG
科幻赛道

今天的演讲分为四个部分,首先,我会介绍我们优化思路的核心理念,接着会从车辆、场景、图像压缩这三个方面来介绍团队是如何通过优化,在手机端实现 90FPS 的高质量画面的。

一、核心理念

在开始优化之前,我们要明确我们的目的。

策划说:现在很多手机都支持高帧率,我们要做 90FPS。因此,我们要尽量减少每一帧的性能开销。

美术说:我们想要逼真的效果,媲美PC端赛车游戏的品质。

但与PC相比,手机尺寸过小,受到种种性能限制,在移动设备上实现 90FPS 是一个很大的挑战,我们需要在高质量的视觉效果和低消耗的性能之间保持平衡。

我们得先问问自己:什么是最重要的?什么是不必要的?因此,抓住重点,就是我们优化的核心理念,找出对玩家影响最大的关键因素。之后自然而然,我们就会知道下一步该怎么做,哪些是需要深入研究的,哪些是可以放弃的。

先来确定我们游戏的关键点:我们想要一款具有高度写实、流畅、令人兴奋的移动赛车游戏,还原到游戏当中,对应的就是:写实的车辆、逼真的场景,以及高帧率。

二、车辆优化

首先,我们将讨论车辆优化。

我们想为玩家提供高品质的车辆,因此,我们需要抓住车辆的表现重点:高质量的质感、具有吸引力的外观、正确的动效和光影表现。

2.1 高质量的材质效果

先从材质开始,在游戏中,最为重要的两种材质是:透明涂层和碳纤维。

我们使用双层 BRDF 来制作透明涂层,使之更有质感;并使用双层法向量(Double-layer normal)来改良碳纤维材质,使其看起来更有光泽。

微信图片_20230506092124.JPG

微信图片_20230506092125.JPG

通过两种材质的叠加,我们得到了高质量、高拟真的车辆效果。

微信图片_20230506092126.JPG

在此基础上,我们想要更多不同的效果,让车辆外观更为独特、表面材质更丰富。

于是,我们增加了一个用于影响outer normal(外层法线)的法线贴图,赋予了车辆外观更多的改变,实现了更富有细节的“橘皮”车漆效果。

微信图片_20230506092128.JPG

我们也可以调整inner layer's normal(内层法线),做出不同强度的金属颗粒效果,打造车辆表面的不同的磨砂质感。

微信图片_20230506092129.JPG

以此类推,通过增加不同的法线贴图,我们可以实现不同的材质效果。

2.2 有吸引力的外观

除了法线贴图,我们也使用了其他贴图来打造多样化的车辆外观效果。

颜色贴图(Color map)可以影响不同图层的高光颜色(Specular color)效果,通过调整参数,我们可以实现不同的效果,参考下图。

微信图片_20230506092130.JPG

除了静态材质效果,我们也在动态效果上做了研究。通过在不同通道上设置不同的参数,我们实现了各种 GhostWarp 和动态效果。还有更多的动态车辆效果,都是通过同样的方式实现的。

除此之外,我们还需要处理锯齿的问题。由于车辆表面是透明涂层材质,图像中的锯齿(Aliasing)非常明显。通常,我们会用时域超级采样抗锯齿(Temporal Super Sampling Anti-Aliasing,TSAA) 来解决这个问题,但是这么做成本比较高,因此我们需要更优的方案。

微信图片_20230506092131.JPG

有一天,我注意到了场景中的一个区域,由于它的四周非常空旷,锯齿状非常突出。后来我发现,成因是法线细节过多。于是,我的解决方法是直接去掉法线细节。结果锯齿也消失了!这种方法简单有效,我们打算把它应用于车辆上。

因为车身有着光滑的透明涂层,在某些部位同样出现了高光锯齿,我们用法线导数来计算出边缘的锯齿形状,也就是图上的白线部分。

微信图片_20230506092133.JPG

之后,我们增加了车身透明涂层(clearcoat)表面的粗糙程度,降低边缘的透明图层厚度,减少了物体表面反射高光的强度,就得到了这样的结果。对比之前的外观,显然处理过后的外观更为平滑。我们还烘焙了 AO ,将颜色信息存储在顶点中,改善了车门缝处的细节。

微信图片_20230506092134.JPG

2.3 正确动态光照

锯齿问题解决了之后,下一步就是处理动态光照。要做出好的车辆动效,关键在于环境反射和动态光照。如果要在移动设备上实现真实的动态光照效果,挑战比较大。

因此,我们使用 Parallax IBL (Parallax-Corrected Image-Based Lighting,视差图像光照)来改善环境反射效果,使用烘焙的SH(球谐函数Spherical Harmonics,简称SH))来模拟动态光源产生的反射效果。

与传统 IBL 相比,Parallax IBL 可以更好地模拟车辆移动时的反射效果,同时也能够兼容移动端。

但Parallax IBL 存在一些缺点,那就是图像精度不够,但是尚在可接受范围。我们需要沿着赛道精准放置大量 IBL probes (基于图像的光照探头),并且生成大量的环境贴图,从而进行优化。再将 HDR 格式转换为可压缩的 LDR (Low Dynamic Range 低动态范围)格式,进一步压缩图像大小。

现在我们可以在更低的纹理尺寸下获得更高质量的动态反射。但在夜晚场景下,效果仍旧不是很理想。

微信图片_20230506092136.JPG

如图所示,传统的动态反射算法只能模拟非金属材质的反射效果,对于金属材质,主要是高光镜面反射。

于是我们添加了一个车辆高光反射系统,使效果有了明显的提升。

微信图片_20230506092137.JPG

接着,将场景划分为网格。对于每个网格,我们使用3个 "half4" 向量来存储 3 个 RGB 颜色通道。每个通道保存不同颜色的第一层级SH,接着用这些数据来计算高光反射。

将颜色通道分开处理的好处是:将通道分离后,得到的颜色细节更多。添加基于 SH 的高光反射模型后,车辆会受到不同方向的光照影响。

而且,即使是使用第一层级 SH 系数,也可以给我们提供丰富的光照颜色。下图是方向性红色光源效果。在夜间场景下,车辆光照得到了很大改善。

微信图片_20230506092138.JPG

但是新的问题出现了,在白天场景下,由于添加了 SH 高光,车辆的亮度增加了。由于烘焙的 SH  和捕获的 IBL,场景的主要亮度来自天空环境贴图。此时,亮度是重复计算的。

微信图片_20230506092140.JPG

我们使用 IBL 来平均亮度,对 SH 反射进行衰减处理。可以看到,白天场景下,车漆变得更加自然了。

微信图片_20230506092141.JPG

经过上面一系列步骤,游戏中车辆渲染效果大大改善。

三、场景优化

在车辆渲染优化中,我们已经预留出了一定的包体资源量,因此场景优化的目标是在严格的资源限制下实现良好的视觉效果。

3.1 全局光照优化

首先,我们需要确定场景渲染中最重要的部分。游戏中,车辆在比赛时会快速移动,全局的光照表现往往比模型或场景上的小细节更加重要。

下面的两张图片说明了光照的重要性。左图是LDR(Low Dynamic Range,低动态范围成像)的天空效果。右图则是HDR(High Dynamic Range,高动态范围成像)的天空效果。显然,右边的光照效果更符合现实环境。

微信图片_20230506092142.JPG

又比如,下图中的山体面数很低,但在高质量的光照下,仍然感觉画面非常真实。

微信图片_20230506092143.JPG

然而,很多手机并不支持 HDR 成像的纹理压缩格式 ASTC(Adaptive Scalable Texture Compression,自适应可扩展纹理压缩)。于是,我们使用 Modified Reinhard curve(修改后的Reinhard曲线)将 HDR 图像映射到 LDR图像格式,在shader中对其进行解码。

幸运的是,这种编码方式取得了较好的效果,我们获得了不错的光照表现。

微信图片_20230506092145.JPG
“假HDR”中呈现的高质量天空效果

请注意上图中,云是Sky Map上的内容,看起来十分逼真,那我们为什么不试着在Sky Map(天空贴图)上做更多的尝试呢?在下方这张山景图中,远处的山脉其实是被烘焙到Sky Map上的内容!通过这种方式,我们无需额外的资源消耗,就可以获得逼真的远景。

微信图片_20230506092146.JPG
天空球打开和关闭对比

3.2 人眼自适应

另一个关键点在于人眼自适应(eye adptation)。

开启自适应亮度调节后,可以使得场景在不同亮度环境中保持合理的曝光。

传统的自适应亮度调节做法中,降采样过程会导致大量的内存加载和存储操作,非常消耗移动设备的处理资源。

由于我们的游戏场景中没有动态光照, 所以某种程度来说,曝光值是静态的,且可以被预计算的。所以我们决定进行离线降采样处理。

经过烘焙后,我们得到了预期的静态场景渲染结果。

微信图片_20230506092147.JPG
自适应亮度调节前后对比

但由于自适应亮度调节的关系,游戏特效会出现曝光过度的情况。我们添加了一个亮度系数调整了视觉效果亮度,让整个场景更加和谐。在不同的曝光下,亮度系数也需要不断调整。我们选取了一些常见的特效场景,手动进行了调节。

微信图片_20230506092149.JPG

将数据拟合成多项式曲线(Polynomial curve)后,我们得到了最终结果,特效没有受到自适应亮度调节的影响,场景的亮度也显示正常。

微信图片_20230506092150.JPG

3.3 树木的优化

然而,我们又碰到了新的问题。

这个照片取景地是杭州西湖附近的北山路,也是我们游戏中设计的第一条赛带,沿路有数十棵树。一般情况下,我们会使用复杂的3D树木模型来绘制, 但这么做就容易出现过度绘制的问题。尤其是当车速过快,通过时间大概只有 10 秒,因此我们要用更为经济的方法来对这些树木进行渲染。

微信图片_20230506092151.JPG

首先,我们要了解设计的树的类型。我们想要枝繁叶茂的树林,而不是单棵细节丰富的树。

因此,我们尝试使用Billboard(广告牌)应用于树的渲染,用四种贴图来保留光照特征,但是要为 Billboard 生成法线贴图有些复杂,让我们来看看生成过程。

首先,我们需要修改模型树的法线。原始模型的树叶法线是混乱的,我们希望法线能够沿着树状结构分布。

于是我们将传统法线(Traditional Normal)和形状法线(Shape Normal)结合,以获得细节丰富和完整的高多边形法线。

微信图片_20230506092153.JPG

然后,我们将混合的法线信息烘焙到 Billboard 上,以创建 3D 模型,从而计算 Billboard 的动态阴影。下面的四幅图像显示了同一 Billboard 在不同相机视图中的着色结果。

借助Billboard,我们实现了丰富的树木,同时减少了绘制次数以及更低的性能消耗。

微信图片_20230506092154.JPG

虽然我们使用了四种纹理来维持原始模型的形状,但仍然会有信息的丢失。我们想要通过 AI 计算来获得与原始 3D 模型相同的细节。

我们使用了高多边形树和离线渲染器来获得作为作为基准的逼真渲染结果(ground truth)。接着使用可微分渲染(Differentiable rendering)来找到最接近基准结果的贴图。

下方的视频是拟合的结果。左边是基准结果,右边是我们的 AI 计算结果。新方法只需要消耗两张贴图。而且你可以看到,两个结果基本没有差别。

接着,我们使用简单网格来模拟画面远方的树,在正常游戏场景下,显示效果也很好。

下方左图是我们游戏的截图。我们结合少量的树木模型和大量的 Billboard 生成了茂密的丛林。右图是 Overdraw(绘制过度)分析图。深蓝色表示绘制一次,浅蓝色表示绘制两次,可以看到大部分树木区域只绘制了一次。

微信图片_20230506092156.JPG

四、纹理压缩

我们前面提到的技术包括用 SH 计算车漆的高光反射、使用 IBL 纹理计算环境反射、使用光照贴图在场景中保存烘焙的全局光照(Global Illumination,GI),以及通过自动亮度调整来获得更好的光照。我们还有潜在可见性数据(Potential Visibility Data),虽然在本次演讲中没有提到,但是在游戏中也有应用。很明显,所有这些技术的关键词都是烘焙。

烘焙会导致包体过大。游戏6GB的包体中,超过 80% 的内容都是贴图。

我们检查了贴图内容,以下面为例,包体里包含 PBR 渲染所需的三张贴图。我们注意到这三张贴图非常相似,都包含了Window (具有透明度的表面区域)。

微信图片_20230506092157.JPG

其次,它们都包含了三角形。法线贴图上的三角形虽然不明显,但确实存在。

微信图片_20230506092158.JPG

我们的想法是,既然这些 PBR 参数都存在相同部分,那么相同部分其是冗余数据,如果我们能减去相关性,就可以节省空间。

我们用 PCA (主成分分析)来消除相关性。我会通过一个简单的二维空间示例演示 PCA 的工作原理。

假设我们有一个包含许多红点的XY 平面,我们需要用二维变量来描述这些红点。但是如果我们能找到一条穿过所有红点的直线,就可以将数据从二维空间转换到一维空间。而 PCA 的作用就是找到这条直线。

再回到我们的问题,我们可以将 PBR 纹理表达为 9 维向量,PCA 的任务是找到最佳4维平面对9维向量进行拟合。

微信图片_20230506092200.JPG

与参考图相比,PCA 的场景亮度更高。所以我们在输入中增加了权重,并通过机器学习来确定权重。

微信图片_20230506092201.JPG

最后,通过使用压缩图,我们获得了与原始图像相近的PBR参考图结果。

微信图片_20230506092202.JPG

本次演讲主要是介绍我们团队是如何从三个方面入手,来打造90帧高质量写实手游。这三个方面分别是车辆、场景,以及压缩技术。

首先,车辆对赛车游戏的重要性不言而喻,只有高品质的车辆才能打造高品质的赛车游戏。

其次,在资源极其有限的情况下,我们仍旧实现了良好的光照和写实的树木。

最后,我们通过压缩技术减小了数据的存储和传输消耗。

以上就是今天演讲的内容,也希望我们的经验能对你有所帮助!

相关阅读:

【GDC2023干货分享】移动平台上的软光栅遮挡剔除方案
【GDC2023干货分享】创新的用户获取模式——直播引流探索
【GDC2023干货分享】开源软件在引擎开发中的帮助

文/蛋蛋&Baoyong

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2024-5-7 06:38

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表