Category: Mesh Painting

Preparing your Mesh for painting


Before reading this page make sure you’ve reviewed the Quick Start Guide and Choosing your Workflow articles to gain familiarity with some of the terms used here.

The preparation needed for painting on a mesh depends entirely on the UV workflow chosen for painting, so it is good idea to know which workflow (mesh-space / world-space / local-space) you want to use first.


Preparing a Mesh for World-Space/Local-Space Painting

No preparation is necessary. This workflow uses location based UVs so you can get started straight away on any kind of mesh.


Preparing a Mesh for full 3D Painting (Mesh-Space UVs)


Skeletal meshes: A lightmap UV is compulsory for skeletal meshes in this workflow. So in addition to your regular UV map (UV0), you will need to create a simple lightmap UV on UV1. You will need to ensure that every part of your mesh (per-pixel) has a unique coordinate in the lightmap UV you’ve created. Now you should be able to use Don_Mesh_Paint_UV1 to paint without any issues.

Static meshes: A lightmap UV may be necessary for static meshes if you need seamless painting (usually a good thing to have) or if you’re painting across multiple materials. For more information on scenarios where you can get away without a lightmap, see the Choosing your Workflow page.

Why do I need to create a lightmap? The lightmap here serves as a “paintmap”. This UV channel is used to bake positions from your mesh onto a lookup texture that facilitates painting. This is currently the only way to paint on skeletal meshes because they do not support Collision UVs (i.e. translation of a HitResult into a UV coordinate). This is also the only workflow that supports fully seamless painting across UV islands (for procedural brushes, not for decals).

What is the success criteria for a good paintmap? Every pixel of your mesh needs to resolve to a unique coordinate on your lightmap UV. Basically, no overlapping faces allowed. You’ll know your lightmap is off if you’re simply not be able to paint on certain parts of the mesh. This effect is clearly demonstrated if you try to use a UV0 mesh paint node (instead of the prescribed UV1) for 3D mesh painting. Because UV0 can contain overlapping faces, you will never be able to paint on the faces that are overlapped by another because those pixels will get overwritten by a competing face.


Physics Asset and Trace Channel Considerations

Characters need to ensure that they are painting strokes on the skeletal mesh’s physics asset rather than the root collision capsule. This is because the root collision capsule is usually a very rough approximation of your mesh’s actual geometry and the accuracy obtained from this is nowhere near what you need for smooth painting.

So how do you solve this? While tracing your HitResult (from weapons/etc) you can use a trace channel that the skeletal mesh will block, but the capsule doesn’t (eg: use a collision profile where the character’s Mesh blocks the Camera channel while the Capsule ignores it). This is the approach used by the sample project. Another option is to manually route the skeletal mesh component to the PaintStrokeAtComponent function after extracting the skeletal mesh from Hit Result’s actor.

Speaking of Physics Assets, skeletal meshes will need a physics asset that accurately envelops the geometry of mesh (including any WPO offsets). Because the precision of your painting is directly tied to the hit location supplied to the Paint nodes, you won’t get good results unless your physics asset (or collision capsule if you want to go down that route) accurately approximates the pixels of your mesh. It’s pxiels, rather than vertices here, because it really is the pixel locations that are used to determine where a brush stroke should draw paint.


Preparing a Mesh for Decal/Text projection

Again, if you’re using world-space/local-space painting, no further preparation is necessary. Everything will work out-of-the-box .

For mesh-space text/decal stamping, your preparation will lie in UV island management on the lightmap UV. For best results you’ll need to create large, unbroken UV islands across faces that are most likely to receive decals/text. For example, if you’re painting these across a character’s back (for shirt names/numbers/logos like in the sample project), then you’ll want to create your lightmap UV such that the character’s torso has a single, contiguous UV island that has no seams across the back or front.

Here’s the reason why:

Seamless decal/text projection for mesh-space (non-planar) painting  is currently not supported by the plugin. This means that when a UV coordinate has been determined for stamping your decal/text, it will potentially be projected across multiple UV islands, not all of which may be physically co-located with the faces you’re actually targeting. Eg: you could easily move the UV island of a character’s leg right next to the torso and if your decal/text brush size is large enough, then the projection may overflow onto the legs instead of being contained within the torso. To give another example, if the torso were broken into multiple UV islands and placed far away from each other, then a portion of the torso may not receive the effect at all.

Ultimately large contiguous UV islands across important parts of your mesh’s lightmap UV are the best way to mitigate the lack of mesh-space seamless painting for decals/text. Note:- your main UV channel is not bound by these constraints, only your lightmap UV is. You can build your main UV map any way you please.

Quick Start Guide

Using DoN’s Mesh Painting Plugin

The basic workflow involves using a Paint node in your blueprints/code (for creating your effects) with a Material UV node in your materials (for rendering the effects).

Depending on the mesh, type of effect, etc, various Paint and UV nodes are available and can be combined in different ways. Finally, If you’re interested in driving gameplay from painted pixels, a Query node can be used to leverage paint blob collisions.

Step 1) To get started, open your context menu and search for “Don Mesh Paint” to see the list of Paint nodes available:

(C++ users will find the same API exposed in DonMeshPaintingHelper.h)


Step 2) Paint Stroke is the most common paint node you’ll be using. You need to provide a HitResult (from collisions, cursor hits, etc) and the paint effect will be routed to all materials of the hit component, assuming they have a Don UV node setup.

Here’s what a paint node looks like:

See the Paint Nodes Reference page to learn more about the various painting nodes available and the parameters that you can control.

Inside the Material Editor

After your code/blueprints is setup to paint effects, you’ll need to configure the materials on your character/mesh for receiving paint. You can reuse any of your existing materials and effects as you like, there is no need to create a new material.


Step 3) In your Material Editor, open the palette to your right and search for “Don” to see the list of UV workflows available.


Which UV node should I choose for my material?

It depends on what kind of mesh you’re painting and the overall effect you’re going for, but here’s a quick cheat-sheet:

  • Characters will typically need Don_Mesh_Paint_UV1 (We use UV1, not UV0; characters need a dedicated lightmap UV)
  • Landscapes: Don_WorldSpace_XY is ideal
  • Floors: Don_Local_Space_XY
  • Walls: Don_Local_Space_XZ

For a comprehensive treatment of this subject, be sure to read the articles Which UV Workflow should i choose? and Preparing your Mesh for painting.


Step 4) Let’s see what a UV node looks like in action:

In this example from the sample project, we have a character that is receiving a Lava effect on Hit. Observe how the effect is sourced from the Don Mesh Paint node’s Alpha channel and blended in:

 Note 1: To enable a single “Material Attributes” input as used by the M_SimpleCharacterPaint node above (instead of the regular material output pins), you can simply click on that node and check the “Use Material Attributes” in the Details Panel.

 Note 2: The plugin does not require you to change your existing material setups in this manner. The above setup is purely for visual cleanliness; if you prefer you may continue using the regular material output pins and blend in any channels you’re interested in using.


Putting it all together

Here’s a finished example from the sample project in action.

This example works by first taking the UMG reticle position and obtaining a Hit Result from it (see U_SimpleHUD in the sample project). The demo pawn then supplies this Hit to PaintStroke (see BP_PainterPawn). Finally, the materials of the skeletal mesh (see M_SimpleCharacterPaint) are configured to receive paint in the form of mesh-space UVs.



Sample Project Downloads



4.15 – 4.16

The sample project has several examples of mesh painting and more. You can open the materials of any mesh to see how the Don material nodes are used to blend in effects. BP_PainterPawn is the blueprint which does all the painting for the demo project. This blueprint is somewhat complex (because of the broad nature of the sample project), but for your purposes you will simply need one of the Paint nodes and pass in the parameters relevant for your usecase/project.

Choosing your workflow


The plugin offers a multitude of UV nodes to support different workflows and usecases and this document will cover these in detail. Although you need just one material node to relay your effects inside your material, knowing which one to choose is important.

After reading this article you should be able to choose the correct material node for your usecase from the list below:


Your Workflows

The three main workflows supported by the plugin are Mesh-Space painting, World-Space painting and Local-Space painting.

Mesh-space painting supports full 3D painting by using the UV maps of a given mesh to map your paint textures across a mesh, while world/local-space painting are well-suited for 2D/planar paint projection via location based texture mapping1.

Simply put, if your mesh is 2D/planar or has predominantly only two axes you care about (eg: landscapes, floors, walls, etc) then you should favor a world-space/local-space workflow over the mesh-space workflow. What’s more, even if your mesh is non-planar, but your visual effects are mostly 2D, eg: tagging certain actors/meshes in your world with a certain color, even then, the planar workflow is a better choice because they’re simpler to setup, always seamless and perform much faster than their mesh-space counterpart. World-space painting has the added advantage of sharing a single texture layer across the entire world.

Additionally, mesh-space workflow may require a second UV channel (lightmap) on your mesh. This is compulsory for skeletal meshes, for seamless painting or if you need to paint across multiple materials. Static meshes with a single material should strongly consider turning on the setting “Support UV From Hit Results” (under Project->Physics Settings) as this will simplify your workflow by eliminating the need for a second UV channel.

For more details on getting your meshes paint-ready, see the article Preparing your Mesh for painting.

1 location based texture mapping means your paint textures are aligned across any two specified axes (i.e. XY or XZ or YZ) either in world space or relative space.


Case Study:

Now that you are familiar with the basic terms, we’ll look at a few practical examples and choose a material UV node that is best suited for us.

Case 1: You have a character receiving hit-damage from a weapon and you want to paint splatter/impact effects on the character at the hit location.

Recommended Workflow: Mesh-space painting via Don_Mesh_Paint_UV1. We’re using UV1 instead of a UV0 because we compulsorily need a lightmap UV for skeletal meshes (and that is typically created in UV1). 

Case 2: You have a wall or floor and want to make holes, paint graffiti, or draw other effects on them

Recommended Workflow: Local-space painting via Don_Local_Space_XY (for floors) or Don_Local_Space_XZ (for walls). If you need to chain multiple effects-layers, use the Layer1/Layer2 suffixed nodes, eg: Don_Local_Space_XY_Layer1 and Don_Local_Space_XY_Layer2

Case 3: Your landscape needs run-time effects such as water/lava or any other per-pixel effect across the landscape.

Recommended Workflow: World-space painting via Don_World_Space_XY. Additional layers can be accessed via the Layer1/Layer2 suffixed nodes.

Case 4: You have a complex static mesh that needs seamless painting.

Recommended Workflow: Mesh-space painting via Don_Mesh_Paint_UV1. Although static meshes are not obligated to supply a lightmap channel on UV1, seamless painting is only possible through a lightmap (think of it as a “paintmap”) UV. Ensure that your static mesh has a lightmap channel created on UV1 and that you’re placing the UV1 variant of the mesh painting node in your material.

Now let’s take a look at some slightly more complex examples. These are relevant only to those looking to squeeze the last drop of performance / workflow simplification out of the system.

Case 5: You have a complex static mesh with a single material and do not care about seamless painting (perhaps because your UV map has very few UV islands)

Recommended Workflow: Mesh-space painting via Don_Mesh_Paint_UV0. Be sure to turn on the setting “Support UV From Hit Results” (under Project->Physics Settings) and “Trace Complex” to true (on your Linetrace/sweep) for this to work.

Note:- 4.16 allows you to “detect material on mesh surfaces” and this feature can theoretically be leveraged to support multiple materials via Collision UV painting. This has not yet been implemented.

Case 6: You have a complex static mesh with a single material that needs decal or text projection (i.e. usage of custom brush textures effects or text)

Recommended Workflow: Mesh-space painting via Don_Mesh_Paint_UV0 (if you need 3D projection) or an appropriate local-space/world-space node if you have the ability to approximate your decal projection along any two axes.

Currently, seamless decal/text projection is only supported only for world-space/local-space painting, so if you have just one material and need 3D projection, you can avoid using the (comparatively) heavier positions texture workflow (and the need to create a second UV channel) by leveraging Collision UV support along UV0. You will need to follow the same setup described in Case 5 for this to work.



A simple rule of thumb for most of your usecases will be to use

1) Don_Mesh_Paint_UV1 for non-planar/3D effects

2) Don_World_Space_XY for landscapes

3) Don_Local_Space_XY for floors and  

4) Don_Local_Space_XZ for walls.

For optimizing your workflow even further, take the time to consider whether your visual effect can be approximated as a planar surface, whether you need seamless painting, decal projection and whether you can take the fast-path (collision UV support) for static meshes.