Skip to content

No. 1227 LB LabsEQLabs Pro

Painting Lab

UE 5.4–5.85/52.0.5

Type: Custom Asset Editor (Pattern B) · Asset class: UPaintingLabAsset · Category: Labs

A full in-editor texture painting workspace. Paint directly on a static mesh through its UV layout or a triplanar projection, or switch to a flat 2D canvas for VFX sprites and standalone textures. Five paint modes cover the texture types you actually ship — RGBA Color, direction-encoded Flow, tangent-space Direction, per-channel Mask, and stroke-driven Normal. The asset is a real .uasset holding every texture in the session, and Flipbook Studio turns the same canvas into a frame timeline with onion skin, a playback preview and one-click sprite-sheet atlas export.

Export writes a UTexture2D and an image file on disk in one action, with seam dilation applied automatically. No round-trip to Substance Painter for flowmaps, damage masks, hand-painted VFX sprites, or flipbooks.

Editor open with a paint stroke mid-action on a 3D mesh — Settings panel on the left, painted mesh in the viewport, brush gizmo visible at the cursor.
Editor open with a paint stroke mid-action on a 3D mesh — Settings panel on the left, painted mesh in the viewport, brush gizmo visible at the cursor.
A base coat from the gradient ramp, paint straight onto a sculpture and round its far side, a finer brush for the gold, undo and redo, then export to a 1024 × 1024 texture and a PNG — shown back on the sculpture in the level.
  • Authoring flowmaps for water / cloth / lava materials: Flow mode encodes brush direction directly into RG channels
  • Painting damage and wear masks that hook into a layered material (rust, wetness, edge wear, dirt) — four user-labeled channels per RGBA texture
  • Hand-painted VFX sprites (alpha shapes, erosion masks, splatter decals) on the 2D canvas, with tiling preview to evaluate seamlessness
  • Animated VFX flipbooks. Paint frame by frame with onion skin, preview at your target FPS, and. export a power-of-two atlas plus a ready Niagara SubUV material
  • Painting anisotropic direction maps (hair, brushed metal) using Direction mode, which encodes the brush comb into the surface tangent space
  • Ink and hatch work. The Hatch tool draws parallel line fills; overlap strokes at different. angles to cross-hatch
  • Quick texture polish on top of an imported source: drop an existing texture in as the canvas starting point and paint corrections
  • Don’t expect a Substance Painter replacement for full PBR layer authoring. Painting Lab is. per-texture, not per-material-stack. There is no non-destructive layer system; strokes composite into the pixel buffer as you paint.
  • Don’t paint on meshes with overlapping UVs without symmetry off. Mirrored UVs paint both. regions simultaneously. Use UV channel 1+ for a non-overlapping set.
  • Don’t use this for terrain texture painting. UE’s Landscape painting is a different problem;. Painting Lab targets per-asset textures, not landscape weight maps.
  • Triplanar fallback is for preview only on UV-less meshes. The painted result is world-space. projected and won’t be portable to UV-based tools.

There are two equivalent paths:

From the Content Browser:

  1. Right-click in the Content Browser.
  2. Pick EQLabs → Painting Lab Asset.
  3. Name the asset; double-click to open.

From the EQLabs Hub:

  1. Open Window → EQLabs Hub.
  2. Search for Painting or browse to Art → Paint.
  3. Click the Painting Lab tile.

The asset is a UPaintingLabAsset .uasset. It survives across sessions, holds every texture you’ve painted, and serializes with a magic number + version tag so future format changes load cleanly.

Three dockable tabs: Settings (left), Canvas / Viewport (centre), Texture Preview (right). A fourth tab, Flipbook (Animation), carries the frame timeline.

ControlWhat it does
3D Mesh / 2D Canvas toggleSwaps between mesh-projected painting and flat-canvas painting
Tool selectorPaint / Erase / Smooth / Hatch / Fill / Clear
Paint modeColor / Flow / Direction / Mask (Normal is set per-texture — see below)
Channel togglesR / G / B / A — which channels a stroke is allowed to write
SymmetrySym:Off / X / Y / XY (4-way) / Radial (N segments)

Clear resets the active texture to its neutral value for its paint mode, not to black — see the paint-mode table.

A details view bound to the asset. Structural choices live here rather than on the toolbar: Mode, Target Mesh, Active UV Channel (0–7), Projection (UV or Triplanar), Preview Material, Brush Tip Texture, the Textures array (name, resolution, paint mode, four channel labels), and the Palette.

In 3D Mesh mode it’s an SEditorViewport with the assigned mesh. The brush cursor tracks the mesh surface in UV space; what you paint shows up live on the mesh. Triplanar projection is available for meshes without usable UVs.

In 2D Canvas mode it’s a flat SPaintingLabCanvas widget with pan/zoom. Optional Tile preview wraps the canvas as a 3×3 repeat to evaluate seam continuity.

A per-channel view selector (All / R / G / B / A) isolates one channel for inspection — critical when authoring channel-packed mask textures. A UV wireframe overlay draws the mesh’s UV islands on top of the texture preview.

Gesture3D viewport2D canvas
LMB dragPaintPaint
Shift + LMBLine stroke — press at the start, release at the end; the run commits as evenly spaced dabs—
Ctrl + LMBEyedropper — picks the painted colour under the cursor into the brushEyedropper
Alt + LMBOrbit the camera—
RMB drag—Pan
Scroll—Zoom
Shift + Scroll—Brush size
FieldWhat it doesDefault
SizeBrush radius — UV-space units in 3D mode, canvas pixels in 2D5.0
StrengthPer-stamp opacity / influence, 0–10.5
FalloffEdge softness, 0 (hard) → 1 (fully feathered)0.8
SpacingGap between brush stamps5.0
Spacing ModeDistance (Photoshop-style) or TimeDistance
ColorBrush paint colour (Color mode). The alpha channel paints the A channel.White

Save… writes the current brush settings to a reusable Brush Preset asset; Load… applies one back. Presets carry the whole brush state, so a hatching setup or a soft-airbrush setup is one click away in any Painting Lab asset.

Four jitter channels — Angle, Size, Scatter and Opacity — each with an amount and a control source that decides what drives it:

ControlDrives the jitter from
OffNothing — the parameter stays fixed
RandomA fresh random value per stamp
Stroke DirectionThe direction the stroke is currently travelling
FadeHow far into the stroke this stamp is

An optional grayscale texture used as the stamp shape — brightness controls how strongly each pixel paints. Invert Mask flips it; Threshold sets the cutoff.

Multiple stamps from a stylized brush tip (splatter / leaf / hatch shape) clearly visible on the canvas. Brush tip texture preview in the Settings panel showing the alpha mask currently loaded.
Multiple stamps from a stylized brush tip (splatter / leaf / hatch shape) clearly visible on the canvas. Brush tip texture preview in the Settings panel showing the alpha mask currently loaded.

Lazy Mouse runs cursor positions through a rolling-average filter before the raycast and the dab, so an unsteady hand still produces a clean curve. Smoothing is the window size — default 6, useful range 4–10. Larger is silkier but the brush lags further behind the cursor.

The toolbar exposes four modes directly. A fifth, Normal, is set per-texture in the Settings panel’s Paint Mode field, and is what the PBR Standard template assigns to its Normal slot.

ModeWhat a stroke writesNeutral (unpainted) value
ColorRGBA directlyBlack
FlowThe stroke’s direction as a 2D vector in RG, intensity in B(0.5, 0.5, 0, 1) — zero direction
DirectionThe stroke direction as a normalised tangent in RG, a painted flag in B(0.5, 0.5, 0, 1)
MaskPer-channel grayscale, with your own channel labels(0, 0, 0, 0)
NormalA tangent-space normal pointing outward from the brush centre — an embossed bevel that follows the stroke(0.5, 0.5, 1, 1) — flat

Those neutral values are the single source of truth shared by texture creation, Clear, and the exporter’s seam-dilation gutter detection, so “unpainted” means the same thing everywhere.

Close-up of the canvas during Flow painting; arrow overlays clearly visible per stroke showing direction. Underlying water material visibly responds to the painted flow.
Close-up of the canvas during Flow painting; arrow overlays clearly visible per stroke showing direction. Underlying water material visibly responds to the painted flow.
Mask mode active with three independently-painted channels (R / G / B) composed into a final channel-packed result alongside.
Mask mode active with three independently-painted channels (R / G / B) composed into a final channel-packed result alongside.
Radial-6 symmetry mode active, brush stroke on one segment mirroring instantly to the others. Symmetry indicator visible in the UI.
Radial-6 symmetry mode active, brush stroke on one segment mirroring instantly to the others. Symmetry indicator visible in the UI.

The asset holds any number of textures. Each row shows the name, resolution and paint mode; clicking switches the active painting target. + New Texture appends one; the X on a row removes it. Each texture has its own independent resolution (256–4096) and paint mode.

From Template: two one-click sets that replace the whole texture list:

  • PBR Standard. BaseColor (Color), Normal (Normal), Roughness (Mask), Metallic (Mask),. AO (Mask), all 1024×1024.
  • VFX Pack. Mask4Pack (Mask), FlowMap (Flow), Direction (Direction).

Both wipe the existing textures and their painted pixels, and both confirm first when there is anything to lose.

+ Save Color appends the current brush colour to a per-asset palette; clicking a swatch makes it the brush colour and Shift+click removes it. Clear empties the palette. Capped at 24 swatches — the oldest is evicted when full. The palette lives in the asset, so a project’s colour scheme travels with the file.

Pick a left and a right colour, then Apply as Ramp fills the active texture with a horizontal gradient — a fast start for a ramp texture or a lookup strip.

The Flipbook (Animation) tab turns the active texture into a frame sequence.

ControlWhat it does
< Prev / Next >Step through frames
+ DupAdd a frame after this one, copying its pixels as a starting point
+ BlankAdd a new empty frame after this one
DeleteDelete the current frame (always keeps at least one)
< Move / Move >Reorder the current frame one step earlier or later
OnionShow neighbouring frames as faint ghosts — previous in red, next in green
FramesHow many ghost frames on each side (0–3)
Onion OpacityGhost visibility, 0.05 (faint) → 1.0 (solid)
Play / StopPlay the sequence in the canvas
FPSPlayback rate

Starter Presets set up a whole loop in one click: Fire 16 (16 frames @ 24 FPS), Smoke 16 (16 @ 16 FPS), Magic 12 (12 @ 12 FPS).

  • Export Atlas + Material. Tiles every frame into a power-of-two sprite-sheet atlas. (UTexture2D + PNG) and creates a ready translucent flipbook material for Niagara SubUV or a material Flipbook node.
  • PNG Sequence. Every frame as a numbered 8-bit PNG in Saved/PaintingLab.
  • EXR Sequence. Every frame as a numbered 16-bit float EXR in Saved/PaintingLab.

Without a Preview Material the tool uses its own built-in preview material and binds the active painted texture to its Diffuse parameter.

Assign your own master material and the viewport additionally binds every painted texture to a parameter named after that texture — a texture called BaseColor lands in the BaseColor parameter, Roughness in Roughness, and so on. Parameters that don’t exist on the master are skipped silently, so a partial match is fine: you see what the material can show, and nothing errors.

Three buttons — Export PNG, Export EXR, and Export (Auto-Detect) (PNG for Color and Mask, EXR for Flow and Direction).

Each export produces both:

  1. A UTexture2D asset in the same Content Browser folder as the Painting Lab asset. The Content Browser jumps to it when the export finishes.
  2. An image file on disk under <Project>/Saved/PaintingLab/ — 8-bit PNG or 32-bit float EXR. The success toast carries a Show file link that opens the folder.

Colour data is sRGB-encoded for PNG; Mask, Flow, Direction and Normal stay linear.

Import Texture loads an existing UTexture2D into the active pixel buffer as a starting point.

Every export runs four passes of alpha-aware seam dilation before writing. Painted colour bleeds outward across UV island borders into the unpainted gutter, so the black halos that otherwise appear at island edges once MIPs are generated do not happen. Dilation runs on a copy — the authoritative pixel buffer is untouched and you can keep painting.

Content Browser showing freshly-exported PNG and EXR assets from a paint session. Source mesh in the level using the painted texture.
Content Browser showing freshly-exported PNG and EXR assets from a paint session. Source mesh in the level using the painted texture.

UPaintingLabAsset serializes through a custom Serialize() with a magic number and a version tag (V1_Initial → V2_MultiTexture → V3_UDIMReady). The format is append-only: old assets load, new fields default.

It holds the full texture list with paint mode, resolution, channel labels and the live pixel buffer per texture (and per frame, for flipbooks); the palette; the mesh and preview-material references; the UV channel; the projection mode; and the brush-tip reference. Reopen an asset weeks later and every texture, every channel label and every swatch is where you left it.

SettingDefaultRange / Type
Paint ModeColorColor / Flow / Direction / Mask / Normal
Brush Size5.0float
Brush Strength0.50 – 1
Brush Falloff0.80 (hard) – 1 (soft)
Brush Spacing5.0float
Spacing ModeDistanceDistance / Time
SymmetryOffOff / X / Y / XY / Radial
Radial Segments6int
Angle / Size / Scatter / Opacity Jitter0.00 – 1, each with a control source
Jitter ControlRandomOff / Random / Stroke Direction / Fade
Brush Tip Threshold0.50 – 1
Lazy Mouse Smoothing6window size; useful range 4–10
UV Channel00 – 7
ProjectionUVUV / Triplanar
Texture Resolution1024256 – 4096
Palette—up to 24 swatches, oldest evicted

Asset persistence: the painting session is stored inside the .uasset itself — there is no separate JSON config or sidecar.

  • Undo depth is bounded by texture size. Each level holds a full copy of the pixel buffer, so. the stack caps at 20 steps, dropping to 5 on a 4096×4096 texture.
  • A whole drag is one undo step. A single stroke with many stamps pushes one snapshot, not one. per stamp.
  • Triplanar fallback is preview-only. It paints in world space rather than UV space, so the. result isn’t portable to other tools. Use only when the mesh has no usable UVs.
  • Max canvas resolution is 4096×4096. For larger textures, paint as a sprite-sheet atlas or. tile across multiple textures in the same asset.
  • Symmetry interacts with overlapping UVs. Meshes with mirrored UVs paint twice when symmetry. is off. Either turn symmetry on or move to a non-overlapping UV channel.
  • Smooth is a box blur. For high-frequency detail recovery, use small brushes and multiple. passes; large blurs over fine detail are destructive.
  • UDIM fields are scaffolding. UDIMTile and bIsUDIMTile exist on each texture entry and the. format version is named V3_UDIMReady, but multi-tile painting is not implemented. Leave the defaults alone.

Fixed in v2.0.3: changing Target Mesh used to stop the live preview

Section titled “Fixed in v2.0.3: changing Target Mesh used to stop the live preview”

In releases up to and including v2.0.2, reassigning Target Mesh after the first assignment left the mesh rendering with its own material instead of the live paint preview. Painting still worked and the texture was still updated correctly — the strokes landed, the Texture Preview panel showed them, and export was unaffected — but they stopped appearing on the mesh.

If you are on v2.0.2 or earlier, the workaround is to close and reopen the Painting Lab asset after changing Target Mesh.

Found on 2026-08-29 by the standalone edition’s documentation screenshot rig and fixed the same day, shipping in v2.0.3: SPaintingLabViewport::SetPreviewMesh now clears PaintPreviewMasterSource alongside the cached MID, so the next UpdatePaintPreviewMulti rebuilds the instance and re-binds it to the new component’s material slots. The Painting Lab EditorUI test asserts the preview survives both the first and the second mesh assignment; with the fix reverted that assertion fails, which is how the fix was verified rather than assumed.

Painting Lab ships as its own Fab plugin as well. Since standalone 2.1.0 it is the same tool feature for feature — same painter, same five modes, same export, Flipbook Studio and Brush Presets included — and it opens from its own launcher rather than the Hub. See Painting Lab (standalone).

The full workflow, start to finish.
Report an issue with this tool

Opens our feedback form in a new tab with the tool name pre-filled.