Sculpt Mode vs Paint Mode in ArmorPaint: Architecture and Pipeline Differences
ArmorPaint’s Sculpt Mode and Paint Mode represent distinct workflow architectures governed by the g_config->workflow enumeration, where Paint Mode targets standard PBR texture maps via texpaint buffers while Sculpt Mode operates on high-precision displacement textures (texpaint_sculpt) using specialized sculpt brushes and separate render commands.
ArmorPaint is an open-source 3D texture painting application that supports two fundamentally different creative workflows. The system distinguishes between these modes through the g_config->workflow configuration value defined in paint/sources/enums.h, which determines texture allocation, brush behavior, and render pipeline routing.
Workflow Enumeration and Core Architecture
The primary distinction begins with the workflow constant assigned to the global configuration. In paint/sources/enums.h (lines 87‑89), the workflow is defined as:
- Paint Mode: Uses
WORKFLOW_PBR(0) orWORKFLOW_BASE(1) - Sculpt Mode: Uses
WORKFLOW_SCULPT(2)
When the user selects Sculpt from the main menu in paint/sources/ui/ui_menubar.c (line 788), the application sets g_config->workflow = WORKFLOW_SCULPT and triggers a complete reinitialization of the layer system. This switch allocates an entirely different class of render targets and redirects brush input to the sculpt-specific pipeline.
Texture Targets and Memory Layout
Paint Mode and Sculpt Mode write to fundamentally different GPU textures. In paint/sources/util/util_layer.c, the allocation logic diverges based on the active workflow:
- Paint Mode creates
texpainttargets (lines 30‑38) for base color, metallic, roughness, and other PBR channels using standard precision formats. - Sculpt Mode allocates
texpaint_sculpt(lines 119‑132) as a 128‑bit floating‑point texture (GPU_TEXTURE_FORMAT_RGBA128) to store high‑precision displacement data.
Sculpt Mode additionally maintains auxiliary render targets including texpaint_sculpt_base and texpaint_sculpt_ref for intermediate displacement calculations, whereas Paint Mode relies solely on the standard PBR texture stack.
Brush Systems and Tool Architecture
The brush engines differ significantly between the two modes. In paint/sources/ui/ui_header.c (line 382), the UI exposes standard paint brushes—color, fill, erase, and masking tools—that manipulate the texpaint buffers directly.
Conversely, Sculpt Mode brushes are defined in paint/sources/render/make_sculpt.c (line 184) and accessed through g_context->brush_sculpt. These include specialized sculpt operations such as:
SCULPT_TYPE_GRABSCULPT_TYPE_PINCH- Flatten and Smooth variants
These tools do not paint color values; instead, they deform the mesh by writing displacement vectors to the texpaint_sculpt texture.
Render Pipeline Execution
The render path conditionally executes sculpt commands only when valid sculpt data exists. In paint/sources/render/render_path_paint.c (lines 231‑233), the engine checks:
if (g_context->layer->texpaint_sculpt != NULL && !picking_tool && !g_context->material_preview) {
render_path_sculpt_commands(); // Lines 510‑518
}
Paint Mode executes the standard pipeline defined in render_path_paint.c, drawing directly to the PBR targets. Sculpt Mode invokes render_path_sculpt_commands() to dispatch compute shaders that process displacement data. When g_context->layer->texpaint_sculpt is NULL, the engine skips all sculpt commands and reverts to standard painting (line 231).
Layer Management and Identification
Layers are type‑tagged by the presence of specific texture pointers. In paint/sources/ui/ui_view2d.c (line 218), the UI identifies sculpt layers by checking l->texpaint_sculpt != NULL, while regular paint layers satisfy l->texpaint != NULL.
The context menu logic in paint/sources/ui/tab_layers.c (lines 927‑937) exposes different operations based on this distinction. Sculpt layers feature an Apply Sculpt command that bakes displacement data into the standard PBR maps.
Creating and Switching Modes Programmatically
To switch workflows in code, set the global configuration and reinitialize the layer path:
// Force Sculpt workflow
g_config->workflow = WORKFLOW_SCULPT;
/* Re‑initialise render targets for sculpting */
layers_new_path_layer_sculpt_init(NULL);
Creating a dedicated sculpt layer (triggered from tab_layers.c lines 1041‑1042) allocates the high‑precision texture:
// Called from the UI "Sculpt Layer" button
void tab_layers_button_new_sculpt_layer(void *_) {
sculpt_layers_create_sculpt_layer(); // allocates texpaint_sculpt
sys_notify_on_next_frame(&tab_layers_button_new_sculpt_layer, NULL);
}
Applying Sculpt Data to Paint Layers
To merge sculpt displacement into standard PBR textures, the Apply Sculpt command invokes:
// Context‑menu command "Apply Sculpt"
void tab_layers_draw_layer_context_menu_apply_sculpt(void *_) {
slot_layer_apply_sculpt(l); // merges texpaint_sculpt into l->texpaint
sys_notify_on_next_frame(&tab_layers_draw_layer_context_menu_apply_sculpt, NULL);
}
This operation samples the texpaint_sculpt texture and bakes the displacement into the layer’s base color and normal maps, allowing the sculpted detail to persist after switching back to Paint Mode.
Summary
- Workflow constants: Paint Mode uses
WORKFLOW_PBRorWORKFLOW_BASE, while Sculpt Mode requiresWORKFLOW_SCULPTas defined inenums.h. - Texture targets: Paint Mode writes to standard
texpaintbuffers; Sculpt Mode requirestexpaint_sculptwith 128‑bit floating‑point precision. - Brush systems: Paint uses color/fill tools via
ui_header.c; Sculpt uses displacement brushes (SCULPT_TYPE_GRAB,SCULPT_TYPE_PINCH) managed inmake_sculpt.c. - Render paths: The engine checks
layer->texpaint_sculptinrender_path_paint.cto conditionally executerender_path_sculpt_commands(). - Layer identification: Sculpt layers are validated by
l->texpaint_sculpt != NULLand can be baked to paint layers viaslot_layer_apply_sculpt().
Frequently Asked Questions
How do I switch from Paint Mode to Sculpt Mode in ArmorPaint?
Set g_config->workflow = WORKFLOW_SCULPT and call the layer initialization routine. According to util_layer.c (lines 660‑693), changing the workflow automatically recreates the appropriate render targets. The UI entry point in ui_menubar.c (line 788) triggers sculpt_layers_create_sculpt_layer(), which allocates the high‑precision texpaint_sculpt texture required for displacement editing.
What texture format does Sculpt Mode use for displacement?
Sculpt Mode allocates texpaint_sculpt as a 128‑bit floating‑point texture (GPU_TEXTURE_FORMAT_RGBA128) as implemented in util_layer.c (lines 119‑132). This format provides the numerical precision necessary for high‑frequency displacement data, whereas Paint Mode uses standard 8‑bit or 16‑bit textures for color and material channels.
Why are sculpt brushes different from standard paint brushes?
Sculpt brushes manipulate geometric displacement rather than surface color. In make_sculpt.c (line 184), sculpt brush types like SCULPT_TYPE_GRAB and SCULPT_TYPE_PINCH are stored in g_context->brush_sculpt and processed by the render_path_sculpt_commands() pipeline. These tools write to the texpaint_sculpt render targets using compute shaders, while paint brushes update the texpaint PBR buffers through the standard rasterization path.
Can I convert Sculpt Mode data into regular PBR textures?
Yes. The Apply Sculpt operation in tab_layers.c calls slot_layer_apply_sculpt(l), which samples the displacement data from l->texpaint_sculpt and bakes it into the layer’s standard PBR textures. This merges the sculpt detail into the base color and normal maps, allowing you to continue editing in Paint Mode while preserving the sculpted surface detail.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →