GDC翻译:Ghost Recon Wildlands 中的地形工具与技术

原视频链接:https://www.gdcvault.com/play/1024029/-Ghost-Recon-Wildlands-Terrain
带注文PPT链接:https://www.gdcvault.com/play/1024708/-Ghost-Recon-Wildlands-Terrain

介绍

在这里插入图片描述
大家好,欢迎来到这里。今天我们将讨论《Ghost Recon Wildlands》中我们创建的地形,以及我们为此创建的工具。首先,先介绍下我们自己。

在这里插入图片描述
我的名字是Guillaume Werlé。我是一名图形程序员,负责 Ghost Recon Wildlands 的地形技术。我喜欢富有创意的编程。在业余时间我是 demoscene 社区的活跃成员。

在这里插入图片描述
我的名字是 Benoit Martinez。我是 Lead Artist 和 Technical Art Director。我负责关卡美术团队和PCG / Houdini 团队。我于 2011 年加入育碧在 《GhostRecon: Future Soldier》工作,然后在《Ghost Recon Wildlands》项目一开始我就成为核心团队的一员。Wildlands 制作期间我成为了 2 个男孩的父亲,过去 4 年我一直很忙。

在这里插入图片描述
今天我们将讨论地形、技术、工具。

实现的效果

首先我们先看一段视频(https://vimeo.com/207479108):
在这里插入图片描述
好的,这就是我们今天所要讨论的。这个巨大的地形。它是育碧有史以来最大的动作冒险开放世界。
在这里插入图片描述

它有很大的多样性,11种不同的生态环境,每种都有其独特的成分。
在这里插入图片描述

湖,河,小溪总共有16平方公里。
在这里插入图片描述

还有很多Instance。有许多树、灌木、岩石。当然,它们都是由程序化工具创建的。
在这里插入图片描述

还有很多路、偏离轨道的小径、公路护栏、交通标志、贴花。它们都是生成的。
在这里插入图片描述

遍布世界的完整铁路网。
在这里插入图片描述

游戏中超过 200 个特定地点:营地、地标、前哨和 58 个完全程序化建造的村庄。
在这里插入图片描述

总览

在这里插入图片描述
今天我们要解释的就是,这一切是如何开始的。总结来说:

  • 第一个原型——我们是如何在 2012 年开始的
  • 地形工具——Guillaume 将讲述他创造的工具
  • 然后他会提供有关地形渲染的所有细节
  • 程序化工具——我(Benoit)将讨论环境创建的工具和管线
  • 然后我们将总结本次演讲

1. 第一个原型

视频:https://vimeo.com/207479227
在这里插入图片描述
第一个原型五年前就开始了。我们是一个非常小的团队,大概四个美术师,一个图形工程师。在 《GhostRecon Future soldier》之后,我们开始尝试更大的地形。我们使用真实世界的数据,然后用World Machine 细化了 DEM 文件。然后在 Houdini 我们创建了一些工具来:

  • 自动创建带LOD的 tile mesh。
  • 根据坡度、高度、粗糙度和其他来自 World Machine 的 mask,如流程图,来定义 splatting mask 用来分布材质。
  • 使用规则来定义植被的散布点。规则包括坡度、高度、材质、密度、树之间的距离等。

我们这样一个小团队构建这样一个原型只用了数个月,这在当时是个很有说服力的测试。给了我们足够的信心。

在这里插入图片描述
为了构建原型,我们使用了旧引擎YETI。尽管我们设法取得了一些不错的成绩,但这并不符合我们的雄心,因此我们最后选择了来自刺客信条的 Anvil。
就这样,一切开始了。

原型帮助我们认识到了两件事:
在这里插入图片描述

我们必须改进我们的地形工作流程。编辑网格,然后在编辑器和 DCC 应用程序之间来回是不切实际的。我们需要一种地形技术,可以让美术师轻松编辑,而在运行时又有很高的效率。
Houdini 被证明是灵活且高效的,它让TA可以在没有工程师的帮助下独立创建工具。

2. 地形工具

下面,请 Guillaume介绍下地形工具。

2.1 GPU雕刻

在这里插入图片描述
我在 4 年前加入了育碧和 Ghost Recon 团队。
在开发这个原型仅仅几个月后,我就开始研究地形编辑器。
在这里插入图片描述
在这几个月里,美术团队开发了一个基于 WorldMachine 的高度图生成管线。
地形编辑器的主要目标很简单,就是将这张没有任何材质信息的大分辨率高度图作为输入,并将其转化为:
在这里插入图片描述
这样一个逼真的拥有大量丰富性的世界。
这张截图是一个玩家在上周的公测中拍摄的,几乎说明了我们想要实现的目标。
我们希望在近距离观察时可以看到大量细节,而又有令人印象深刻的远景,并且两者之间可以进行无缝过渡。
在调整画质时,像素比率可以达到每厘米 10 纹素和每 2 厘米 1 个三角形。
玩家可以去游戏中的任何地方——这意味着这种质量水平必须在全世界保持一致。.

在这里插入图片描述
我们在编辑器中开发的第一个功能是高度图雕刻工具。
出于多种原因,我们想在 GPU 上执行此操作。首先是因为它很快。我们需要能够编辑地图的大片区域并单击一下即可 “盖上” 整座山。也因为这是在编辑时获得准确视觉反馈的最佳方式。
高度图和画笔在一个 floating point render target 中混合在一起,游戏着色器可以直接使用它。

在这里插入图片描述
制作游戏是一个迭代的过程。
我们需要一种在游戏中尝试新想法的方法,并且可以在不浪费太多时间的情况下恢复它们。
所以我们想出了的概念。
World Machine 输出保存在我们所说的 Base 层中,而编辑器中所做的每一次更改都在 Macro层中。
当编辑的结果不令人满意时,Macro图层内容可以很容易地被擦除,以恢复到高度图的原始状态。
下面一个展示高度图雕刻工具的简短视频,该工具展示了“复制/粘贴”画笔和“擦除”画笔。(https://vimeo.com/207479248
在这里插入图片描述
上面视频首先尝试扩展了这个山脉,最后擦除了修改的部分。

在这里插入图片描述
我们还为 houdini 生成的修改创建了一个专用层。这是一个极其重要的特性,Benoit 将在第二部分的演讲中对其进行描述。简而言之,TA使用 Houdini 可以对地形进行完全的读/写控制。
最后一层是包含所有关卡设计相关更改的层,它们无法用Houdini完成。

2.2 材质分配

在这里插入图片描述
现在我要描述下我们的材料分配步骤。

在这里插入图片描述

正如我之前已经说过的,我们想要一个具有一致质量水平的逼真世界。
着眼于地图的大小,我们很快得出结论:手动绘制所有内容是一个糟糕的主意。
我们需要一个半自动过程。所以我们决定程序化生成材料分布。

在这里插入图片描述
为了在雕刻时能对地形有个更好的理解,地形编辑工具已经根据法线方向对高度图进行了着色。
从远处看,这个简单的规则几乎足以产生令人信服的山脉。
因此我们决定扩展这个概念。

当满足规则的所有条件时,我们将显示有全部特征的材质,来替代纯色。
在这里插入图片描述

我们设计条件的依据是:拓扑、噪声、或是其他可以在像素着色器中实时计算的简单kernel。

这是我们材质设置的编辑器的截图:
在这里插入图片描述

正如你所看到的,《Ghost Recon》中的每个设置都由多个规则组成,一个一个得叠在一起,它们会从下到上进行计算,然后将显示在计算期间成功的最后一条规则的材质。

在这里插入图片描述
在这个视频(https://vimeo.com/207479253)中,我们以一个纯色开始,然后不断调整其他材质层的参数直到感觉合适。

在这里插入图片描述

我们现在只需单击一下即可以整个设置来绘制,但仍然需要大量工作才能让过渡看起来自然。

我们决定扩展“规则”的理念来驱动画笔的不透明度。下面的视频(https://vimeo.com/207479279)展示了其效果:
在这里插入图片描述
材质分布的结果随后被保存到 2 个纹理中。

我们称第一个为“splatting”。 它包含了材质的索引:
在这里插入图片描述
第二个称为“Vista”纹理,看起来像谷歌地图中的截图。它被用作渲染远处时的Albedo:
在这里插入图片描述

然后所有东西被切成小块,并压缩成四叉树。
在这里插入图片描述

这种简单的结构对于 LOD 生成和 patch culling 都非常方便。
对于四叉树的每个节点,可以根据剔除结果和到相机的距离由加载线程流入或流出。

3. 地形渲染

3.1 材质

在这里插入图片描述
在开始讲渲染之前,我先快速描述下我们的材质。

《Ghost Recon》 中的每个材质都符合 PBR 标准,由使用 ZBrush 和 Substance 创建的几种高分辨率纹理制成。
在这里插入图片描述

每种材质还包含了置换贴图:
在这里插入图片描述

基于曲面细分的置换帮助我们获得了我们在开发原型时所期望的“次世代”的效果。
由于我们对效果要求很高,我们愿意在其中投入大量的 GPU 时间。

在这里插入图片描述
很多地形渲染器会使用 4 种材质,如果世界中只有一个设置,这通常就足够了。
但我们的世界有很大的多样性,在制作结束时,我们在地形上共有 143 种独特的材质。
在开始时就加载所有这些材质并不是一种可行的选择。

在这里插入图片描述
我们将玩家周围 32 个最近的材质缓存在一个纹理数组中。
然后使用一个 indirection table 将全局的 splatting 索引转换为本地缓存索引。
渲染前景时,我们直接从这个缓存中采样纹理。

3.2 前景渲染拆解

在这里插入图片描述
听完这些后,我将描述我们的渲染步骤。这是前景着色器的最终结果:
在这里插入图片描述

为了让你对内部发生的事情有一个高层次的概述,我将逐步分解。

我们从获取 splatting 索引开始,我们将其翻译成本地缓存索引,然后从缓存中采样所有 pbr 纹理:
在这里插入图片描述

我们使用双线性插值再次执行此操作 3 次,以便在所有材质之间有良好的过渡:
在这里插入图片描述

为了避免拉伸,我们对斜坡使用了双向投射:
在这里插入图片描述
这意味着我们必须做两次计算,每个轴一次。

在这里插入图片描述
第一个版本的着色器在效果上令人满意,但是性能上却太耗了。太多的纹理采样操作与混合操作发生在像素着色器和Domain着色器上。由着色器导致的高寄存器压力,导致了一个很低的 wavefront occupancy。
我们需要更简单的东西。

之后我们在寻找优化的可能性。
在这里插入图片描述

我们注意到,那些完全平坦,和完全倾斜的面,并不需要混合那么多不同的材质。因此,我们的思路是为下面几种情况制作特别的着色器。

第一种情况(平坦的地方),取四个材质,做双线性插值:
在这里插入图片描述

第二种情况,斜坡。需要做双向投射:
在这里插入图片描述

最后一种情况,过渡区域仍旧需要做全部的运算:
在这里插入图片描述

最终:
在这里插入图片描述不过,将地形切割成独特的小块的方式,从硬盘空间的角度来说成本太高。所以我们的方案是在运行时做这件事:只要视窗中出现了它们就使用计算着色器来生成。

这种方式很大地优化了我们的性能。现在大约80%的地形会采样4个材质而非之前的12个。

这时,我们很关心另一个挑战:道路网。
在这里插入图片描述
在运行时生成它们听起来会是一个技术上的噩梦。但存储在磁盘上它们的空间也会很大。我们决定将道路直接雕刻到地形上而非使用传统几何体来表示,然而这个技术也有一些问题,比如廉价的材质过度,和明显的细节匮乏。

屏幕空间贴花看起来不错:
在这里插入图片描述

但是它性能太差了,有太多overdraw:
在这里插入图片描述

因此这个方案被否定。另一方面,它也不能影响拓扑结构。

3.3 虚拟纹理

在这里插入图片描述

在我们的情况中,虚拟纹理看起来是一个很好的优化方式。
在这里插入图片描述

将材质混合以及所有贴花投射都预计算到一个图集中,这样就可以大大减少纹理采样的数目了。虚拟纹理已经成功在很多其他作品中应用了,我相信在GDC这里的大家都很熟悉它的概念,因此我就不说太多细节了。

然而就像其他渲染技术一样,虚拟纹理也伴随着一些不利条件
在这里插入图片描述

因此我们设法在以下几点改进了传统的技术。

在这里插入图片描述

最简单判断需要哪部分虚拟纹理的方法是:将场景光栅化到一个屏幕之外的表面上,然后在CPU中读取内容。这个操作成本很高,尤其是游戏运行在4K显示器上时。
而且,我们的地形着色器还有细分并显示了大量的三角形,使用更低分辨率的RenderTarget将会丢失太多的细节。
在这里插入图片描述
我们没有使用专用的 pass,而是在 gbuffer 的 pass 期间绑定了一个额外的 3D 纹理作为RenderTarget。
当我们渲染地形时,使用 UV 和 miplevel 作为输出的坐标,然后直接标记出虚拟纹理需要显示的部分。

在这里插入图片描述
之后,计算着色器解析纹理内容并记录缺失的部分。
结果(只有几个字节)之后会在 CPU 上读取。

在这里插入图片描述
我们的内容量很大。当以最高画质运行时,虚拟纹理显示的像素比率为 “每厘米 10 纹素”。如果预先计算和压缩,这将需要大约 2 PB 的存储空间。

在这里插入图片描述
所以我们决定在运行时生成这些内容。材质和贴花被混合在一起渲染在一个屏幕之外的表面上,然后被一个异步的计算管线快速地压缩。
而当帧与帧之间相似度较低时的情况则很难处理大量需要更新的图块,比如驾驶一个飞快行驶的车辆时会让帧率骤降。
The virtual texture update had to be time sliced across several frames,并且必须进行大量调整,以在“保持良好的帧速率”和“低延迟”之间找到合适的中间点。

在这里插入图片描述
我们成功地用虚拟纹理替换了我们昂贵的前景着色器。幸运的是,我们在前期制作的早期就​​做出了这个决定,因此我们调整了内存预算。
如你所见,以 1080p 运行游戏时,需要 200MB 的空间来存储图集。在原生 4k 中运行时,此预算增加到 1GB。

我想通过在 xbox one 上提供一些性能统计数据来结束这部分演讲。
在这里插入图片描述
这些是平均值并且在很大程度上取决于视角,但我们可以说大多数情况下,GPU 端的一切都在 8 毫秒之内。这 8 毫秒不包括 BC 压缩,因为它是并行运行的。

4. 程序化工具

4.1 程序化工具 —— 大方向上的选择

在这里插入图片描述
我要谈谈我们的程序工具。
它们是什么,它们如何工作以及它们背后的设计理念。
在这里插入图片描述
尺度

  • 工具需要能在一个大尺寸上工作,也需要能在局部工作。
  • “保持对最大的山脉和对最小的石头的控制”这是众所周知的,而对工具也是如此。

合作

  • 一个巨大的关卡
  • 两个地方的两个团队:巴黎和Bucharest

迭代

  • 我们需要有能力可以改变主意
  • 尝试新想法
  • 工具是一种数据:工具被创建和存储在世界中,就像其他实体一样。工具其实是一种可以生成它自己的实体的“元实体”。

最重要的是,我们需要在每天都保持世界是可玩的。

在这里插入图片描述

  • 工具是依赖于规则的:用户通过编辑参数和调整规则来生成内容。
  • 确定性:相同的输入产生相同的结果。
  • 离线:不在运行时生成东西,一切都是预先烘焙的。
  • Houdini:世界创建管线,以及所有的工具都是由Houdini创建的。
  • CPU:由于我们使用的是 Houdini,所以大部分工具都是基于 CPU 的(最新版本的 Houdini 可以更好地应用 GPU,但我们当时并非如此)。 但依赖 CPU 不是一个问题:CPU 很便宜,我们可以使用更多的 RAM,而我们的一些工具确实需要大量的 RAM!

在这里插入图片描述

Houdini是什么?

  • SideFX 公司开发的一款 DCC
  • 广泛应用于特效(但我们这里并非如此)
  • 我们使用它来创建场景

我们用Houdini干什么:

  • 原型:一个用来实验初期想法的好工具箱。
  • 工具创建:创建内容。
  • 预览数据 / 获得数据 / 压缩数据 / 优化数据

为什么使用 Houdini 而不是 C++ / GPU 工具?

  • 快速迭代
  • 没有编译时间:工具就是HDA(Houidni Digital Asset)。工具变动/修复BUG → 发布给团队 → 所有人立即可用
  • 性能? 当然,专用工具会更快,但 Houdini 的灵活性是无可匹敌的。

Houdini团队:

  • 1个TD(我)和3个TA创建了所有的工具并建立管线。
  • 30个“世界建造者”(关卡美术和关卡设计师)使用工具。

我们使用了SideFX的什么产品?

  • Houdini(DCC App) → 创建HDA工具。
  • Houdini engine → Houdini Core API 被集成到我们的游戏编辑器中,以便可以在编辑器中使用HDA工具。
  • Houdini Batch(渲染农场) → 在农场上计算工作。

地形实际上是其他一切的基础。 我们要做的第一件事是创建一个自定义节点来访问地形数据,这是一个地块(500m)的例子。
在这里插入图片描述
如你所见,我们有多种选择。这里我们只获取基础地形层。

在这里插入图片描述
上图是同样的地块,但应用了所有的层。包括手动雕刻图层(Macro和Micro),还有“生成层”比如道路。

在这里插入图片描述

我们有许多工具用来将不同的资产填充到世界上。工具不是直接创建几何体,而是帮助美术师为已存在的资产决定摆放规则。大多数处理摆放位置的Houdini工具只会返回:

  • 矩阵
  • 物体ID

https://vimeo.com/207489407
在这里插入图片描述
上面视频展示了工具创建的步骤,和它的快速性以及灵活性。

在这里插入图片描述

我们估计 80% 的数据是使用 Houdini 创建或操纵的,由于是基于规则的工具,所以可以保证它们的一致性。让大范围的迭代可以由工具进行,这样可以节省美术师的时间,让它们能专注于具有更大价值的且无法自动化完成的任务:

  • Consistent big picture
  • 赋予世界意义
  • 通过环境讲故事

4.2 从头开始说细节 —— 地形驱动一切

在这里插入图片描述

地形是第一个层,下面让我们讨论在这之上建立的其他层的细节。

提取地数据

“地形” 所蕴含的数据不仅仅只有是海拔和 splatting(纹理)。我们计算出很多非常有用的信息,可以在许多其他工具中复用这些信息。几个例子:
在这里插入图片描述

  • 根据高度我们可以提取粗糙度,检测波峰,这在放置岩石或植被时很有用。
  • 从河流、材质和一些特定对象中,我们可以定义湿度,然后将其用于植被规则或影响地面的高光反射。
  • 累计太阳的平均照射,我们可以得到一个有用的mask,来驱动植被和环境声音。
  • 最初的 flow mask 来自WorldMachine,我们用它来影响地形的纹理贴图。但是由于地形经过了雕刻和修改,所以我们还存储了一张最新的waterflow mask。

我们在农场上自动化了更新这些地形层的过程:
每次用户提交一些地形拓扑更改时,它都会触发农场上的重新计算。存储在服务器上的更新文件可以通过 Houdini 工具即时访问。 由于它是中间数据,可以随时更新,因此我们没有任何版本控制。没有版本控制和备份可能听起来很可怕,但我们在生产过程中从未遇到任何问题。

在深入了解我们工具的具体细节之前,先看一个简短的视频来演示程序化生成层:https://vimeo.com/207479343
在这里插入图片描述

  • 沿着道路生成的道路生成层。
  • 野外、植被、岩石中的路径。最后两块大石头是手动放置的,其他一切都是程序化的,包括河流的雕刻、水的mesh、流动场。
  • 甚至连村庄都是生成的,从地形修改到建筑物摆放。
  • 带有隧道和桥梁的火车轨道
  • 它在全局范围上保持一致地工作,连接所有道路,计算流图mask,放置植被和村庄。
道路

一开始最重要的是,如何定义道路。
在这里插入图片描述
我们无法想象我们需要手动指定所有的道路,我们队伍不够大。我们不是在制作一个赛车游戏,我们只是想做一个有一致道路网格的足够大的世界。

于是我们有了想要通过“寻路”来创建道路的想法。因为游戏中重要的是“你从哪走到哪去”,比如从一个地点到另一个地点,从一个定居地到另一个定居地。于是我们努力找出正确的寻路算法,尝试重现关卡设计师会在关卡中摆放道路的逻辑。另外,我们需要保持“一致性”,道路中每一处的角度最大会是20°~25°,我们对于道路设置有一套预设。而工具,也就是算法,总是会生成一致的结果并与其他工作相匹配,我们是一个完整的团队。

我们从中学到了一些。我们的第一版如下图。它挺有趣的,但是不够好。也许你想让它平滑一些,但是你不能这么做,一旦你平滑了,那么曲线就不完全贴合在地形上了。
在这里插入图片描述

最后,我们根据这篇论文 《Procedural Generation of Roads》(EUROGRAPHICS 2010),开始试验“加权各向异性最短路径”算法。关键在于不是朝 4 个方向看,而是朝多个方向和多个距离看每个方向。这正是我们所需要的:在这里插入图片描述
所以算法基本和之前一样,参数也一样,但是应用了各向异性,最终产生了上面的结果。

我们将“way point”放在地形上,然后就可以开始计算了。
而算法的参数和之前一样

当然,工程上还有很多的问题。比如我们需要让所有的路连接彼此,我们需要以地块为单位读取数据等等,最后要让它在农场中计算。

最后,我们获得了道路网络,它具有不同类型且是最小路径:
在这里插入图片描述
请记住,所有这些都是离线处理的。 计算时间不是(或不是真的)问题(计算 2km * 2km 地块大约需要 10 分钟)。

道路层 —— 数据意味着更多的数据

道路的输出为:
在这里插入图片描述

  • 道路轨迹:它还有其他多种用途,例如 交通AI 。
  • 地形改变:生成一个高度场纹理,用以改变地形。
  • Splatting:用于更新地形材质的mask
  • 桥梁:如果路径寻找算法表示“跨过河流” 是最好的/成本较低的方式,那么我们会允许它越过河流。

在这里插入图片描述
https://vimeo.com/207479385
以上视频是在一块地形上寻找路径和道路网络(没有小路径,只有主要道路)。

道路道具层

在这里插入图片描述
我们已经有了工具可以手动(译注:摆放曲线)创建贴花、电线、围栏和防撞栏。而当我们创建出一个完整且令人信服的道路网络时,我们意识到我们只需将道路网络中的道路轨迹输入这些工具就行了,无需手动放置(译注:摆放曲线)。

铁路层

在这里插入图片描述
铁路的工作方式与道路工具相同,使用路径,但规则略有不同。它的坡度更低,转弯更少且范围更大,因此需要更多的桥梁和隧道。
道路轨迹是一个隐式输入,因为铁路需要考虑道路不重叠(在某些情况下保持平行)并始终以 90 度角穿过以避免危险的交叉和潜在的交通问题。

在这里插入图片描述
https://vimeo.com/207479400
如前所述,一些工具(例如此处的桥梁工具)可以在独立模式下使用手动创建,也可以嵌入到更大的工作流中以自动创建内容。
注:桥梁和隧道由模块构成。即,没有创建新的几何体,它只是instance。

河流层

在这里插入图片描述
世界上有 16 平方公里的面积被水覆盖。它是一个独特的连续网格,被划分到地块中(每平方公里一块)。
水包括湖泊、河流和溪流。河流和湖泊是地形的主要特征,可以使用地形工具进行雕刻。另一方面,溪流数量太多了,它们使用寻路的方式将山顶连接到河流,然后河流连接到湖泊。
对于地形改变,我们定义了一些层级顺序。因此管线中,溪流在道路下方,但对于河流,我们更喜欢桥梁以保持河流的连续性。
由于我们为溪流(以及某些情况下的河流)生成了轨迹,因此我们可以重用它用于定义矢量流图的信息,然后将流图存储在顶点色中。

定居点层

在这里插入图片描述
“定居点构造器” 是我们最复杂的工具之一。
其输入是:一个中心、建筑物列表和一些参数。目标是为游戏生成完整的村庄。
获得一个稳定、可用的工具需要一些时间(花了一年),但我们最终达到了我们想要的质量。
我们设法尽早锁定程序化生成的村庄,这样美术师便能够手动为每个村庄添加细节。

https://vimeo.com/207479416
在这里插入图片描述

自定义场层

在这里插入图片描述
就像之前说的,“工具可以被连接在一起”。
“自定义场工具” 可以创建单独的“场”,它可以用作定居点的输入、指定特定摆放物的激活性、指定草,等等等。

岩石层

在这里插入图片描述
为了放置岩石,我们使用了传统方法:
定义放置的mask — 美术师可以直接在编辑器中预览mask,包括:

  • 放置规则适用的地方
  • 材质 — 遮挡 — 曲率 — 流动图 — 粗糙度 — postFilter

mask中将应用的创建规则:

  • 模型
  • 相对坡度的对齐
  • 比例因子
  • 密度 / 最小间距

在这里插入图片描述
如果需要,工具将考虑其他工具的结果,以消除与道路或建筑物重叠的石头。
结果并不会直接发送给编辑器,而是会生成点缓存数据,还会为每个石头生成VDB体积

植被层

石头的VDB,在这种情况下会被用来植被的排除,确保石头VDB中没有点生成。
在这里插入图片描述
基本上,植被工具的工作方式类似于岩石工具,但它仍然是一个具有自己的参数集的特定工具。
事实证明,那些复杂且多用途的工具,它们维护复杂且效率较低。因此在所有情况下,我们更喜欢拥有专用的工具。

在这里插入图片描述
我们可以在整个生产过程中改进工具。
为了避免每个可能的使用者都有特定的要求,我们决定每个工具都有一个 “所有者”。通常是一位美术师将与将要创建工具的TA合作。所有者也将为工具制作文档,以制作全面的用户友好型文档而不是技术文档。
我们还集成了预设支持,因此所有者可以创建规则集,然后大多数使用者只需重复使用现有预设,而无需完全理解和使用所有参数。

点缓存 —— 维护上千个工具与数百万个instance

在这里插入图片描述
减法工作流程:
将“程序化内容”和“手动控制”进行混合是非常复杂的。如果有人想要一个精细的手动控制,它应该只是手工完成。所有工具都支持使用手动定义的曲线输入或隐式输入(例如:从道路中排除植被)的排除区域。有了减法的工作流程,负责植被或岩石放置的艺术家不必考虑村庄、道路或任何东西。他们可以自由地为生物群系创建规则,而必要的排除会在以后的集成过程中完成。

异步更新:
我们需要保证一个始终可玩的世界,但这并不意味着它是准确的。这意味着,如果地形拓扑发生变化,我们不需要完全重新计算植被放置,大多数时候我们只需要确保没有任何东西阻挡道路并且所有东西都贴合地形就行了。请记住,所有这些工具都是独立使用的,不受其他对象放置的任何限制,而且它们也可以用于原始的基础地形。

我们还有一个“点缓存”。点来自于每个工具。

  • 编译器中的第一件事是根据地形检查instance
    • 将所有东西capture到地形(保留任何相对的地形偏移——想想半埋的岩石)
    • 删除程序化地形区域不需要的对象
      • 清除道路、河流、定居点等处的植被
  • 然后我们检查instance之间的相互关系
    • 桥梁和隧道会删除岩石
    • 岩石会删除植被
    • 电力线不能穿过树
    • 等等…
植被与岩石 —— 优化

由于我们可以在Houdini中访问所有数据,因此我们可以比“放置对象”做更多的事情。
在这里插入图片描述
在这里,我们检查对象密度(植被和岩石)并相应地平衡每个对象的 LOD 乘数。比如在一个非常茂密的森立里,你就可以降低一些LOD质量,这不会被玩家注意到的。

声音层 —— 不仅是视觉

除了视觉效果,我们还可以与声音设计师合作。
在这里插入图片描述

我们给了他们一个工具,可以根据物体的类型和地形定义规则以生成声音图。每种颜色都是特定环境声音的索引。

Python工具 —— 将所有东西粘结在一起

在这里插入图片描述
Worldbatch(世界批量化工具)有助于自动完成任务,或允许您随时更新世界使用的任何类型的数据。

Worldbatch 基于 Houdini python (hython) 并使用 “Hqueue” (SideFX公司的)作业分配系统在“构建渲染农场”上启动数据“作业”。一个作业加载 Houdini 资产 (.otl) 并根据需要设置参数并从该 otl 启动数据渲染过程。

它可以在UI模式下单独使用,用户可以直接从世界地图中选择他想要重新计算的内容,并将作业发送到自己的计算机上,或发送到渲染农场。

我之前提到过 Perforce 插件,当用户在 Anvil 中提交涉及地形的更改列表时,Worldbatch 也将自动启动,Worldbatch 将由命令行脚本启用,并将基本作业发送到农场。以确保即使地形发生变化,数据也是最新的。

程序化工具总结

在这里插入图片描述
我们四个TA,在经验不足的情况下,创建了145个工具,实现了完全自动化的管线,而且结果还不错。

这种方式强化了关卡设计师,让他们可以专注于最重要的东西,而不是一遍又一遍地做着同样的事情。

程序化生成不仅仅是视觉部分,还包括声音、游戏逻辑等等。

5. 总结

在这里插入图片描述
最后我们总结一下。
在这里插入图片描述
为什么我们要一块做这个演讲?因为我们是相同的目标,我们在做同一件事,虽然我们是工程师和美术师,但我们在制作工具的过程中实现了彼此的交流。

我们不讨论是GPU工具更好还是CPU工具更好,它们二者都有优势。比如CPU工具,我们有些工具需要64GB的内存,显然没法在GPU上运行(或许将来某一天可以?)

Q & A

Q:不知道我的理解是否正确,你的所有的实例都被放置在Hudini中的吗?如果是这样,为什么这不会对你的引擎造成巨大的性能开销?

A1:在游戏中,在一定时间内,我们在玩家周围设置了空间(好像是1公里?)来加载物体。 嗯对就是这样,我们并不是所有东西都在内存中,只是在工具计算时是在内存中的,在运行时,这些数据是在硬盘上。

A2:而且我们有很棒的实例化系统,我想你可以看到很远的一棵树(billboard),都是instance。


Q:我的问题是你们是如何在每次迭代中测试你们的地图的,我的意思是,它太大了,光走着就要。。。

A2:我们就是走着看啊(哈哈哈),或者开车

A1:我们有个 NightlyBuild(每晚构建),我们有个机器人每晚在游戏中检查性能、内存、丢失的资源。整个过程可能需要12小时,会在主机和PC上运行。然后第二天我们就可以看到一张图,其中有绿色的部分,还有提示帧率不足或内存不足的黄色部分,但是在项目的最后一切都是绿色的。

A2:当然,如此大的地图对于QA来说是个噩梦。但是程序化生成的内容大多数情况下都不会造成他打的问题,因为你控制着一切。当然,你的指标也会在变,所以程序化工具也会出一些问题,但是不是太多。

(后续没听懂。。。。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值