Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/armory3d/armorpaint/llms.txt

Use this file to discover all available pages before exploring further.

The brush node system is a logic-node graph that runs every time you apply a brush stroke. Unlike material nodes — which compile into GPU shader code — brush nodes execute as a lightweight logic tree on the CPU each paint frame. The graph’s job is to compute the dynamic properties of the current brush stamp: where it paints, how large it is, what its opacity looks like, and which mask or stencil image it uses. Every brush slot in the Brushes panel has its own independent node graph, so you can give each brush a completely different procedural behavior.

Canvas Type

The brush node editor operates on CANVAS_TYPE_BRUSH. You can open it by clicking the Node Editor button in the Brush panel, or by pressing Tab when the brush editor is focused. Brush node canvases are entirely separate from material canvases — nodes and links in one do not affect the other.

Brush Output Node

Every brush graph must contain exactly one Brush Output node (type brush_output_node). It is the terminal node that the paint engine reads each frame to determine how to stamp the current brush.
Input SocketTypeDefaultDescription
PositionVECTOR(0.0, 0.0, 0.0)XY paint position in normalized screen space
RadiusVALUE1.0Brush radius multiplier
ScaleVALUE1.0Brush stamp scale multiplier
AngleVALUE0.0Brush stamp rotation in radians
OpacityVALUE1.0Brush opacity (also accepts a texture name string for mask images)
HardnessVALUE1.0Brush hardness (edge falloff)
StencilVALUE1.0Stencil mask (also accepts a texture name string for stencil images)
The Directional boolean property on the Brush Output node enables direction-locked painting, aligning the stamp to the stroke direction. When the Opacity or Stencil socket receives a string value (the name of an asset image with a .rgb or .a suffix), the paint engine uses that texture as a mask image instead of a flat scalar. Connecting a tex_image_node — which outputs asset name strings — to these sockets is the standard way to drive texture-based brush masks.

Available Brush Node Types

Brush nodes are per-brush-slot. Each brush in the Brushes panel has its own node canvas. Brush graphs are saved as part of the project file and are not shared between brushes unless you manually duplicate them.
NodeType StringDescription
Brush Outputbrush_output_nodeTerminal output node. Drives Position, Radius, Scale, Angle, Opacity, Hardness, and Stencil for each paint stamp. Required in every brush graph.
Inputinput_nodeReads the current pointer/pen position in normalized screen coordinates. Also drives lazy stroke interpolation via Radius and Step inputs. Supports pen pressure for position, ruler-locked painting, and grid snapping.
Tex Imagetex_image_nodeSamples an asset image. Outputs the file name string with .rgb or .a suffix. Connect to the Brush Output’s Opacity or Stencil socket to use an image as a brush mask.
Colorcolor_nodeOutputs a constant RGBA color value.
Floatfloat_nodeOutputs a constant float (scalar) value.
Integerinteger_nodeOutputs a constant integer value.
Vectorvector_nodeOutputs a constant float3 vector value.
Booleanboolean_nodeOutputs a constant boolean (true/false) value.
Stringstring_nodeOutputs a constant string value.
Mathmath_nodeApplies a scalar math operation (Add, Subtract, Multiply, Divide, etc.) to one or two float inputs.
Vector Mathvector_math_nodeApplies a vector math operation (Add, Subtract, Normalize, Cross, Dot, etc.) to one or two vector inputs.
Separate Vectorseparate_vector_nodeSplits a float3 vector into its X, Y, and Z scalar components.
Randomrandom_nodeGenerates a random float value. When a graph contains a random_node, the paint engine sets brush_nodes_uses_random = true, causing each stamp to get a fresh random value.
Timetime_nodeOutputs the current application time as a float, enabling time-animated brush properties.
Nullnull_nodeA passthrough/identity node. Outputs its input unchanged; useful as a routing placeholder.

Example Workflow: Stamp Brush with a Texture Mask

1

Create a new brush slot

In the Brushes panel, click + to add a new brush slot. Give it a name.
2

Open the brush node editor

Click the Nodes icon on the brush slot, or press Tab with the brush panel focused. The canvas opens with a default Brush Output node already present.
3

Add an Input node

Press Space to open the node search. Type input and select Input to add the pointer/pen position node. Connect its Vector output to the Position input of the Brush Output node.
4

Add a Tex Image node

Press Space again and search for Tex Image. Select your stamp image asset from the node’s dropdown. This node outputs the image’s asset name string.
5

Connect the mask

Wire the Tex Image node’s RGB output to the Opacity input of the Brush Output node. The brush will now use the image as its opacity mask.
6

Adjust stamp tiling

To tile the stamp, add a Float node set to a value less than 1.0 and connect it to the Scale input of the Brush Output. This scales the UV space and produces a tighter tiling of the stamp texture.
7

Paint

Return to the 3D viewport and paint. Each stroke stamp will be shaped by the selected texture mask.
Brush graphs evaluate on the CPU every paint frame, not on the GPU. Keep brush node graphs small for optimal performance during high-frequency strokes or particle painting.

Build docs developers (and LLMs) love