# Sculpt Mode vs Paint Mode in ArmorPaint: Architecture and Pipeline Differences

> Explore ArmorPaint's Sculpt Mode vs Paint Mode, understanding their core architectural and pipeline differences for PBR texturing and high-precision displacement workflows.

- Repository: [Armory 3D/armorpaint](https://github.com/armory3d/armorpaint)
- Tags: architecture
- Published: 2026-09-11

---

**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`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/enums.h) (lines 87‑89), the workflow is defined as:

- **Paint Mode**: Uses `WORKFLOW_PBR` (0) or `WORKFLOW_BASE` (1)
- **Sculpt Mode**: Uses `WORKFLOW_SCULPT` (2)

When the user selects **Sculpt** from the main menu in [`paint/sources/ui/ui_menubar.c`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/util/util_layer.c), the allocation logic diverges based on the active workflow:

- **Paint Mode** creates `texpaint` targets (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`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/render/make_sculpt.c) (line 184) and accessed through `g_context->brush_sculpt`. These include specialized sculpt operations such as:

- `SCULPT_TYPE_GRAB`
- `SCULPT_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`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/render/render_path_paint.c) (lines 231‑233), the engine checks:

```c
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`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/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:

```c
// 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`](https://github.com/armory3d/armorpaint/blob/main/tab_layers.c) lines 1041‑1042) allocates the high‑precision texture:

```c
// 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:

```c
// 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_PBR` or `WORKFLOW_BASE`, while Sculpt Mode requires `WORKFLOW_SCULPT` as defined in [`enums.h`](https://github.com/armory3d/armorpaint/blob/main/enums.h).
- **Texture targets**: Paint Mode writes to standard `texpaint` buffers; Sculpt Mode requires `texpaint_sculpt` with 128‑bit floating‑point precision.
- **Brush systems**: Paint uses color/fill tools via [`ui_header.c`](https://github.com/armory3d/armorpaint/blob/main/ui_header.c); Sculpt uses displacement brushes (`SCULPT_TYPE_GRAB`, `SCULPT_TYPE_PINCH`) managed in [`make_sculpt.c`](https://github.com/armory3d/armorpaint/blob/main/make_sculpt.c).
- **Render paths**: The engine checks `layer->texpaint_sculpt` in [`render_path_paint.c`](https://github.com/armory3d/armorpaint/blob/main/render_path_paint.c) to conditionally execute `render_path_sculpt_commands()`.
- **Layer identification**: Sculpt layers are validated by `l->texpaint_sculpt != NULL` and can be baked to paint layers via `slot_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`](https://github.com/armory3d/armorpaint/blob/main/util_layer.c) (lines 660‑693), changing the workflow automatically recreates the appropriate render targets. The UI entry point in [`ui_menubar.c`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/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`](https://github.com/armory3d/armorpaint/blob/main/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.