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.

ArmorPaint shaders are written in Kong, a custom shading language that compiles to platform-specific GPU code at build time. The ashader component of amake invokes the embedded minikong compiler to translate each .kong file into HLSL (for Direct3D 12), MSL (for Metal), or SPIRV (for Vulkan). At runtime, the engine loads the pre-compiled binary shader for the active graphics API — no shader compilation happens at startup.
Kong is a custom shading language developed for the ArmorPaint / iron engine project. It is not standard GLSL, HLSL, or MSL. The minikong compiler embedded in base/sources/kong/ is based on Kongruent by RobDangerous.

Kong Language Overview

Kong shader files use a .kong extension and describe vertex and fragment (pixel) shader programs as typed functions. The language features:
  • Strongly typed scalars and vectors: float, float2, float3, float4
  • Struct definitions for vertex input/output layouts
  • fun keyword for shader function declarations
  • #[set(everything)] attribute for binding constant buffers, samplers, and textures
  • #[pipe] struct to wire vertex and fragment stages into a pipeline object
  • sample() built-in for texture sampling
Kong’s syntax is intentionally compact and maps closely to how GPU pipelines are described in modern APIs, making it straightforward to target multiple backends from a single source file.

ashader Compilation Pipeline

ashader.c (part of amake) drives shader compilation during the build. For each .kong file it produces one output per enabled target:
  1. minikong compiles .kong.hlsl source
  2. The DirectX Shader Compiler (dxc) compiles .hlsl.cso D3D bytecode
  3. The .cso file is bundled into the data/ output directory
Define: IRON_DIRECT3D12

Base Shaders

The UI renderer shaders live in base/shaders/ and are shared across all platforms:
FilePurpose
draw_image.kongRender a textured quad with per-vertex color tinting
draw_rect.kongRender a solid-color rectangle
draw_text.kongRender text glyphs from an atlas texture
draw_tris.kongRender colored triangles
line.kongRender 2D lines
line_overlay.kongRender lines drawn on top of the 3D scene

Example: draw_rect.kong

This is the simplest engine shader — it renders a colored rectangle with no texture lookup:
#[set(everything)]
const constants: {
    empty: float4;
};

struct vert_in {
    pos: float2;
    tex: float2;
    col: float4;
}

struct vert_out {
    pos: float4;
    col: float4;
}

fun draw_rect_vert(input: vert_in): vert_out {
    var output: vert_out;
    output.pos = float4(input.pos, 0.0, 1.0);
    output.col = input.col;
    return output;
}

fun draw_rect_frag(input: vert_out): float4 {
    return input.col;
}

#[pipe]
struct pipe {
    vertex = draw_rect_vert;
    fragment = draw_rect_frag;
}

Example: draw_image.kong

The textured quad shader samples a 2D texture and multiplies by per-vertex color. Note the pre-multiplied alpha output:
#[set(everything)]
const constants: {
    empty: float4;
};

#[set(everything)]
const sampler_linear: sampler;

#[set(everything)]
const tex: tex2d;

struct vert_in {
    pos: float2;
    tex: float2;
    col: float4;
}

struct vert_out {
    pos: float4;
    tex: float2;
    col: float4;
}

fun draw_image_vert(input: vert_in): vert_out {
    var output: vert_out;
    output.pos = float4(input.pos, 0.0, 1.0);
    output.tex = input.tex;
    output.col = input.col;
    return output;
}

fun draw_image_frag(input: vert_out): float4 {
    var texcolor: float4 = sample(tex, sampler_linear, input.tex) * input.col;
    texcolor.rgb = texcolor.rgb * texcolor.a * input.col.a;
    return texcolor;
}

#[pipe]
struct pipe {
    vertex = draw_image_vert;
    fragment = draw_image_frag;
}

Paint Shaders

The paint-specific shaders live in paint/shaders/ and handle all 3D viewport and painting operations:
FilePurpose
cursor.kong / cursor_decal.kongBrush cursor rendering in the viewport
mesh_posnortex.kongMesh rendering with position, normal, and UV
mesh_posnor.kongMesh rendering with position and normal
mesh_poscol.kongMesh rendering with per-vertex color
layer_copy.kong / layer_copy_bgra.kongLayer buffer copy operations
layer_merge.kongLayer compositing
layer_invert.kongLayer color inversion
dilate_pass.kong / dilate_map.kongUV dilation for seam removal
deferred_light.kongDeferred lighting pass
ssao_pass.kong / ssao_blur_pass.kongScreen-space ambient occlusion
taa_pass.kongTemporal anti-aliasing
compositor_pass.kongFinal image compositing
prefilter_envmap.kongEnvironment map pre-filtering
world_pass.kongWorld/background rendering
histogram_pass.kongHistogram computation for the color analyzer
bloom_downsample_pass.kong / bloom_upsample_pass.kongBloom effect

Material Shader Generation

ArmorPaint’s procedural material system does not use pre-written .kong files for material outputs. Instead, parser_material.c traverses the live material node graph at runtime and generates shader source code dynamically. This generated code is then compiled on-the-fly by the embedded Kong compiler (enabled via the with_kong build flag) and uploaded to the GPU. This means every change to the material node graph produces a freshly compiled shader, allowing fully procedural, node-driven materials without a fixed set of pre-authored shader permutations.

Raytrace Shaders

Hardware ray-tracing shaders live in base/shaders/raytrace/. Unlike the Kong-based UI and paint shaders, these are written directly in API-native source languages and pre-compiled to binary:
FileBackends
raytrace_brute_core.*.cso (D3D12), .spirv (Vulkan), .metal (Metal)
raytrace_brute_full.*.cso (D3D12), .spirv (Vulkan), .metal (Metal)
raytrace_bake_ao.*.cso, .spirv, .metal
raytrace_bake_light.*.cso, .spirv, .metal
raytrace_bake_bent.*.cso, .spirv, .metal
raytrace_bake_thick.*.cso, .spirv, .metal
The source files (raytrace_brute.hlsl, raytrace_brute.comp, raytrace_brute_core.metal, etc.) are in base/shaders/raytrace/src/ along with build scripts (build_dxr.bat, build_metal.sh, build_vkrt.sh). These shaders power the Brute Pathtracer — ArmorPaint’s hardware-accelerated path-tracing engine — which supports Direct3D 12 DXR, Vulkan ray tracing, and Metal ray tracing.
Developers who want to add custom shaders via a plugin can use the plugin_material_kong_get() API to hook into the material shader generation pipeline. This allows plugins to inject custom node types that produce Kong-compatible shader code fragments integrated with the standard material output.

Build docs developers (and LLMs) love