AshForge Canvas · Texturing

The Canvas Bench

Everything Canvas can do to a surface, in the order you'd actually do it — and the reasons professional texture artists do it that way. Built for the modder who has a mesh and wants it looking like it belongs in Ascent of Ashes by tonight.

Companion to Mod Kit Accelerated·Verified against Canvas main·2026-08-26

Canvas paints in six PBR channels at once, with a layer stack per channel, non-destructive masks, and curvature-driven wear that reads your mesh's own geometry. That combination is what separates it from "a paint program that draws on a model" — and it's the part most people never switch on, because nothing on screen tells you it's there.

This page is the missing instruction. Every control named here exists in the shipping build; every number is one you can type in. Where a technique comes from wider practice rather than from Canvas, it's marked as such and sourced at the bottom.

Before you start

Canvas installs from the Hub like every other suite tool — and, like every other tool, it opens from the Hub, not from its own shortcut. Windows, Linux AppImage, and the update feed are all live.

Step 01Get a mesh that can hold paint

Painting is UV-bound. Canvas picks the triangle under your cursor, converts the hit to a UV coordinate, and stamps into the texture there. No UVs, no paint — so the first thing to settle is whether your model has a usable layout.

Open one with Open Model…. If it arrives without UVs, Canvas says so in the status line. Fix it from the Auto-UV menu, which offers five routes:

RouteWhat it doesReach for it when
xatlasIndustry-standard atlas packer, best overall qualityDefault answer. Start here.
Smart (angle-based)Splits charts on angle thresholdsOrganic or faceted shapes where xatlas over-fragments
Box projectionSix-way projection into a 3×2 gridCrates, panels, anything essentially cuboid
Planar — Top (Y)Single-axis projectionFlat ground pieces, decals, signage
Planar — Front (Z) / Side (X)As above, other axesWall panels, façades

Auto-UV changes nothing you can see — it rewrites coordinates, not pixels. So Canvas flips on the UV Checker automatically when it finishes. Read the checker before you paint a single stroke: squares should be square and roughly the same size everywhere. Stretched squares mean stretched texture. Squares that shrink on one part mean that part gets less resolution than its neighbours.

That second reading is texel density — pixels per unit of world space — and keeping it uniform across an asset is what makes a set of props look like they come from one world rather than a bring-and-buy sale. Ascent of Ashes is played at a fixed isometric distance, which is a gift: you can pick one density and hold it everywhere, because nothing is ever inspected from 20cm away. Set it by what the camera actually resolves, not by what looks crisp in the Canvas viewport with your nose against it.

From the bench

Open UV Layout alongside the checker. It draws the wireframe of your charts over the current channel, so you can see where a seam is about to fall. A seam through the middle of a face you'll paint detail on is a seam you'll fight all night; rotate the model and re-run Auto-UV rather than paint across it.

Step 02Six channels, one material

This is the mental model everything else hangs off. Canvas doesn't have "a texture". It has six independent layer stacks, each compositing over its own neutral base into its own image, all six feeding one material at once.

SIX STACKS ONE MATERIAL Albedo layers → base coat Normal layers → flat 128,128,255 Roughness layers → mid grey Metallic layers → black AO layers → white Emissive layers → black composite texture texture texture texture texture texture StandardMaterial3D one material on the model viewport
Why nothing happens when you paint the wrong channel. The Channel selector at the top of the side panel decides which of these six stacks your brush writes into. Every layer operation — add, delete, mask, blend mode, opacity — acts on the active channel only. Each channel composites over a different neutral, which is why an empty Roughness reads mid-grey while an empty Metallic reads black.

Two controls make this stack legible while you work:

Step 03Values that don't lie

PBR is a physical model, and it punishes invented numbers. Albedo that's too dark starves global illumination; metallic that sits at 0.5 describes a material that doesn't exist. The ranges below come from measured references (sourced at the end), translated into what you actually type into Canvas.

ChannelPaint withWorking rangeThe rule
AlbedoColour sRGB 50–240 Nothing in nature is pure black or pure white. Charcoal bottoms out near 50; fresh snow tops out near 240.
MetallicGrayscale 0 or 255 Binary in practice. A surface is metal or it isn't. Mid-greys only appear where metal is partly covered — paint, rust, grime — and then the mask does the blending, not the value.
RoughnessGrayscale 25–235 Your busiest channel. Perfect mirrors and perfect diffusers are both rare; variation here sells a surface faster than albedo detail.
NormalRaw RGB 128,128,255 = flat Don't hand-paint this. Paint height in grayscale and use Height → Normal.
AOGrayscale White = open Contact shadow only. Use Bake AO rather than painting it.
EmissiveColour Black = off Only what actually emits light. Bright albedo is not emission.

The trap that ruins most first attempts

Don't paint lighting into albedo. Highlights, shading, and baked-in shadow belong to the renderer, not the base colour. If you paint a bright streak on the top edge because it looks good in your current viewport, it will still be there when the light moves — and it will look wrong from every angle but one. Albedo answers "what colour is this material"; nothing else.

Step 04The whole point: smart material layers

This is the feature worth learning Canvas for, and it's two clicks deep in a tab most people never open.

A material layer — added by clicking a card in the Materials tab — is not a flood fill. It creates a linked fill layer in every channel the preset defines, and gives all of them one shared mask, black. Black means hidden. So the material is loaded into all six channels at once, and invisible.

Then you paint the mask, and the entire PBR material appears where you brush — colour, roughness, metalness, all together, with everything under it untouched.

Materials tab click a card creates LINKED FILL LAYERS Albedo fill Roughness fill Metallic fill AO fill (whichever channels the preset defines) all of them share ONE mask, by reference shared mask black = hidden paint white Edit mask brushed reveal every channels at once
One mask, every channel at once. Because the mask is shared by reference, a single stroke reveals the material's colour, roughness, metalness and occlusion together — physically coherent by construction. Deleting the layer removes it from every channel atomically, so a channel can never be left holding half a material.

What a "material" actually contains — read this before you expect too much

The eight cards are flat per-channel values, not textures. "Rough Stone" is a brown at roughness 0.9 with metallic 0; "Brushed Metal" is a grey at a low roughness with metallic 1. There is no stone grain in one and no anisotropic brushing in the other — and most presets define four channels (Albedo Roughness Metallic AO), not all six.

So the mechanism is the professional part; the library is eight starting points. Every scrap of character comes from what you brush on top — which is what Steps 05 through 08 are for. Set your expectations there and the workflow makes sense; expect a texture library and you'll wonder why your stone looks like brown plastic.

There is also currently no way to save your own. MaterialPresets is a fixed list compiled into the program, with no load-from-disk path. Build a recipe you love and you rebuild it next time, by hand.

Driving it

From the bench

Reach for + Fill plus a mask instead of brushing raw colour whenever you might change your mind. A fill layer's colour stays editable forever; brushed pixels don't. Professional texture work is mostly masks over fills — the brush shapes where, almost never what.

Step 05Wear that reads as history

Uniform grunge looks like noise. Believable wear is positional — it appears where physics puts it. Edges and corners get knocked and rubbed until the material underneath shows through; recesses and crevices collect dust and grime that nothing wipes out.

Canvas computes both from your mesh's own geometry. Edge Wear and Cavity Dirt bake a curvature estimate — comparing each vertex normal against its neighbours — into a UV-space map, then composite your brush colour through it.

YOUR MESH convex concave bake curvature map bright = convex Edge Wear exposed edges → base metal Cavity Dirt recesses → dust, grime active layer
Geometry decides where the story goes. The curvature bake is cached per mesh, so the second click is instant. Both buttons composite into the active layer of the active channel — which means you can run Edge Wear into a mask just as easily as into colour, and that is usually the better move.

The professional move

Don't run Edge Wear directly onto albedo. Add a material layer for the material underneath — bare metal under paint, say — then run Edge Wear into that layer's mask with Edit mask on. Now the worn edges reveal a full PBR material rather than a paler colour: the exposed metal is genuinely metallic and genuinely smoother, because it's a real material showing through, not a lighter shade pretending.

Then break the perfection. Curvature wear applied at full strength wraps every edge evenly, which reads as machine-made. Set the brush to Erase with the Noise (grunge) tip and knock holes in the wear mask so the wear becomes intermittent — heavy where a hand or a crate would actually strike, absent where nothing reaches.

From the bench

Ask "what happened to this object" before you texture it, and let the answer choose the wear. A colony's cooking pot is worn on the rim and the handle and sooty underneath. A gun is worn where it's gripped, holstered and dropped. Wear applied by rule looks generated; wear applied by story looks made.

Step 06The brush bench

Eight modes, four tips, and the sliders that decide whether a stroke reads as a stroke or as a surface.

ModeDoesTexturing use
Paint / EraseDeposit / removeEverything. In mask editing, reveal / conceal.
CloneCopies from an offset source — Ctrl+click to set itRepairing a seam; repeating a detail without re-painting it
SmudgePicks up and drags colourStreaks, drips, pulling grime downward with gravity
Blur / SharpenSoftens / crispens what's thereBlur a mask edge to kill a hard cut; sharpen a worn edge to bite
Dodge / BurnLightens / darkens existing pixelsValue variation without recolouring. Superb on roughness.

Tips

The four sliders that matter

ControlWhat it changesSetting it
OpacityCeiling of a single dabLow (10–25%) for anything you want to build up in passes
FlowRate of deposit per dabLow flow + high opacity = airbrush-like build-up along a stroke
SpacingGap between dabs, as a fraction of radiusTight for solid strokes; wide turns any tip into a scatter stamp
StabilizerSmooths cursor jitterRaise it for long panel lines and cable runs. Lower it for organic grime.

Two more worth switching on: Pen pressure (independently to opacity and size) if you have a tablet, and Preset — save a brush you've dialled in, recall it later. A grunge brush you tuned once and named is worth more than any single texture you'll paint with it.

Symmetry, stencils, decals

Step 07Let the mesh do the work

Two bakes turn geometry into texture data, and both save hours of hand-painting.

Bake AO casts rays per vertex to measure how occluded each point is, and writes the result into the AO channel. Run it once, early, after your UVs are final. It's synchronous and dense meshes take a moment — that's raytracing, not a hang.

Height → Normal reads the active layer's luminance as a height field and converts it to a tangent-space normal map with a Sobel filter, controlled by Height strength. This is how you get surface relief without sculpting: paint your rivets, panel gaps, scratches and weld beads in grayscale — bright is raised, dark is recessed — then convert. Painting normal maps by hand is a losing game; painting height is intuitive.

Order matters

Bake AO after UVs are final and before you invest in painting. Re-running Auto-UV invalidates everything baked into UV space, and the curvature cache clears when the mesh changes. Settle geometry, settle UVs, bake, then paint.

Step 08The grime pass that ties it together

This is the last 10% that separates a texture set from a texture. When an asset has three or four materials on it, each individually correct, it still reads as parts bolted together — because nothing has happened to them as one object.

The fix is a single unifying pass on top of everything:

  1. 1Add a new layer at the top of the Albedo stack.
  2. 2Set its blend mode to Multiply and its opacity low — 10–20%.
  3. 3Pick a desaturated, slightly warm dark — the colour of the world's dust, not black.
  4. 4Paint with the Noise (grunge) tip at large size across the whole model, ignoring material boundaries entirely.
  5. 5Add the same pass to Roughness — dirt is rougher than what it lands on, and this is the half most people skip.

Because it crosses every material boundary, it makes the object read as one thing that has sat in one place. For Ascent of Ashes specifically, this is also where you pull a bright asset back into the game's muted, grounded palette — a warm grey multiply at 15% does more to make a prop belong than any amount of albedo tweaking.

From the bench

Use Layer groups to keep this navigable. Collapse "Base", "Wear", "Grime" and you can reason about the asset instead of scrolling a stack of thirty. Group opacity lets you dial an entire pass up and down in one control — the fastest way to answer "is this too much?" is to halve the group and look again.

Step 09Judge it honestly

A texture that looks great under one light is a texture you can't ship. The Scene tab exists to stop you fooling yourself.

Step 10Ship it

Set Texture resolution in the Scene tab before the final pass — 1024 / 2048 / 4096. Changing it resamples every layer and mask across all channels with Lanczos filtering, but it also clears undo history, so decide before you're deep in.

For an isometric colony sim, 1024 covers most props comfortably and 2048 is generous. Resolution you can't see is GPU cost the player pays for nothing.

ExportProducesUse for
Export GLB…Self-contained .glb, textures embeddedHanding the asset to anything that reads glTF
Export Texture Maps…Six PNGs, one per channelTaking the maps into another engine or tool
Export as Mod…Full mod folder — manifest, scene, modelThe straight line from Canvas to a loadable mod
Export Per-Surface…Separate GLB + PNGs per original mesh partMulti-part models that need independent materials
Send to Crucible…Exports and launches the Crucible on itSeeing it in a real scene immediately

ReferenceShortcuts and rescue

KeyDoes
Alt + clickEyedropper. Samples the composited colour under the cursor into the brush, in any mode. Use it constantly to keep a palette tight.
Ctrl + clickSets the clone source (Clone mode only)
Ctrl + ZUndo — 20 deep, covers strokes, fills, bakes, smart masks and adjustments
Ctrl + Y · Ctrl+Shift+ZRedo

Adjust Active Layer… gives brightness, contrast, hue, saturation and invert with live preview — the values apply as you drag and revert cleanly if you cancel, so it's safe to explore. Invert is the quickest fix in the program: a mask that's revealing exactly the wrong areas is one click from correct.

Save early

.canvas projects keep every channel's layer stack, masks, fill layers, material-layer links and groups. Exported textures are the output; the .canvas file is the work. Save it before every bake and every resolution change — those are the two operations that clear undo.