PBR Texture Baking Types and Workflows in ArmorPaint: A Complete Technical Guide
ArmorPaint supports 14 distinct PBR texture baking types—from Curvature and Normal to Ambient Occlusion and Thickness—that generate physically-based rendering maps via both rasterization and GPU ray-tracing pipelines.
PBR texture baking types and workflows in ArmorPaint enable artists to convert high-resolution sculpt detail and scene data into optimized texture maps for game engines. The baking system is implemented in the armory3d/armorpaint repository and exposes these features through the Bake Texture node and the Bake Material menu interface.
Overview of PBR Baking Architecture
The baking system in ArmorPaint distinguishes between rasterized bakes (geometry properties) and ray-traced bakes (lighting and occlusion). All bake types are defined as enumerations in paint/sources/enums.h and processed through the Bake Texture node implementation found in paint/sources/nodes_material/bake_texture_node.c.
Ray-traced bake types—including Occlusion, Lightmap, Bent Normal, and Thickness—require GPU ray-tracing support and utilize a dedicated pipeline in paint/sources/render/render_path_raytrace_bake.c.
Complete List of PBR Texture Baking Types
ArmorPaint defines 14 bake types covering geometric analysis, lighting simulation, and ID masking:
Geometry and Surface Analysis
- Curvature (
BAKE_TYPE_CURVATURE): Calculates convex and concave surface areas per texel to generate edge-wear masks. - Normal (
BAKE_TYPE_NORMAL): Transfers high-poly world-space normals onto low-poly UV layouts using RGBA128 format for precision. - Object Normal (
BAKE_TYPE_NORMAL_OBJECT): Stores object-space normals without world-space transforms, ideal for fixed-orientation assets. - Height (
BAKE_TYPE_HEIGHT): Encodes displacement data in the red channel to drive parallax occlusion mapping. - Derivative (
BAKE_TYPE_DERIVATIVE): Computes the slope/derivative of height data to capture fine surface detail. - Position (
BAKE_TYPE_POSITION): Bakes world-space XYZ coordinates into RGB channels for position-based shader effects.
Utility and ID Maps
- TexCoord (
BAKE_TYPE_TEXCOORD): Outputs raw UV coordinates for debugging or custom shader workflows. - Material ID (
BAKE_TYPE_MATERIALID): Assigns integer IDs per face based on material slot assignments. - Object ID (
BAKE_TYPE_OBJECTID): Encodes unique object identifiers for compositing and selection masks. - Vertex Color (
BAKE_TYPE_VERTEX_COLOR): Renders vertex color data into a texture format.
Ray-Traced Lighting Bakes
- Occlusion (
BAKE_TYPE_OCCLUSION): Ray-traced ambient occlusion (AO) that darkens cavities and contact shadows. - Lightmap (
BAKE_TYPE_LIGHTMAP): Bakes indirect global illumination into a static lighting texture. - Bent Normal (
BAKE_TYPE_BENT_NORMAL): Calculates AO-aware normals oriented toward open space to improve indirect lighting integration. - Thickness (
BAKE_TYPE_THICKNESS): Measures geometric thickness between front and back faces for subsurface scattering and translucency effects.
Step-by-Step PBR Baking Workflow
The ArmorPaint baking workflow follows a six-stage pipeline controlled through the Bake Texture node and global context settings.
1. Select the Bake Target
Open the Bake Texture node or select Bake Material… from the main menu (defined in paint/sources/ui/ui_menubar.c at line 328). The node's UI, implemented in bake_texture_node_button, populates a combo box with available bake types. Ray-traced options only appear when gpu_raytrace_supported() returns true.
/* UI population logic from bake_texture_node.c */
string_array_t *bakes = any_array_create_from_raw(
(void *[]){
tr("Curvature"), tr("Normal"), tr("Object Normal"),
tr("Height"), tr("Derivative"), tr("Position"),
tr("TexCoord"), tr("Material ID"), tr("Object ID"),
tr("Vertex Color"),
}, 10);
if (gpu_raytrace_supported()) {
any_array_push(bakes, tr("Occlusion"));
any_array_push(bakes, tr("Lightmap"));
any_array_push(bakes, tr("Bent Normal"));
any_array_push(bakes, tr("Thickness"));
}
ui_combo(&bake_type, bakes, tr("Bake"), false, UI_ALIGN_LEFT, true);
2. Configure Bake Settings
For ray-traced bakes, configure Samples, AO Strength, Radius, and Offset through the node interface. These values are stored in the global context:
g_context->bake_samples– Ray samples per pixelg_context->bake_ao_strength– Ambient occlusion intensity multiplierg_context->bake_type– Selected enum value fromenums.h
3. Initiate the Bake Process
When you click the Bake button (icon ICON_PLAY), the function bake_texture_node_run switches the active tool to TOOL_TYPE_BAKE, sets the context bake type, and initializes an RGBA32 render target (or RGBA128 for Normal and Height bakes requiring high precision).
4. Execute Ray-Tracing (When Applicable)
If the selected bake type requires ray-tracing, render_path_raytrace_bake_commands in render_path_raytrace_bake.c allocates three intermediate render targets (baketex0, baketex1, baketex2). The system dispatches rays iteratively based on g_context->pdirty, which tracks remaining samples.
/* Ray-trace execution snippet from render_path_raytrace_bake.c */
if (g_context->pdirty > 0) {
f32_array_t *f32a = render_path_raytrace_f32a;
f32a->buffer[0] = render_path_raytrace_frame++;
f32a->buffer[1] = g_context->bake_ao_strength;
// Additional uniforms for radius, offset, etc.
_gpu_raytrace_dispatch_rays(
any_map_get(render_path_render_targets, "baketex2")->_image,
f32a
);
}
5. Integrate Results into Layers
After completion, bake_texture_node_check_result replaces the active layer's texpaint texture with the baked output. The system automatically restores the original render-target format if temporary RGBA128 was used, and triggers UI redraws to display the result.
6. Post-Process and Export
You can now edit the baked map within the layer stack, blend it with existing textures, or export via Export → Bake to Textures for use in external game engines.
Programmatic Control and Scripting
Developers can trigger bakes programmatically by manipulating the global context structure directly:
/* Trigger a Normal bake from custom tooling */
g_context->tool = TOOL_TYPE_BAKE;
g_context->bake_type = BAKE_TYPE_NORMAL; // Select normal bake
g_context->pdirty = g_context->bake_samples; // Initialize sample counter
make_material_parse_paint_material(false); // Re-parse material for bake mode
For batch operations or automated pipelines, modify g_context->bake_ao_strength and other parameters before setting pdirty to initiate the rendering loop handled in render_path_paint.c.
Summary
- ArmorPaint provides 14 PBR texture baking types defined in
paint/sources/enums.h, ranging from geometric normals to ray-traced occlusion and thickness maps. - Two technical pipelines exist: rasterization for geometry-based bakes and GPU ray-tracing for lighting-based bakes (Occlusion, Lightmap, Bent Normal, Thickness).
- RGBA128 precision is allocated automatically for Normal and Height bakes, while standard RGBA32 handles other types.
- The Bake Texture node in
bake_texture_node.corchestrates UI presentation, context configuration, and result integration. - Ray-traced workflows utilize three intermediate render targets managed by
render_path_raytrace_bake.cwith configurable sample counts and strength parameters.
Frequently Asked Questions
What is the difference between Normal and Object Normal baking in ArmorPaint?
Normal (BAKE_TYPE_NORMAL) stores world-space normals relative to the scene coordinate system, which is essential for assets that rotate or move in game worlds. Object Normal (BAKE_TYPE_NORMAL_OBJECT) stores normals relative to the object's local coordinate system, making it ideal for static objects where the orientation never changes. Both use RGBA128 format for high-precision normal vector storage.
Which PBR texture baking types require GPU ray tracing support?
The Occlusion, Lightmap, Bent Normal, and Thickness bake types require active GPU ray-tracing capabilities. These are conditionally added to the UI only when gpu_raytrace_supported() returns true, as implemented in the bake_texture_node_button function. All other bake types (Normal, Height, Curvature, etc.) work on standard rasterization hardware.
How does ArmorPaint handle high-poly to low-poly normal map baking?
When you select Normal or Object Normal from the bake types, ArmorPaint uses the high-poly mesh as the source for surface detail while projecting onto the low-poly UV layout. The system automatically creates an RGBA128 render target to preserve fine surface details without banding artifacts, then transfers the result to the layer's texpaint texture via bake_texture_node_check_result.
What is the difference between Height and Derivative bakes?
Height (BAKE_TYPE_HEIGHT) stores absolute displacement values in the red channel, representing how much geometry protrudes or recedes from the surface plane. Derivative (BAKE_TYPE_DERIVATIVE) calculates the mathematical derivative (slope) of that height field, capturing surface steepness rather than elevation. Derivative maps are often combined with height data to improve bump mapping accuracy in shaders that calculate surface gradients.
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 →