我正在走我的行走机器时写这篇文章。由于我有ADHD,所以如果运动不足以在早上做第一件事,也就不太可能发生,哈哈。我在亚马逊上花了一把便宜的行走机,然后将我已经设置好的无级限升低的桌子作为我的电脑外接鼠标设置好,并将我的鼠标和键盘设置好。在我的显示器上,监视器略向上倾斜,这样我就可以看他们了何必在家里,而不是到健身房或禅修室呢?我过去会在几个月后就放弃加入的。我们开发的游戏是要在 console 上运行的,所以我们需要考虑console 的限制。那些系统关心的是你向GPU 发出多少个单独的绘制请求而不是你绘制多少块三角形。

我曾经在PAX East上将游戏展示给人家看之前,已经走了2-3小时。但现在我又开始走行走机了,身体已经恢复了。

上次我展示了游戏中的新农田背景。然而,之前从未提及的游戏中的新背景还有一个谜题。

GPU 实例化:2,583 种植物减少到 3 绘制请求

我的3D 设计师在去年11月或更早之前就开始向我发送terrain 模型的测试,我当时的3D 设计师实际上就是游戏的粉丝。他曾经在差不多两年前为了他自己的理由重新设计了游戏LOGO,并非我请他干的。他一直在不断地将背景中的各样元素添加进来,总之他现在在游戏开发中有一个非常重要的作用。

他还想尽可能地添加背景细节,以至于我担心GPU 和性能问题。但是在上星期之前,我曾经花了2-3小时的时间去玩游戏,而且又玩了几天之久之后,我才恢复了一点身体。

GPU 实例化

如果每种植物都是一个单独的物体,那么它的GPU 实例化会变得很难。它们的大小不同,形状不同,并且它们之间互相之间根本没有任何关系。唯一能做的就是简单地将一块terrain 的 3D 网格绘制3次。但是,由于它们都是相同的材质,可以应用GPU 实例化。但是,它并不是那么简单。我需要将这些不同形状的植物组合成为一个单独实例。然后我需要让每个实例中植物的叶子和枝条能实现独立的运动。

我花了几个月的时间让3D 设计师为game 中的各样场景创造详细的环境,然后我让他在每周的时间上继续优化。我们为game 设计的新背景是基于海洋的区域,我们需要在其中实现海浪,让水波能够有一个更美的感觉。游戏背景里的草丛是非常多的。在整个背景中,都有几千个植物,这些植物之间都互相有着不同的位置。

之前在PAX East 上展示的游戏背景中的全部新元素都非常令人期待。游戏的背景包括temperate 土地、海洋、洞穴、岩石、和城市区域。在这些区域中,有很多地方都需要各种元素才能让它们更加有生命感,才能让背景变得更加美丽。

背景和问题

在设计背景的过程中,有一个问题是显而易见的。之前的背景中的所有元素都是一个个的实体对象,每个元素需要一个独立的绘制请求。那么在背景区域中,有这么多的植物,这些植物所使用的资源会不会给GPU 造成压力,而让游戏不能顺畅地运行?我们是从一个背景开始的,而不是一个个单独的元素。所以我需要将所有这些元素用一个GPU 实例化的方式来呈现。

创新的解决方法

我最先尝试了标准的GPU 实例化。它很有用,因为它可以减少绘制请求的数量。但是,这种方法并不是最合适的。因为plants 的形状是不同的。这意味着它们的网格也不一样。但GPU 实例化需要所有对象具有相同的网格。那么我就不得不重新考虑这个问题了。突然间,我想到了一个很简单的解决方法。

以前,我认为能看到的所有元素都是重要的。但实际上,并不是所有的元素都是重要的。例如,在game 中,用户是不能与树的叶子或者草叶互动的。那么这些元素为什么不能被合并成一个单独的实例?因为它们都能被使用相同的纹理,而且它们的形状非常相似。

但另一方面,如果这些元素是可以互动的,那么它就不适合GPU 实例化。因为每个元素都有不同的网格,网格的数量会非常的多。那么,我决定利用一种叫做merge 的方法,将植物的实例一起绘制为一个实例。那么在这种情况下,我需要确定每个树的实例要么只有树木的实体部分,要么只有叶子的实体部分。

那么我需要根据植物的类型来选择这三种合并方法。我已经编写了一个工具,它能够在1秒之内对所有树的叶子与树木分离。那么树的总数会减少。但是,这样就能保证,我的3D 设计师能够合并成一个实例的树与背景中的叶子不产生问题。同时,GPU 实例化能够减少GPU 的负担。

那么剩下的问题是如何让每种植物能够独立地sway。当植物被合并成一个实例时,它们就不能像以前一样sway了。当用户走过背景区域时,他能够看到很多植物的叶子。那么为什么用户不能看到sway?如果植物的顶部能够sway,那么它的底部也必须能sway。那么sway 是如何实现的?

解决问题的方法

那么如何实现每个植物的sway 呢?我写了一个shader,它能够让植物的顶部能够sway。但是,一个问题是,它需要一个很好的解决方法才能让每个植物sway 不像其他植物一样sway。那么我又怎么解決這個問題呢?

那么最后,我写了一个shader。它能让植物sway。在写这个shader之前,我决定让植物的sway 与风有关。那么我让所有的植物能够向不同方向sway。但是,我又需要让植物之间sway 的方向能有所不同。那么,我发现一个解决方法。

那就是将植物的sway 实现为一个sin 的曲线。那么这样,植物sway 的方向就能具有了自然的感觉。那么,植物sway 的速率就能有了自然的感觉,而且植物之间sway 的速率能有了自然的感觉。

我还让植物sway 的速率与实际植物的大小相关。那么就不会有瘫痪的效果。如果植物很小的,它sway 的速率会很快。那么,植物sway 的速率会有一个自然的感觉。

那么,最后,我写了一个script让植物sway 的速率能根据用户的位置改变。那么用户能够看到植物sway 的速率。

结果

那么我让植物sway 后,我跑了个测试。那么,这次我的测试表明,每个植物sway 的效果非常好,它能够像实际植物一样sway。

那么,最后,我跑了个测试。那么,这次我的测试表明,我之前写的工具能够让植物sway。那么,我们就没有一点问题了。

那么,使用GPU 实例化减少了绘制请求的数量。那么减少GPU 的负担,GPU 实例化就变得非常有用。那么,能够减少GPU 的负担,GPU 实例化也就变得非常有用。

那么,能够使植物sway 有了一种自然的感觉。那么使植物sway 有了自然的感觉,植物sway 能够有了一种美丽的感觉。那么能够让植物sway 有美丽的感觉,植物sway 也就变得非常有价值了。