在此虚幻引擎 4 教程中,您将学习如何在任何类型的网格上绘制颜色。
网格绘画是玩家在游戏中的物体上绘画的能力。
网格绘画的例子有《超级马里奥阳光》中的粘液、《传送门 2》中的凝胶和《喷射战士》中的墨水。
它可以用作游戏元素,也可以纯粹用于视觉效果。
无论哪种方式,网格绘画为游戏设计师和艺术家开辟了很多可能性
虽然前面的示例几乎都是相同的效果,但您也可以使用网格绘制来实现许多其他效果。
例如,您可以用它来喷涂物体、渲染角色的伤口,甚至让玩家绘制自己角色的脸!
在本教程中,您将学习如何在骨架网格物体上绘画。
为此,您将:
-
将网格展开为 UV 形式
-
使用线迹中的命中位置来球体遮罩网格
-
使用场景捕获将展开的网格和球体蒙版渲染到渲染目标
-
使用蒙版在角色材质中的纹理之间进行混合
注意:这不是关于顶点绘制的教程。顶点绘制取决于网格分辨率,无法在游戏中更改。另一方面,本教程中的方法独立于网格分辨率,也适用于游戏。
*注意:本教程假定您已经了解使用虚幻引擎的基础知识。
如果您是虚幻引擎新手,请点击查看虚幻引擎初学者教程系列。*
本教程是关于在虚幻引擎中使用渲染目标的 4 部分教程系列的一部分:
第 1 部分:使用渲染目标绘画
第 2 部分:创建可交互雪地
第 3 部分:创建交互草地
第 4 部分:动态网格绘制
入门
解压缩并导航到MeshPainterStarter并打开MeshPainter.uproject。
如果你按Play,你会看到你要画的角色。
就像雪地和草地小径教程一样,这种方法也需要场景捕捉。
为了节省时间,我已经为您创建了一个场景捕捉蓝图。
如果您想了解有关捕捉设置的更多信息,请查看我们的可交互的雪地。
首先,让我们看看如何在网格上绘画。
网格绘画
在大多数情况下,您正在使用的网格已经进行了 UV 映射。
所以显而易见的事情是使用渲染目标创建一个遮罩,然后将其应用于网格。
但是,直接在渲染目标上生成遮罩(使用 Draw Material to Render Target)通常会导致跨 UV 壳的不连续性。
这是立方体的 UV 贴图和球体遮罩纹理的示例:
这是应用于立方体的蒙版:
如您所见,2D 球体蒙版不会环绕角,因为它没有考虑几何形状。
要生成正确的蒙版,球体蒙版需要改为对网格的世界位置进行采样。
但是在使用 Draw Material to Render Target 节点时如何访问世界位置呢?
创建展开材质
导航到Materials文件夹并创建一个新材料。将其命名为M_Unwrap然后打开它。
接下来,更改以下设置:
-
着色模型:未点亮。这是为了确保场景捕获不会捕获任何照明信息。
-
双面:启用。有时,根据网格的 UV 贴图方式,展开的面可以面向另一个方向。Two Sided 将确保您仍然可以看到任何翻转的面孔。
-
用法\与骨架网格体一起使用:启用。这将编译材质在骨架网格物体上工作所需的着色器。
接下来是展开网格。
为此,请创建以下设置。
请注意,我已经在MPC_Global资产中创建了CaptureSize和UnwrapLocation参数。
这将 UV 展开网格到指定大小的指定位置。
请注意,如果您的网格的唯一 UV 贴图位于单独的通道上,您将需要更改TextureCoordinate节点的Coordinate Index 。
例如,如果唯一 UV 在通道 1 上,您可以将Coordinate Index设置为1。
下一步是创建球体蒙版。
为此,您需要两个参数:命中位置和球体半径。
创建突出显示的节点:
这将为球体遮罩内的像素返回白色,为外面的像素返回黑色。
不要担心为参数设置值,因为稍后您将在蓝图中进行设置。
将Absolute World Position节点设置为Absolute World Position (Excluding Material Shader Offsets)很重要。
这是因为像素的世界位置会因展开而改变。
排除材质着色器偏移将为您提供展开前的原始世界位置。
这就是展开材料所需的全部内容。
单击“应用”,然后关闭材质。
接下来是将材质应用于角色以展开它。
展开角色
对于本教程,捕获蓝图将处理展开和捕获。
首先,您需要一个展开材质的动态实例。
导航到Blueprints文件夹并打开BP_Capture。
然后,将突出显示的节点添加到Event BeginPlay。
确保将Parent设置为M_Unwrap。
接下来,您需要一个函数来执行解包和捕捉。创建一个名为PaintActor的新函数。
之后,创建以下输入:
-
ActorToPaint:类型是Actor。要解包和捕获的演员。-
-
HitLocation:类型是Vector。这将是球体遮罩的中心点。
-
BrushRadius:类型为Float。以世界单位表示的球体遮罩的半径。
虽然这种绘画方法可以适用于任何actor,但我们只会检查传入的演员是否继承自Character类。
为了简化代码,我们会将角色的骨架网格组件存储到一个变量中,因为您需要多次引用它。
为此,添加突出显示的节点:
现在是时候进行展开和球体遮罩了。
为此,将突出显示的节点添加到节点链的末尾:
这是每一行的作用:
-
首先,这将保存网格的原始材质,以便您稍后可以重新应用它。之后,它将应用展开材质。
-
这条线会将命中位置和笔刷半径传递给展开材质以进行球体遮罩
在您可以测试展开之前,您需要从播放器开始进行线跟踪以获得命中位置。
获取命中位置
单击编译,然后返回到主编辑器。
然后,打开BP_Player。打开拍摄功能并添加突出显示的节点。
对于本教程,将Brush Radius设置为10。
单击Compile,然后关闭BP_Player。
按播放键然后左键单击角色以执行展开和球形蒙版。
您想知道为什么蒙版一直在移动么,那是因为零件在球体蒙版中进进出出。
但这不是问题,因为您只会在命中时捕获解包。
现在您已经展开网格,您需要捕捉它。
捕捉展开
首先,在展开的网格后面添加一个未点亮的黑色平面是个好主意。这将有助于防止 UV 壳边缘出现接缝。
打开BP_Capture,然后添加一个名为BackgroundPlane的Plane组件。
为了节省时间,我已经为您制作了黑色材质。将材质设置为M_Background。
对于本教程,展开和捕获大小为500×500单位,因此背景平面至少需要那么大。将比例设置为(5.0, 5.0, 1.0)。
由于平面的位置和展开位置相同,因此将平面向下偏移以防止任何 z 轴冲突也是一个好主意。
为此,请将Location设置为(0.0, 0.0, -1.0)。
接下来,您需要执行捕捉。返回到PaintActor函数并添加突出显示的节点:
这将捕捉展开的网格。之后,它将重新应用网格的原始材质。
目前,场景捕获将覆盖渲染目标的先前内容。
为确保球体遮罩累积,您需要确保场景捕获添加到之前的内容中。
为此,选择SceneCapture组件并将Scene Capture\Composite Mode设置为Additive。
单击编译,然后关闭蓝图。接下来,您需要在角色材质中使用渲染目标。
使用遮罩
导航到Characters\Mannequin\Materials并打开M_Mannequin。
然后,添加突出显示的节点。确保将Texture Sample设置为RT_Capture。
这将在遮罩为白色的地方显示红色,在遮罩为黑色的地方显示橙色。
不过,如果您愿意,可以在纹理或材质层之间进行混合。
单击“应用”,然后关闭材质。按播放键并左键单击角色开始绘画。
写在最后
虽然您在本教程中只使用了球体蒙版,但它们并不是您可以使用的唯一形状。
其他还有盒子、圆柱体、圆锥体等等!