我正在使用马桶机写这篇文章。我有ADHD,所以如果我不在早上马桶开始,我根本就不会运动,哈哈。我在亚马逊上买了一个便宜的马桶机,将我之前用于鼠标垫的液体桌子抬高到与我的PC相差不多的高度,然后在上面放置我的鼠标和键盘。显示器稍微倾斜一些,以便我站在这里时可以看到。房子里的某个东西对于我来说比健身房和瑜伽要好,因为我通常会在几月后停止上健身或瑜伽。通常情况下就是这样。

在上周,我一直走路2-3小时,直到我去波士顿参加PAX东部展览会之前。但是现在我又恢复到之前那种状态了。

上次我分享了一些新农田地形的素材,但这里更有意思的是我之前从来没有提到过的新地形的问题和解决方案。

GPU实例化:如何将2,583棕榈树压缩到3个绘制命令

我的3D建模师上个十一月(或更早)就开始向我发送地形模型测试了。他对游戏有很强的兴趣,甚至在去年两年前就自愿重新设计了穹顶 Logo。经历了很长一段时间后,他已成为我在游戏中唯一活跃的合作者。他在游戏上工作到现在约两个年頭。在过去的两个月里,他一直是游戏开发中最重要、唯一(除了我之外)的活跃人士。

在今年三月份,紧接着我去了波士顿参加PAX东部展览会之前,他就发送了新地形的重建版本。我们花了很多个月讨论并筹备之后,这才完成了新地形。新的地形比之前有很多更多的细节,而且还包括了一个海洋带。每天,他都在不断地发送修复和改进。当时我很想在PAX之前就实现它,但并没有做成。今天,他还在发送背景的并动图层,每层都是不同的深度,后面都是桉树和橡树。

那么问题来了?

每个物体都是一个请求

每个游戏中的物体都是一个请求给图形卡,而且每个请求都会产生一个绘制命令。每棵花,每棵树,每个地上植物物体。”绘制这个。””好,看看这个。””好看这个。其中有2,583多棵树。

如果在不错的机器上,没有问题。但是我们也是用着Switch和其他低端机器的,所以我们需要在所有情况下都是很好的性能。低端机器对于实例化所做的各个绘制请求很感兴趣。这并不是关于有多少个三角形,而是关于有多少个物体(实例化绘制)的请求。

我正在看这个令人眼前的美丽地方的所有细节,那是我游戏缺乏的重要内容。然后我又在想,必须拦截他了吗?因为游戏无法处理所有这些。

那么我尝试着解决这个问题了吗?

绘图实例化

标准绘图实例化是第一个尝试。当你告诉GPU“这里是一张mesh,画2500个个体在全世界的不同位置。你可以尝试去画,画一个个体”。这本身很有效,但它要求所有原始geometry的完全匹配,而且所有植物都是不一样的形状。没有压缩到足够少。

但是这些植物完全没有物理上的交互作用。不能走到其上取走,踩到它们,什么都没有。这是所有植物没有互相作用的原因,可以实例化。这是为了为什么这些植物才能实例化。然而,这也导致了一个问题:我们仍然需要给它们各自的游戏物体及其脚本。

为什么不是吗?

实例化

这些植物没有互相作用,也没有独特的互相作用脚本。只有一些静态的信息,而那些静态的信息并不很昂贵。那么有可能把他们合并成一个大对象吗?因为每个植物的形状不一样,但当你把它bake到世界空间里之后,有关GPU来说,它们就只是一种对象了。它看起来更大一点,没有那么多vertices。

在下面提到了为什么合并植物是不安全的,因为它们的形状很不一样,但是现在每棵树都是两个部分:叶丛和梢桩。

合并它们?

我的工具写在Unity框架上,可以直接把它们合并起来。这将大大减少渲染命令数。现在我们可以在Unity底层进行优化了。

分割树

树需要物理分割,所以它不是合并树叶的对象。它需要跟踪每棵树的叶子的位置。在合并树叶之前,确保树梢和树叶是分开的。这是一个容易的任务,Unity中的一个工具可以做得到。

动植物

它们的形状都一样,每棵树叶是静态静态的,所以可以合并。只要不动,就不需要合并,但当它们移动起来时,却可以合并。

将植物合并

将植物的mesh都合并起来。将它们都merge进单一一个大对象。我们写了一个可以让Unity合并meshes的工具。在unity中,工具可以轻松的合并树的叶子,而不需要去改变树梢。这样也减少了cpu的使用,从而减少了渲染命令。

然后,选择你想要合并的植物,然后点击一下。就会发现树叶已经合并,但树桩不合并。

检测

检测树桩和叶子的变化。这使得我们知道哪棵树桩是静态的,哪棵树是交互的或者是否是静态的。

最后

我已经完成了这两个部分,将植物合并了。然后我创建了一个检测工具。在Unity中,可以一次性检测每棵树桩的类型,并将它们转移到合适的地方。然后我们可以确定哪个植物可以做成静态静态的植物,可以合并到一起。

风?

当所有植物都是单独的对象时,能够轻松地让植物随风而动。让每个植物都独立地随风而动。然而,一旦有超过1000个植物,实例化的技术的效果就不明显,然后就慢了。这是为什么必须合并植物而不让它们独立动起来了。

怎么才能做到这一点?

在这里有一个问题:如何让植物独立地随风而动。当每棵树都在独立地随风而动。那么在植物合并后如何让树叶子独立地移动。

在树叶子的前面,我将每棵树木都用一个“swing”值绘制。如果我说0我意味着这棵树动不了。1意味着能够随风而改变。如果每棵树在顶端和底端的swing值是不一样,这样就能产生不同程度的随风效果,而不是所有树叶在一起。

这样,就可以让植物随风而动了。

shader

然后我写了一个读取这些绘制值的shader,然后使用两个重叠的sin波函数来移动叶子。这两种函数的频率是不同的,这样就能产生风的感觉。有些树叶子也向右移动,而有些在向左移动,而有些树叶子的swing值并不完全一样。

我希望你能明白,我正在解释每个细节。让树枝和树叶子彼此独立地随风而动。

在树合并后的树叶子中,我们希望能让叶子保持随风的感觉。不能做到完全不动。

结果

最后的结果是,我把所有tree和植物都合并成一个对象。从原始的2,583多棵树的3,000左右的绘制命令变成3个对象。这是惊人的。这样就只有3个绘制命令了。我们之前的农田中,花朵在每个地面上都有,树的叶、树枝都有。但是现在是只有3个绘制命令了。剩下的就是让小植物的叶子都可以自由的在风中翩飞。

剩下的就是测试。

目前还没有针对Switch和其他低端机器去进行测试,只在正常机器上运行了。但从结果看来它表现的非常不错了。

最重要的是,在我们之前的游戏中,最重要的内容是有了。是的!

我没有测试Switch和其他低端机器,所以还有待去测试,结果已经让我很满意了。但是更多的测试是必要的。