Batch and the command line
A scenery set is two hundred files that have to be consistent. tnmap is a standalone executable that applies
one configuration to all of them. It needs nothing installed — no runtime, no interpreter, no application.
The short version
Dial in the look in the editor. Edit ▸ Copy batch command, pick your shell, and paste. Or save a preset and point at it:
tnmap sprites/ --preset knight.tnpreset --out normals/
Usage
tnmap <files or folders...> [options]
Folders are searched for images. Every input is written as <name>_normal.png, beside its input by default.
Run control
| Flag | What it does |
|---|---|
--preset <file> | Settings saved from the editor. Flags below override it. |
--out <dir> | Write here instead of alongside each input. |
--suffix <text> | Inserted before the extension. Default _normal. |
--jobs <n> | Sprites in flight at once. Default 1. |
--dry-run | List what would be written, and stop. |
--dry-run first, always, on a folder you care about.
Method
| Flag | What it does |
|---|---|
--solution <name> | lineart (default) or luminance. See Solution type. |
--depth <n> | Luminance only: how far the surface tilts, 0 to 1. |
--smoothing <n> | Luminance only: blur passes before the slope is measured. |
A misspelled name is refused rather than assumed, and the run stops. Accepting it would mean two hundred sprites solved by the other method with nothing on the console to say so.
Under --solution luminance every flag below is ignored, since that method reads brightness and nothing else.
Surface
| Flag | What it does |
|---|---|
--polarity <n> | 1 convex, -1 concave. Under luminance, 1 reads bright as raised. |
--form <n> | Follow the overall form. 0 skips it and the extra work it costs. |
--flatten <n> | Pull the interior toward the camera. |
--axis-reach <n> | Reach of a painted tube axis, in pixels. |
--lambda <n> | Smoothness against the detail. |
--boundary-blur <n> | Outline direction smoothing. |
Drawn lines
| Flag | What it does |
|---|---|
--[no-]line-art | Read drawn strokes as folds. |
--darkness <n> | How dark a stroke must be. |
--chroma <n> | How much colour a stroke may carry. |
--relief <n> | How much darker than its surround. |
--radius <n> | Surround distance in pixels. 0 measures it per sprite. |
--fold <n> | Fold angle at a stroke, in degrees. |
--fold-weight <n> | Confidence in that fold. |
--[no-]creases | Sharp folds at strokes. |
Detail methods
Applied everywhere, since there is no painted region to scope them to.
| Flag | What it does |
|---|---|
--shading <n> | Weight: follow drawn shading. |
--bevel <n> | Weight: add bevelled volume. |
Output
| Flag | What it does |
|---|---|
--target <n> | unity, godot, unreal, opengl, directx. |
Two decisions worth knowing about
The detection radius is measured per sprite by default
A folder of artwork is usually one artist's hand at one scale, so a single radius would often do — but "usually" is not good enough when the failure is silent, and each file contains the right answer for itself.
Pass --radius <n> to fix it across the batch. Do that when consistency between frames matters more than the best reading of
each, which for an animation it usually does.
Nothing is normalised across the batch
It would be easy to rescale every output against the set's own extremes, and it would look tidier. It is also how animation flicker gets manufactured, because a frame's appearance would then depend on its neighbours. Each sprite is solved on its own terms.
Things it will refuse or warn about
- Files this tool already produced. A second run over the same folder would otherwise take its own output as input, solving a normal map as though it were artwork. Nothing about the result looks obviously wrong until an engine renders it, so outputs matching the suffix are skipped.
- Artwork with no transparency, reported per file, because that file is usually one among many and the run must not be silent about it. The file is still written; you decide.
What the command line cannot do
Hints. A hint addresses particular pixels of a particular sprite, so there is nothing sensible for it to mean applied across a folder. Painted hints live in a project or a frame batch, and exporting those from the editor is what applies them — File ▸ Export every frame… solves each frame with its own hints. See Frames and animation.
The GPU. The batch tool runs on the CPU. See Performance and hardware for why, and why it matters less than it sounds.
Getting it
The batch tool ships with the application as a single executable. Put it somewhere on your PATH and it works from any
directory.