【GAD翻译馆】天空传奇之无极群岛的渲染技术

发表于2017-09-19
评论0 3.2k浏览

翻译:徐明刚(日月靑争 )    审校:龚斌涛(建筑学概论)


天空传奇之无极群岛SkySaga:Infinite Isles 是一个目前处于内测状态的基于像素,沙盒,单人/多人探索和创造的游戏。它具有鲜明的审美、生动饱满的色彩以及复杂的光照。另外它还支持昼夜周期、天气系统、半透明固体的阴影,云,透明光照,体积雾,和许多动态光照。游戏中还设有各种各样的生物种类,从阳光明媚或冰冻的森林到炎热的沙漠和隐藏在雾中的地下城镇等等。

游戏的程序性、美术及对于光照技术的要求,产生了许多有趣的渲染技术挑战,我们必须要克服。


游戏引擎

该游戏运行在专有的游戏引擎Meandros上。渲染器的核心是token提交和处理系统。在Meandros上下文中的token是一个可以设置Direct3D渲染状态,像素着色器,纹理,提交drawcall等的单工操作。每个可渲染实体在提交token时都需要将其渲染成适当的token流,渲染器在缓冲区中对其进行收集和处理,以达到排序和避免冗余状态设置的目的,然后提交给D3D API。该系统的优点是它对缓存非常友好,因为tokens非常紧凑并且可以本地访问它们需要提交的数据。token系统与渲染器架构无关,可以支持传统的渲染方式或延迟渲染。

在高级阶段,token流(buffers缓冲器)属于管道阶段(Pipeline Stages),每个管道阶段实现渲染通道,如阴影通道,光照通道,后处理通道等。管道阶段之间可以连接起来,一个的输出是另一个的输入。

使用管道阶段系统,我们实现了游戏中用到的延迟着色架构。我们选择延迟着色而不是延迟光照或传统渲染的原因主要是由于我们不得不在游戏中支持大量的动态光照,同时还有渲染消耗呈几何量的增长导致我们不能多次渲染。在g-prepass期间,我们填充了一个4个方面渲染目标g-buffer,其中包含所有的材料和表面信息,以执行屏幕空间中像素的光照和阴影。

g缓冲区中,我们存储的数据如下:

  • 法线坐标XYZ和几何法线坐标XY
  • 深度XYZ –环境光阻挡
  • 压缩反射率XY – 发光 – 点亮标志
  • 金属 – 中规模AO – 光泽度

法线存储在视图空间中,我们将深度编码为3个通道,以便释放一个渲染目标通道供其他用途。环境闭塞项我们应用在使像素角和交叉点的小范围变暗上并让它在纹理中烘焙。中规模AO是我们用下面描述的光传播方法计算的环境遮挡。反射率我们使用这里描述的方法压缩成2个通道。

g缓冲区的布局使得我们能够在后面执行单独的屏幕空间(screen-space)通道以混合不同的材料属性,如后面将要解释的用于各种效果的方法。


材料和光照

传统的游戏通常依靠简单的光照模型,主要通过美术来驱动外观,即使用饱和的颜色,在纹理中烘焙光照信息等。在SkySaga中,除了支持动态的昼夜循环和大量的动态光照之外,光照条件在不同的生物类型之间变化也很大。 由于这些原因,我们需要能够很好地响应光照环境的材料。

我们尝试了各种光照模型,从游戏最初支持的平滑(非标准化)Blinn-Phong,到标准化,再到后来的GGX BRDF。 美工喜欢GGX镜面反应与较为平滑的衰减,所以我们最终使用它作为我们的光照模型。我们还使用反射率 - 金属度 - 光泽度(Albedo-Metalness-Glossiness)方式来支持金属和非金属,从而使反射率作为金属中的镜面颜色并将非金属的镜面颜色值固定为0.04

除了g缓冲区之外,我们使用64位纹理实现了HDR光照和阴影管道的所有渲染过程。

对于动态光照,我们支持单方向投影光照,用于太阳/月亮和许多点光源,其中少数可随时投影,具体取决于平台。

对于定向光阴影,我们在每个级联中使用了具有4级联和PCF滤波的标准级联阴影映射系统。在SkySaga的世界里,我们有可以在地面上投影也可在其他云上投影的云彩。由于云使用标准的实体阴影覆盖,使世界看起来非常黑暗,在一些生物群落中可能对比度相对较高,所以我们需要一个额外的“半透明”阴影解决方案。我们选择将阴影地图(shadowmap)分成两个通道,用216位深度值进行存储,一个用于实体,另一个用于半透明几何体。正如预期的那样,我们使用正常偏移映射对自我阴影恶化的阴影瑕疵产生的负面影响进行了改进。此外,对于透明几何,可以选择在第二个渲染目标中渲染颜色和深度。这允许来自半透明几何的彩色阴影以及彩色体积光束。


环境,环境光照和遮挡

为了避免平坦的阴影区域,我们采用了Valve提出的六轴环境光照解决方案。 这允许法线贴图在阴影中添加一些变化。六六种颜色用于驱动环境光照,从而使每个生物群体呈现出各种外观。

为了仿照全局光照效应并模拟中等范围环境遮挡,我们在CPU上创建一个像素体占据的3D阵列,并通过一些步骤将光传播衰减。 这样允许“开放”的空间,就像洞穴和门一样,接收到一些光。空间越多,环境光衰减到零就越快。在光传播通过之后,3D阵列包含达到每个像素的光量(被占用或不占用)。我们使用这些信息将中间环境遮挡物烘焙到像素的顶点并在光照计算期间使用。对于动态对象,顶点烘焙不可做选择,所以我们通过一个常数来对到达物体位置的光进行采样,并将其传递给着色器。这种“闭塞”信息对掩蔽效果也是非常有用的;正如我们稍后要解释的,我们用它来遮盖封闭空间的雪和雾。

为了向场景添加环境反射,我们渲染了一个包含云层,浮岛等滑雪元素的动态立方体图。为了接近光滑的反射,我们在生成后对立方体图进行模糊化处理,并使用它们的光泽度值将其应用于反射表面来选择模糊度。


渲染透明度

海水,瀑布和河流的形式是SkySaga的一大特色。通常透明度在延迟着色引擎中是向前的光,这样使光照成为问题,特别是对于无方向的动态光照。为了简化渲染器并使实体和透明表面之间的光照一致,我们选择将一层透明层存储在g缓冲区中,并将其与其余的(固体)几何体一起照亮。我们设计了透明度渲染系统来渲染任意数量的透明层,但是使用来自光照缓冲区的光照信息能观察到最接近的层,而定向光只能使剩余部分向前发光。

光照透明面为任何延迟渲染器增加了一层复杂性,但是其可以实现的结果和光照质量是值得为之付出努力的。

大多数后处理(postprocessing)效应依赖于深度信息的存在。由于alpha面通常不存储深度,因此正确地雾化它们并对其施加像景深这样的效果并不是微不足道的,因为它们的表面被认为属于它们后面的实体表面或者是Skydome。为了避免在我们的游戏中出现上述情况,我们使用大致的深度信息透明表面以延迟的方式渲染到单独的渲染目标。另外我们支持两种类型的延迟alpha渲染目标,一种是像水(海洋)这样的表面,它们需要被雾化并且具有景深,另一种用于一些不需要粒子效应的表面(大多数情况下,如果它们需要,那么我们可以写入深度信息,但边缘可能会出现瑕疵)。美工或者程序员可以轻松地选择通过alpha表面的渲染方式,以及如何影响后处理效果。


累积效果/贴花

游戏的程序性以及希望轻松地创建各种环境的愿望,需要拥有在程序上覆盖现有生物群落的效应以产生新生物群落的能力。为了增强我们的动态天气系统,我们向游戏添加了一个g缓冲区修正游戏通道,这样可以轻松积累积雪和灰尘,增加湿度以及贴花到场景中。该2D通道通过修改g缓冲区中的某些材料参数来改变场景的外观。

由于场景应用效果往往受到场景中物体的物质属性限制,例如我们不能将雪应用于发光面,或者我们不应该为了创造湿润的外观而使金属表面的反射率(其作为镜面颜色)变暗,我们选择在修改之前创建一个g缓冲区副本,并将其用作输入。然后我们可以通过有条件地混合正常情况,反射率,光泽度等的新值来添加效果。在我们的设置中,我们可以使用标准alpha混合修改除了环境遮挡以外的任何g-buffer属性。同样的方法可以用于“整体”效果,如雪,或局部效果,如贴花。

我们使用上述环境遮挡信息来遮蔽洞穴和建筑物的积累效应。这样做效果非常好,因为它可以随着环境光线的累积影响“衰减”。

来自Winter biome的以下场景展示了g缓冲区修正游戏通道的应用;地形上的雪,建筑物和道具完全应用到屏幕空间中。


后处理效果

游戏通常会严重依赖后处理效果来增强视觉效果。 在SkySaga中,我们实施了一系列后处理效果,如本地屏幕空间反射,体积雾,景深,BloomTonemapping

我们使用屏幕空间raymarching方法来产生局部反射,逐渐衰减到屏幕边缘,来避免由于丢失信息造成的伪影。为了填补缺少的信息,我们使用前面描述的全局动态立方体图。

为了增强游戏中的气氛,我们以类似于Toth的方式计算源自主动态光(Sun / Moon)的阴影体积雾。

地形的动态性和可破坏性使美工在局部放置边框(例如在森林,室内等中)改变雾的密度非常困难。为了在玩家周围创造光束,我们必须在整体增加雾密度,这会对生物群体的其他部分产生不利影响。为了实现局部光束,我们依靠已经在CPU上执行的动态“机箱(enclosure)”计算,以确定一个玩家是在室内还是室外。在室内时,我们会逐渐增加玩家周围的雾密度,使光束更加明显,这在实践中效果很好。

最后,尽管雾效果不是通过点光源来实现,但是通过模糊光缓冲器并施加到雾上来实现点光源散射效果。为了进一步提高效果,在模糊通过之前,我们添加阈值在主渲染目标中,其中包含光源本身的图像(其明亮的核心,在阈值之后)。在以下屏幕截图中可以看到火炬上创建的亮点。

我们的景深方法受到Morgan开发技术的启发。我们根据场景的深度计算和存储圆形的交错(the circle ofconfusion),并计算两层 - 聚焦前景和待模糊背景。我们根本不使用近模糊平面。为避免背景层颜色渗色,我们使用双边过滤器进行模糊化处理。我们使用场景深度通过在模糊背景和对焦前景之间线性插值来应用DOF DOF在我们的游戏中表现非常出色,使得背景元素变得柔软,画面清晰。

我们的泛光方法很简单,包括对主要渲染目标进行阈值处理,模糊结果并将其添加到主渲染目标。

最后,为了色调映射我们尝试了从ReinhardFilmic的几种方法。我们的美工觉得他们需要更多的控制来保持游戏的风格化和饱和度,所以我们最终使用3D LUT进行着色。这种方法包括通过如使用一些缩放操作将HDR图像转换为低范围的图像、拍摄游戏的屏幕截图、在其上粘贴身份查找纹理、并在Photoshop中操作它直到达到所需的视觉外观。然后提取查找纹理(LUT),转换为3D纹理,并使用原始颜色作为3D纹理坐标应用于着色器中的最终渲染目标。这种方法非常灵活,允许美工为每个生物群落生产不同的降色LUT,并实现非常不同的外观,例如在雪花生物群中去饱和,转变为蓝色,或增加阳光下的生物群落的饱和度和活力。


支持各种硬件配置

为了广泛支持个人电脑配置,我们投入了大量的精力来使游戏获得尽可能多的扩展。这是通过组合着色器和几何LOD(细节级别),树和像素块LOD的宣传系统实现的,这相当于使用距离改变像素大小。此外,我们简化了一些后处理效果,特别是那些不影响游戏性如体积雾,降低到平原的距离雾。为了减少像素顶点缓冲区大小,我们还使用贪心网格划分优化了体元几何,并且我们基于这种方法的遮挡系统减少了绘图的数量,这种方法适合于像我们这样的许多基于块封闭空间的几何布局。


未来工作

在本文中,我们简要介绍了SkySaga背后的渲染技术。我们描述的一些渲染系统随着时间的推移而不断发展和完善。此外,随着新的生物多样性类型被添加到列表中,例如熔岩世界或水下世界会出现新的渲染挑战。此外,Direct3D11端口正在计划支持下一代系统。

免责声明:

这些系统仍在进行中,可能并不全部存在于上线游戏中,或者可能在游戏中看到之前进行更改。这个帖子最初出现在这里,经许可复制。

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

标签: