使用Megascans、SpeedTree和UE4制作程序草

介绍

我叫 Karsten Malmquist,我是瑞典马尔默 Ernst&Borg 工作室的环境艺术家。我毕业于马尔默的一所名为 The Game Assembly 的游戏开发学校,我曾在 PortaPlay 和 Star Vault 担任 Mortal Online 2 的实习生。

实时程序草项目

几个周末,我一直在摆弄这个项目。它最初是尝试制作景观材料,后来变成了更大的东西。在这一点上,这是我想在程序上生成整个生物群落的更大项目中的第一个“里程碑”。对我来说,这几乎就像在 3D 中绘制空气一样!

Megascans 到 SpeedTree 工作流程

我创建资产的工作流程通常从浏览 Megascans 库开始,因为我总是想知道我可以使用哪些资产。在浏览时,我尝试大致了解哪些资产可以开箱即用,哪些资产可以修改为可用于我的项目的内容。在这种情况下,Megascans 库有很多可以使用的草模型,但是看到它们在三角形上比我想要的有点过于密集,我决定制作自己的集群。

知道我要制作自己的草丛后,我开始将 Megascans 的一些不同草图集带入 SpeedTree 以寻找合适的草丛。我使用了 SpeedTree,因为它提供了一种非破坏性的程序工作流程,您可以在其中改变几乎任何事情的想法,而无需从头开始重做所有事情。我使用扫描图集的原因是,您可以尝试许多不同的漂亮图集,直到找到合适的图集,而不必花费大量时间制作好的高多边形。

在尝试不同的图集纹理时,我得出的结论是,单个草股之间间距更大的图集通常看起来更好。当我使用草线之间紧密间距的图集时,整个纹理随着 mipmap 开始混合在一起,打破了草由单个草线组成的错觉。

为了在 SpeedTree 中创建草丛,我首先通过在图集顶部放置顶点来创建卡片网格,并确保我为不同的 LOD 分配了适当的三角形计数。我现在不太担心确切的三角形数量,因为我知道一旦我将集群带入虚幻引擎并查看它们的性能,我将不得不重新审视这一步。

设置卡 LOD 后,我可以开始制作集群。为此,我首先使用 Zone 节点来定义草可以生成的位置,然后连接一个包含我之前创建的卡片网格的 Leaf Mesh 节点。SpeedTree 节点通常的工作方式是子节点在父节点上生成,在这种情况下,这意味着来自叶子网格的卡片将在区域节点创建的区域内生成。

为了从整体上调整集群,我修改了 Zone 节点以更改卡片可以生成的位置,然后修改 Leaf Mesh 节点以更改在给定位置生成的卡片数量以及卡片的方向。

选择 Zone 节点后,我转到“generation”选项卡并调整“sweep”设置以使集群以圆形生成并调整“number”设置以随机生成更多区域。

选择叶网格节点我还调整了“生成”选项卡下的草卡数量,然后向下转到“局部方向”选项卡以更改单个卡片的局部方向。我建议尝试不同的设置以查看它们的作用,因为它们并不总是一目了然。

在编辑草丛时,我正在考虑以下几点:

  1. 整个集群的大小
  2. 集群中有多少卡

集群的大小将影响需要在引擎中生成以覆盖地面的实例数量。为了提高性能,您希望集群相当大以保持较低的绘制调用,但您不希望它们太大以至于集群在地形不平坦的地方伸出地面。

卡的数量会很大影响性能,因为大量的卡会导致大量透支,这是非常昂贵的。对于这个项目,我发现花一些额外的三角形来切割草图集的完全透明部分对性能更好。如果您在 SpeedTree 中制作自己的植被,我建议您尝试不同的三角形计数以找到最佳位置。

这是我的草丛现在在 SpeedTree 中的样子:

在 SpeedTree 中设置集群后,我将它们带入虚幻引擎。在这一点上,我想在整个场景的上下文中看到草地,而不是在一片草地上放大。虽然我在引擎中有草,但我也在寻找我需要在 SpeedTree 中进行哪些调整,以使它们在引擎中看起来不错。然而,在我回到 SpeedTree 之前,我想在虚幻引擎中设置一个合适的着色器,这样我就不会在寻找改进时被草地上奇怪的阴影分心。

设置草着色器

从 SpeedTree 将植被带入虚幻引擎通常不会立即看起来很好,因为您需要一个好的着色器来使植被看起来很好。SpeedTree 中有一个选项可以将现有材质导出到 Unreal 中,但我发现我需要的功能比它提供的功能要多得多。我没有使用导入的着色器,而是自己制作了包含以下功能的着色器:

1.淡化草丛基于与相机的距离。为了做到这一点,我使用了 PerInstanceFadeAmount 节点,它告诉着色器给定草实例的褪色量。为了使用这个节点,我必须用草地贴图生成草地,我用景观材料来做。草图是一种通过其材质在景观上生成程序性植被的方式,称为景观草类型资产。打开 Landscape Grass Type 并将“Start Cull Distance”设置为低于“End Cull Distance”的值将使 PerInstanceFadeAmount 开始输出,在草材质中,每个草实例的数量在它们比 Start Cull 更远时淡化距离。有了这些信息,我现在可以调整草的整体不透明度,使其在远处淡出。

2.增加法线贴图的强度。这将打破草卡上的照明,给人一种错觉,即单个草丝指向不同的方向,而不是看起来像一排平的草丝。我为此效果使用了 FlattenNormal 节点。其结果将根据您使用的法线贴图而有所不同。理想情况下,您希望草丝指向不同的方向,并且单个草丝像在自然界中一样弯曲、扭曲和转动。

3. 次表面散射。这是使草看起来可信的最重要的部分之一。我发现使用反照率作为次表面颜色对草来说效果很好,我还用顶点颜色淡出根部附近的次表面散射效果,以便更好地将草与景观纹理混合。

4.颜色变化也很重要,以摆脱均匀色草的人造外观。我在我的着色器中使用了小规模和大规模变化,小规模变化由一个名为 SpeedTreeColorVariation 的节点组成,它为每个草实例提供随机颜色。大规模的颜色变化来自在世界空间 XY 中平铺的纹理蒙版,我用它来在两种色调之间进行 lerp。

5.高度变化是我最喜欢的着色器功能之一,因为它使草看起来非常蓬松。我通过沿着它们的法线偏移顶点来实现这一点。由于我不想移动草根,我将顶点颜色放置在最靠近地面的顶点处,以便从这种偏移效果中掩盖根部。为了获得变化,我在世界空间中使用蒙版平铺来确定要偏移的集群。

这是着色器的视觉摘要:

设置景观材质

景观材料是将这个项目中的所有东西结合在一起的部分,它使我能够从根本上以高层次的方式艺术指导程序性植被。材料本身非常简单。它有两层,一层叫“草”,另一层叫“草高”,我可以在风景上画出来。这些层将使用景观草输出节点生成不同的草网格。Grass 层将生成一个较短的草网,而 Grass High 层将生成一个更高的草网。此外,我在整个景观的世界空间 XY 中使用蒙版平铺在 Grass 图层上生成杂草和花朵簇。最后,为了减少过度绘制,我通过简单地从各自的蒙版中减去高草蒙版来确保杂草、花朵和短草不会在高草图层上生成。

优化

我发现在优化任何类型的植被(包括草)时,透支是最重要的因素之一。因为我知道我想要漂亮的特写渲染,所以我决定用卡片使草丛更密集,例如,如果我试图达到 60 FPS 目标,我会这样做。对我来说,这个项目在我的 PC 上以 40-45 FPS 的速度运行,使用 GTX 1060 和 1080p。为了提高性能,我会降低草丛中卡片的密度(幸运的是,这是一个非常简单的解决方法,因为我在 SpeedTree 中使用了程序工作流),并在虚幻引擎中生成相距更远的簇。

结论

回想起来,这个项目是一次非常有趣的经历,我从中学到了很多东西。我想说最大的挑战是弄清楚如何采用在 SpeedTree 中看起来不错的集群并使其在虚幻引擎中看起来不错。在我看来,弄清楚要使用什么样的图集纹理以及设置一个好的着色器是两个关键的里程碑。

优化也是一个很大的挑战。虽然我尝试了不同的方法并得出了一些结论,但很明显,关于如何制作优化的植被还有很多东西需要学习,我希望在继续这个项目的过程中我能学到一些东西。

感谢您的阅读,我希望您觉得这很有趣。如果您有任何问题,请随时将它们发送给我!

返回首页

作者 CG-BOX

发表评论