使用蓝图创建美丽的治疗建筑

引言


生成程序蓝图是一个诱人的想法。 使用标准化模块和自动放置是很合乎逻辑的,因为毕竟这是相同的体系结构。 但是,当纹理化时,我们如何实现自然多样性而不是重复?

该建筑物仅由一个模块创建,并自动复制到Construction Blueprint 。 想法是该材料几乎不需要任何手动数据输入。 整个建筑仅使用一种材料 (不包括窗户)。 它的功能用于控制顶点颜色的随机性和像素在世界空间中的位置。


唯一的模块就是我们所需要的


无需人工放置或编写脚本。 所有随机化均在材料中完成。

本教程中描述的材料:

  • 取决于高度的污垢层仅覆盖对象到指定的绝对高度
  • 随机选择每个楼层和分段的对象颜色
  • 稍微移动小物体的位置 ,也随机
  • 允许用户为墙壁选择2种颜色以及其破坏值


顶点颜色作为数据


03:34

除了顶点和法线的位置之外,游戏引擎通常还提供对其他值(例如,顶点颜色)的访问。 对网格三角形着色时,颜色将在顶点之间进行插值。 您可以在3D编辑器中绘制它,也可以使用UE中的“ 绘制”选项卡。 如果在引擎中执行此操作,则将有机会修改世界中的网格的单独实例。 我在有关绘制顶点教程中解释了此用例。 但是,在这种情况下,我们将坚持使用导入的颜色,因为我决定将RGB通道用作控制随机化的精确蒙版


不要忘记3D图形中的颜色只是一个三分量向量 。 它的成分是红色,绿色和蓝色的亮度,范围为0-1。该值是任意的,因为顶点的颜色只是数据。 我决定不将它们直接用于绘画纹理,而是决定在每个通道中打包遮罩顶部的颜色:

  • 红色通道墙壁原色和次要颜色的遮罩。 值为0的多边形使用原色,而1为第二色。
  • 绿色通道 -用于从调色板中选择一种颜色 。 这使您可以控制小物件(例如干衣服)的颜色变化。 0到1之间的值将四舍五入为调色板纹理中的索引(UV位置)。
  • 蓝色通道 - 顶点位置的偏移,以水平移动顶点。 这意味着墙壁将使用0(不移动),并且最多可将1分配给空调或亚麻布。 此通道还控制可见性 (不透明蒙版)。 如果该值大于0,则将随机值(针对建筑物的每个部分)添加一个随机值以创建可变性。

在任何严肃的3D编辑器中,都具有绘制顶点颜色的功能。 您可以在编辑器中轻松找到有关操作方法的说明。 只需记住在网格物体导入窗口中告诉Unreal Engine,以便它替换( Replace )顶点的颜色(而不是忽略( Ignore ))。

就像我上面说的,这个项目中的颜色是一组精确的值。 对于类似的任务以及几乎所有的游戏美术技术任务,我更喜欢使用Houdini 。 但是,在任何其他3D编辑器中都可以实现类似的结果(付出更多的努力)。 只需注意着色器中每个颜色通道应指示的内容。

我在一个单独的教程中重点介绍了为顶点颜色通道分配值的整个过程: 使用Houdini以顶点颜色存储数据 。 在本教程中,我将使用棘手的Houdini工具使过程更高效。

施工图


07:57

我创建的蓝图很简单。 它仅创建建筑物的平坦墙,在水平和垂直方向上复制网格。 它具有可变变量MeshWall (静态网格物体), NumberOfFloors (整数), NumberOfSegments (整数)和Material


蓝图的结果:4层楼,2段楼。

整个过程是在构建脚本中执行的,即 在关卡编辑期间。 因此,生成的网格将表现得与其他任何静态对象一样。 例如,在建筑照明时将考虑到这一点。


首先测量网格尺寸。 边框长度是对象尺寸的一半。 我们可以计算一次并保存,因为对于所有细分而言,其值都是相同的。


其余代码在两个周期中运行。 外循环创建整个楼层,内循环创建当前楼层内的线段。 通过循环迭代索引乘以网格的宽度和高度来计算位置。



新的静态网格物体组件将添加到每个线段。 在某些情况下,使用实例会很有用。 添加组件会导致绘制调用数量增加,这在“繁重”的场景中可能会引起问题。


仅此而已。 设置新的NumberOfFloorsNumberOfSegments时,建筑物将自动更新。

顶点颜色掩盖的两种墙壁颜色


21:16


两种颜色都可以作为参数访问。 顶点颜色的红色通道用作它们之间的混合系数。


通道包装和混合


14:22


我们希望墙壁的颜色仅影响墙壁本身,而不影响窗框和空调。 而且,它们不应影响损坏的区域。 这可以通过将遮罩包裹在基色的Alpha通道中来完成。 换句话说,基色的纹理具有透明的背景,并且在那里壁的颜色受到影响。

顺便说一句,我将纹理的金属性,粗糙度和遮挡(全部用灰色阴影填充)到相同纹理R / G / B通道中 。 这将采样器,文件和Lerp的数量减少了三倍,这是一个很好的优化,不需要任何妥协。 在注释中可以找到有关此技术的教程。


纹理噪声



该噪声模式用于混合第一(干净)纹理和第二(损坏)纹理集。 我只是从纹理中加载它,而不是对其进行实时计算(这对于高品质的噪声而言将是一个昂贵的过程)。 WorldAlignedTexture节点从三个侧面进行投影它会按 程序 生成 UV坐标 )。


取决于高度的污垢。 重映射功能


18:00


污垢是在世界空间中通过渐变应用的纯色。 世界中像素位置的分量Z转换为间隔0-1。 这为我们提供了一个有用的蒙版-Lerp系数。 初始的最小和最大值(例如,从150到700 cm)由用户传输为标量参数。 添加了一点噪音以使过渡更加自然。



TAA_Remap_01_Clamped函数由我创建。 我几乎在所有着色器中都使用它。 它将源间隔中的值转换为间隔0-1。 非常适合根据距离(与相机,地面或什至在UV空间中的形状)创建蒙版。

颜色随机化,隐藏元素


晚上10:55


从线段位置的参考点获取随机值,可以移动小对象的调色板。 调色板是一种具有水平对齐颜色的纹理,因此移动用于读取的图像将为我们提供最终的颜色。



调色板的纹理放大比例。 通常的大小是8×1像素,禁用压缩


绿色顶点颜色通道用作随机值和蒙版。 值为0表示“此处不应用颜色”。


应用本地位置偏移



最后一个功能是沿X轴随机移动对象,为此,在顶点上添加了材质控制的位置偏移。 使用此技巧时,您需要注意两件事-复杂的碰撞(用于射击)和距离场。 一个参数和另一个参数都不知道已经执行了这种偏移。

我将再次使用蓝色通道并添加一个随机数-基于我们之前使用的分段位置的相同噪声。 让我们将其从间隔0-1转换为-0.5到0.5的间隔,以便在两个方向上执行移动。 然后,将其乘以PositionOffsetStrength追加节点将添加其余轴(Y和Z上的常数0)。

出乎意料的是,虚幻需要输出在世界坐标中偏移。 我们计算了当地位置 。 如何转换呢?

这可以通过使用“ 变换”节点将该新本地位置的空间转换为世界空间来完成。 然后,我从这个新的顶点位置中减去世界上顶点的初始位置,从而获得世界的偏移量而不是位置。 将此与世界位置偏移材料的发布结合起来,即可完成工作。


成品材料


我希望您从本教程中学到了一些新知识。 这是整个材料节点图的屏幕截图:


项目文件和讨论


您可以免费下载项目文件(如果需要,也可以免费下载): 项目文件 。 如果您有反馈或问题,请加入Reddit中的讨论。

补充阅读


  • 将纹理打包到RGB通道中的一种简单方法是使用Photoshop将三个灰度纹理保存到单个RGB图像的通道中。 打包可节省空间,更重要的是,一次读取操作可获取三种纹理。 这值得付出努力,因为从内存读取纹理是最耗时的GPU操作之一。

Source: https://habr.com/ru/post/zh-CN479880/


All Articles