WoodBaker — the procedural texture baker the woods are made with.
Tool code: run it from a tool, a test or an execute call, never from a
component (baking one wood takes seconds).
Every field is a square n x n grid covering ONE texture repeat, and every
generator is periodic over it (integer lattice frequencies, wrapped cells,
wrapped blurs and derivatives), so every texture tiles with no seam by
construction. Distances are in metres: a recipe knows its tile size, so a
15 cm plank or a 7 x 35 cm parquet block is drawn at its real size.
Image axes: x (U) runs across the grain, y (V, image up) runs ALONG the
grain. Every wood in the collection keeps that convention.
Maps written per wood:
<id>_albedo sRGB colour, no lighting or occlusion painted in
<id>_normal tangent-space normal, green = image-up (OpenGL / glTF)
<id>_rm linear mask: R = ambient occlusion, G = roughness, B = metallic (0)
breathe( ) → void
Yield a frame once a bake has held the engine for 50 ms, so a long bake never freezes the editor.
mul32(a: number, b: number) → number
| arg | type | description |
|---|
| a | number | |
| b | number | |
rng(seed: number) → void
A deterministic random stream: rng() returns [0, 1).
| arg | type | description |
|---|
| seed | number | |
hash(a: number, b: number?, c: number?) → number
A stable 0..1 hash of up to three integers (board ids, cells).
| arg | type | description |
|---|
| a | number | |
| b | number? | |
| c | number? | |
field(n: number, v: number?) → Field
| arg | type | description |
|---|
| n | number | |
| v | number? | |
value2(n: number, fx: number, fy: number, seed: number, out: Field?, amp: number?) → Field
One octave of periodic value noise, fx cells across and fy cells along (integers), added into out scaled by amp.
| arg | type | description |
|---|
| n | number | |
| fx | number | |
| fy | number | |
| seed | number | |
| out | Field? | |
| amp | number? | |
fbm2(n: number, fx: number, fy: number, octaves: number, seed: number, gain: number?) → Field
Periodic fractal noise 0..1, octaves doubling from (fx, fy) cells; anisotropic when fx ~= fy.
| arg | type | description |
|---|
| n | number | |
| fx | number | |
| fy | number | |
| octaves | number | |
| seed | number | |
| gain | number? | |
fbm(n: number, f: number, octaves: number, seed: number, gain: number?) → Field
| arg | type | description |
|---|
| n | number | |
| f | number | |
| octaves | number | |
| seed | number | |
| gain | number? | |
worley2(n: number, cx: number, cy: number, seed: number, jitter: number?) → void
Periodic Worley cells, cx across by cy along (anisotropic cells). Returns F1, F2 (in cell units) and a 0..1 id per nearest cell.
| arg | type | description |
|---|
| n | number | |
| cx | number | |
| cy | number | |
| seed | number | |
| jitter | number? | |
blur(n: number, src: Field, r: number, passes: number?) → Field
Periodic separable box blur of radius r texels (passes times, ~gaussian at 3).
| arg | type | description |
|---|
| n | number | |
| src | Field | |
| r | number | |
| passes | number? | |
normalize(n: number, f: Field, p: number?, q: number?) → Field
Remap a field so its p-th and q-th percentiles land at 0 and 1 (clamped).
| arg | type | description |
|---|
| n | number | |
| f | Field | |
| p | number? | |
| q | number? | |
sample(n: number, f: Field, x: number, y: number) → number
Bilinear sample of a periodic field at fractional texel coordinates (x across, y along), wrapping.
| arg | type | description |
|---|
| n | number | |
| f | Field | |
| x | number | |
| y | number | |
resize(n: number, f: Field, m: number) → Field
Resample a periodic field to size m (box-filtered down, bilinear up).
| arg | type | description |
|---|
| n | number | |
| f | Field | |
| m | number | |
smoothstep(a: number, b: number, x: number) → number
| arg | type | description |
|---|
| a | number | |
| b | number | |
| x | number | |
lerp(a: number, b: number, t: number) → number
| arg | type | description |
|---|
| a | number | |
| b | number | |
| t | number | |
lin(s: number) → number
Linear value of an sRGB 0..255 colour channel, for writing palettes the way they are measured.
| arg | type | description |
|---|
| s | number | |
rgb(r: number, g: number, b: number) → void
A linear RGB triple from an sRGB hex-style triple (0..255).
| arg | type | description |
|---|
| r | number | |
| g | number | |
| b | number | |
rings(n: number, o: GrainOpts) → void
A periodic growth-ring index field (in rings) for a sawn face: the rings of a tapered log cut by the board's plane, so a flat-sawn face shows nested cathedral arches with near-straight sides, and depth ~0 gives quarter-sawn stripes. Optional knots. Returns ring field and knot mask (0..1).
| arg | type | description |
|---|
| n | number | |
| o | GrainOpts | |
latewood(r: number, width: number) → number
Latewood density 0..1 from a ring index: earlywood fades in slowly, latewood ends sharply at the ring boundary. width = latewood share of a ring.
| arg | type | description |
|---|
| r | number | |
| width | number | |
toSrgb8(c: number) → number
| arg | type | description |
|---|
| c | number | |
packAlbedo(n: number, r: Field, g: Field, b: Field) → buffer
Pack an albedo from three linear-colour fields into sRGB rgba8 bytes.
| arg | type | description |
|---|
| n | number | |
| r | Field | |
| g | Field | |
| b | Field | |
packMask(n: number, r: Field, g: Field, b: Field) → buffer
Pack three linear 0..1 fields into rgba8 bytes (R = AO, G = roughness, B = metallic).
| arg | type | description |
|---|
| n | number | |
| r | Field | |
| g | Field | |
| b | Field | |
packNormal(n: number, h: Field, tile: number, strength: number?) → buffer
Tangent-space normal map from a height field in METRES over a tile of `tile` metres. Raised areas face outward; green = image-up (OpenGL / glTF), the convention the engine reads.
| arg | type | description |
|---|
| n | number | |
| h | Field | |
| tile | number | |
| strength | number? | |
cavity(n: number, h: Field, radius: number, depth: number, strength: number?) → Field
Cavity occlusion from height: 1 on tops, darker in pits and grooves. depth in metres for full dark.
| arg | type | description |
|---|
| n | number | |
| h | Field | |
| radius | number | |
| depth | number | |
| strength | number? | |
keepSource(name: string) → any
Re-create a baked texture with a lossless source PNG beside its GPU data, so tools that read the source image (materialLibraryKit's texture-memory measure) see its real size. Settings are kept.
| arg | type | description |
|---|
| name | string | |
save(name: string, n: number, bytes: buffer, kind: string, filter: string?) → any
Write rgba8 bytes as a texture asset in the package's textures folder, with a PNG source kept. kind: color | normalMap | mask. filter: linear (default) or nearest.
| arg | type | description |
|---|
| name | string | |
| n | number | |
| bytes | buffer | |
| kind | string | |
| filter | string? | |