ArmorPaint’s node editors for materials and brushes are fully extensible through the plugin API. A plugin can register new node categories — which appear as groups in the node search list — and map each node type string to a callback that generates the corresponding Kong/GLSL shader code when the material is compiled. This mechanism is the same one used internally by built-in nodes such as the Script node and the Shader node, making the plugin API a first-class path for custom shader logic.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 node type string registered with
plugin_material_custom_nodes_set or plugin_brush_custom_nodes_set must exactly match the type field stored in the canvas JSON for nodes of that kind. Mismatches will cause the code generator to be skipped silently.How Node Plugins Work
Register a category
The plugin calls
plugin_material_category_add (or plugin_brush_category_add) with a display name and an any_array_t * listing the node type strings that belong to it. ArmorPaint appends the category to nodes_material_categories and the node list to nodes_material_list, making it appear in the Add Node search popup.Register a code-generation callback
The plugin calls
plugin_material_custom_nodes_set(node_type, fn). Internally, ArmorPaint stores the function pointer in parser_material_custom_nodes, keyed by the node type string. When parser_material encounters a node of that type during shader compilation, it calls the registered function to obtain the GLSL/Kong expression for that node’s output.Implement the handler
The callback receives the
ui_node_t *node and the output ui_node_socket_t *socket being evaluated, and must return a char * GLSL/Kong expression string (e.g. "0.5" or "constants.my_value"). It can call node_shader_add_constant, node_shader_write_frag, or plugin_material_kong_get to modify the shader being built.Material Node Registration
any_array_t before passing it to plugin_material_category_add, then call plugin_material_custom_nodes_set once for each type.
Brush Node Registration
Brush nodes follow the same pattern but use the brush-specific API. The code generator callback for a brush node is stored inparser_logic_custom_nodes.
Accessing the Kong Material Context
plugin_material_kong_get returns the active node_shader_t * (the Kong shader context) that parser_material is currently building. Your node callback can use it to add constants, write fragment shader lines, or query whether certain features have been enabled.
Script Node — Built-in Custom Shader Injection
The Script node (SCRIPT_CPU type, defined in script_node.c) is ArmorPaint’s built-in example of custom shader injection. It exposes a single text field in which you write a GLSL/Kong expression. During material parsing, script_node_value is called; it reads the expression string, registers a CPU-side shader constant named after the node, and returns a reference to that constant for use in downstream nodes.
script_node_init, which pushes script_node_def onto nodes_material_input and maps "SCRIPT_CPU" in parser_material_node_values. This mirrors exactly what a plugin does — making the Script node a useful reference when implementing your own custom nodes.
The Snippets button on the Script node (implemented via ui_nodes_custom_buttons) shows that custom node UI can also be added using any_map_set(ui_nodes_custom_buttons, "my_button_fn", my_button_fn).
Shader Node — Raw Kong Snippet Injection
The Shader node (SHADER_GPU type, defined in shader_node.c) lets you type a raw Kong/GLSL expression directly into the node graph. Its value function is even simpler — it reads the text field and returns it verbatim as the node’s output expression:
"SHADER_GPU" in parser_material_node_values, the Shader node demonstrates that the simplest possible custom node handler is a one-liner that returns a constant or expression string.
Cleanup: Removing Categories on Plugin Stop
Always remove your categories and custom node handlers inon_delete to prevent stale entries in the node search list and dangling function pointers in parser_material_custom_nodes.