@developerz.ai/ts23d 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/CLAUDE.md +1 -1
  3. package/README.md +10 -5
  4. package/dist/{chunk-a8fxakcj.js → chunk-6b05mnmx.js} +2 -2
  5. package/dist/{chunk-kgvbpqqw.js → chunk-7rtfjh9f.js} +6 -5
  6. package/dist/chunk-7rtfjh9f.js.map +10 -0
  7. package/dist/{chunk-1ypfs7ga.js → chunk-8j4c28jt.js} +790 -276
  8. package/dist/chunk-8j4c28jt.js.map +46 -0
  9. package/dist/{chunk-wtqhq529.js → chunk-d1fv6hrm.js} +6 -6
  10. package/dist/{chunk-wtqhq529.js.map → chunk-d1fv6hrm.js.map} +1 -1
  11. package/dist/{chunk-gcyp9b4d.js → chunk-dbq4qf52.js} +362 -215
  12. package/dist/chunk-dbq4qf52.js.map +25 -0
  13. package/dist/{chunk-xnt2sdhf.js → chunk-drna2rny.js} +2 -2
  14. package/dist/{chunk-ravbb06q.js → chunk-dxvypr7y.js} +2 -2
  15. package/dist/{chunk-11v28977.js → chunk-f6yme003.js} +85 -71
  16. package/dist/{chunk-11v28977.js.map → chunk-f6yme003.js.map} +6 -6
  17. package/dist/{chunk-4ddzsqtc.js → chunk-hg7pf34j.js} +4 -3
  18. package/dist/{chunk-4ddzsqtc.js.map → chunk-hg7pf34j.js.map} +5 -5
  19. package/dist/{chunk-w1zyhj40.js → chunk-jq4e17tj.js} +2 -2
  20. package/dist/{chunk-kvcep7ft.js → chunk-y63c6zcv.js} +967 -218
  21. package/dist/chunk-y63c6zcv.js.map +53 -0
  22. package/dist/cli/args.d.ts +7 -1
  23. package/dist/cli/bin.js +66 -25
  24. package/dist/cli/bin.js.map +6 -5
  25. package/dist/cli/manifest.d.ts +5 -1
  26. package/dist/cli/texture-cache.d.ts +4 -0
  27. package/dist/core/definition.d.ts +7 -0
  28. package/dist/core/errors.d.ts +1 -1
  29. package/dist/core/index.js +1 -1
  30. package/dist/export/credits.d.ts +4 -0
  31. package/dist/export/glb-options.d.ts +48 -0
  32. package/dist/export/glb.d.ts +5 -35
  33. package/dist/export/hierarchy.d.ts +23 -0
  34. package/dist/export/index.d.ts +2 -1
  35. package/dist/export/index.js +21 -7
  36. package/dist/export/index.js.map +1 -1
  37. package/dist/export/lod-coverage.d.ts +12 -0
  38. package/dist/export/metadata.d.ts +2 -0
  39. package/dist/export/version.d.ts +2 -2
  40. package/dist/grammar/index.js +2 -2
  41. package/dist/index.js +63 -17
  42. package/dist/index.js.map +1 -1
  43. package/dist/kinds/head-armour.d.ts +3 -7
  44. package/dist/kinds/head-bust.d.ts +3 -2
  45. package/dist/kinds/head-face.d.ts +3 -1
  46. package/dist/kinds/head-garb.d.ts +4 -0
  47. package/dist/kinds/head-mesh.d.ts +4 -0
  48. package/dist/kinds/head-mouth.d.ts +4 -0
  49. package/dist/kinds/head-params.d.ts +9 -1
  50. package/dist/kinds/head-tone.d.ts +10 -0
  51. package/dist/kinds/head-torso.d.ts +35 -0
  52. package/dist/kinds/index.js +6 -6
  53. package/dist/material/cc0.d.ts +4 -0
  54. package/dist/material/define.d.ts +34 -0
  55. package/dist/material/generator.d.ts +1 -1
  56. package/dist/material/index.d.ts +8 -3
  57. package/dist/material/index.js +39 -7
  58. package/dist/material/index.js.map +1 -1
  59. package/dist/material/library.d.ts +7 -0
  60. package/dist/material/material-def.d.ts +30 -0
  61. package/dist/material/paint/canvas.d.ts +7 -0
  62. package/dist/material/paint/default-sheet.d.ts +3 -1
  63. package/dist/material/paint/fabric.d.ts +4 -0
  64. package/dist/material/paint/image-strip.d.ts +4 -0
  65. package/dist/material/paint/kit.d.ts +5 -0
  66. package/dist/material/paint/metal.d.ts +3 -0
  67. package/dist/material/paint/orm.d.ts +1 -1
  68. package/dist/material/paint/strip.d.ts +1 -1
  69. package/dist/material/paint/types.d.ts +32 -2
  70. package/dist/material/palette.d.ts +2 -0
  71. package/dist/material/slots.d.ts +5 -0
  72. package/dist/material/texture-source.d.ts +34 -0
  73. package/dist/material/trim-sheet.d.ts +20 -4
  74. package/dist/neural/index.js +2 -2
  75. package/dist/passes/index.js +2 -2
  76. package/dist/primitives/index.js +3 -3
  77. package/dist/qa/index.js +2 -2
  78. package/dist/render/beauty.d.ts +1 -1
  79. package/dist/render/index.js +3 -3
  80. package/dist/render/lighting.d.ts +7 -0
  81. package/dist/render/shade.d.ts +1 -1
  82. package/dist/testing/index.js +5 -5
  83. package/docs/README.md +4 -0
  84. package/docs/architecture/gltf-capabilities.md +38 -1
  85. package/docs/architecture/materials.md +151 -0
  86. package/docs/idea/10-sculpting.md +166 -0
  87. package/docs/idea/11-materials-authoring.md +132 -0
  88. package/docs/idea/12-blender-bridge.md +136 -0
  89. package/docs/idea/13-asset-pipeline-research.md +89 -0
  90. package/docs/plans/roadmap.md +12 -0
  91. package/package.json +2 -1
  92. package/recipes/boxcar/README.md +7 -0
  93. package/recipes/boxcar/boxcar.ts +118 -34
  94. package/recipes/goblin_head/README.md +27 -14
  95. package/recipes/goblin_head/goblin_head.ts +11 -9
  96. package/recipes/human_head/README.md +8 -4
  97. package/recipes/human_head/human_head.ts +4 -3
  98. package/recipes/material_swatches/material_swatches.ts +11 -5
  99. package/recipes/orc_head/README.md +32 -20
  100. package/recipes/orc_head/orc_head.ts +9 -7
  101. package/src/cli/args.ts +16 -3
  102. package/src/cli/manifest.ts +6 -0
  103. package/src/cli/run.ts +33 -9
  104. package/src/cli/texture-cache.ts +24 -0
  105. package/src/core/asset.ts +1 -0
  106. package/src/core/definition.ts +7 -0
  107. package/src/core/errors.ts +6 -1
  108. package/src/export/credits.ts +25 -0
  109. package/src/export/glb-options.ts +53 -0
  110. package/src/export/glb.ts +100 -113
  111. package/src/export/hierarchy.ts +122 -0
  112. package/src/export/index.ts +17 -1
  113. package/src/export/lod-coverage.ts +71 -0
  114. package/src/export/metadata.ts +3 -0
  115. package/src/export/version.ts +1 -1
  116. package/src/kinds/head-armour.ts +103 -73
  117. package/src/kinds/head-bust.ts +49 -86
  118. package/src/kinds/head-face.ts +94 -74
  119. package/src/kinds/head-garb.ts +181 -0
  120. package/src/kinds/head-hair.ts +74 -33
  121. package/src/kinds/head-mesh.ts +43 -5
  122. package/src/kinds/head-mouth.ts +111 -0
  123. package/src/kinds/head-params.ts +11 -2
  124. package/src/kinds/head-presets.ts +30 -27
  125. package/src/kinds/head-tone.ts +52 -0
  126. package/src/kinds/head-torso.ts +230 -0
  127. package/src/kinds/head.ts +8 -3
  128. package/src/material/cc0.ts +41 -0
  129. package/src/material/define.ts +130 -0
  130. package/src/material/generator.ts +15 -8
  131. package/src/material/index.ts +34 -3
  132. package/src/material/library.ts +196 -0
  133. package/src/material/material-def.ts +84 -0
  134. package/src/material/paint/canvas.ts +11 -1
  135. package/src/material/paint/compose.ts +1 -1
  136. package/src/material/paint/decode-png.ts +19 -13
  137. package/src/material/paint/default-sheet.ts +40 -28
  138. package/src/material/paint/fabric.ts +63 -0
  139. package/src/material/paint/image-strip.ts +88 -0
  140. package/src/material/paint/kit.ts +37 -0
  141. package/src/material/paint/masks.ts +3 -1
  142. package/src/material/paint/metal.ts +109 -0
  143. package/src/material/paint/orm.ts +14 -1
  144. package/src/material/paint/planks.ts +49 -4
  145. package/src/material/paint/strip.ts +35 -29
  146. package/src/material/paint/types.ts +45 -2
  147. package/src/material/paint/validate.ts +19 -3
  148. package/src/material/palette.ts +3 -0
  149. package/src/material/slots.ts +18 -0
  150. package/src/material/texture-source.ts +86 -0
  151. package/src/material/trim-sheet.ts +79 -13
  152. package/src/render/beauty.ts +2 -2
  153. package/src/render/lighting.ts +26 -0
  154. package/src/render/shade.ts +10 -5
  155. package/dist/chunk-1ypfs7ga.js.map +0 -42
  156. package/dist/chunk-gcyp9b4d.js.map +0 -22
  157. package/dist/chunk-kgvbpqqw.js.map +0 -10
  158. package/dist/chunk-kvcep7ft.js.map +0 -43
  159. /package/dist/{chunk-a8fxakcj.js.map → chunk-6b05mnmx.js.map} +0 -0
  160. /package/dist/{chunk-xnt2sdhf.js.map → chunk-drna2rny.js.map} +0 -0
  161. /package/dist/{chunk-ravbb06q.js.map → chunk-dxvypr7y.js.map} +0 -0
  162. /package/dist/{chunk-w1zyhj40.js.map → chunk-jq4e17tj.js.map} +0 -0
@@ -0,0 +1,53 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/material/cc0.ts", "../src/material/library.ts", "../src/material/palette.ts", "../src/material/texture-source.ts", "../src/material/material-def.ts", "../src/material/paint/default-sheet.ts", "../src/material/slots.ts", "../src/material/trim-sheet.ts", "../src/material/define.ts", "../src/material/paint/noise.ts", "../src/material/paint/canvas.ts", "../src/material/paint/shapes.ts", "../src/material/paint/cells.ts", "../src/material/paint/cells-round.ts", "../src/material/paint/foliage-common.ts", "../src/material/paint/orm.ts", "../src/material/paint/foliage-raster.ts", "../src/material/paint/foliage-broad.ts", "../src/material/paint/foliage-compound.ts", "../src/material/paint/foliage-conifer.ts", "../src/material/paint/foliage.ts", "../src/material/paint/decode-png.ts", "../src/material/paint/stamp.ts", "../src/material/paint/courses.ts", "../src/material/paint/bond.ts", "../src/material/paint/concrete.ts", "../src/material/paint/fabric.ts", "../src/material/paint/image-strip.ts", "../src/material/paint/kit.ts", "../src/material/paint/masks.ts", "../src/material/paint/metal.ts", "../src/material/paint/planks.ts", "../src/material/paint/plates.ts", "../src/material/paint/slate.ts", "../src/material/paint/surface.ts", "../src/material/paint/strip.ts", "../src/material/paint/cell.ts", "../src/material/paint/normal.ts", "../src/material/paint/compose.ts", "../src/material/paint/validate.ts", "../src/material/generator.ts", "../src/material/shader-godot.ts", "../src/material/shader-three.ts", "../src/material/shader.ts"],
4
+ "sourcesContent": [
5
+ "// Ready-made CC0 image materials (opt-in, never registered by default, so the repo paints offline).\n// Register with `defineMaterial(CC0_WOOD_PLANKS_GREY)`, fetch once with `bun run textures`, then\n// `provideTextures(await loadTextureCache())` before painting. Hashes pin the exact bytes.\n\nimport type { MaterialDef } from './material-def.ts';\n\nconst PH = 'https://dl.polyhaven.org/file/ph-assets/Textures/png/1k/wood_planks_grey';\n\n/** Poly Haven \"Wood Planks Grey\" by Rob Tuytel (CC0), 1.5 m square, 1k PNG maps. */\nexport const CC0_WOOD_PLANKS_GREY: MaterialDef = {\n id: 'ph_wood_planks_grey',\n kind: 'flat',\n scaleMetres: 0.6,\n roughness: 0.85,\n description: 'Photo-scanned weathered grey planks (Poly Haven, CC0).',\n sources: ['https://polyhaven.com/a/wood_planks_grey'],\n texture: {\n source: 'polyhaven',\n id: 'wood_planks_grey',\n license: 'CC0-1.0',\n page: 'https://polyhaven.com/a/wood_planks_grey',\n author: 'Rob Tuytel',\n metres: [1.5, 1.5],\n maps: {\n albedo: {\n url: `${PH}/wood_planks_grey_diff_1k.png`,\n sha256: '3e6aeb842edd813759fdc96a6ffe6b695c888280f42501de589442311749ac5d',\n },\n normal: {\n url: `${PH}/wood_planks_grey_nor_gl_1k.png`,\n sha256: 'a9f2ad602eca2d59e84f203b1087e819e62ae517532bb25f7eb02a13c826e08b',\n },\n arm: {\n url: `${PH}/wood_planks_grey_arm_1k.png`,\n sha256: '9b81e9a0b4f9db0a920c4c2ce8ff13e0411b3624d4de455acdabe41e3fafe20e',\n },\n },\n },\n};\n\nexport const CC0_MATERIALS: readonly MaterialDef[] = [CC0_WOOD_PLANKS_GREY];\n",
6
+ "// The house material library: sixteen physically distinct strips with measured or sourced PBR\n// numbers (docs/architecture/materials.md has the table and the reasoning). Metals use the\n// physicallybased.info reflectance (sRGB here), dielectrics stay inside the 30–240 sRGB albedo\n// range, roughness follows engine/asset references. Colour lives in the texture, so tint these\n// with a near-white vertex colour (`NATURAL`) — except where noted (paint films take the hue).\n\nimport type { MaterialDef } from './material-def.ts';\nimport type { MaterialStripId } from './trim-sheet.ts';\n\nconst PB = 'https://physicallybased.info';\nconst ROBLOX = 'https://create.roblox.com/docs/art/modeling/material-reference';\nconst PBR_GUIDE = 'https://www.adobe.com/learn/substance-3d-designer/web/the-pbr-guide-part-2';\n\ntype Library = Readonly<Record<MaterialStripId, MaterialDef & { readonly id: MaterialStripId }>>;\n\nexport const MATERIAL_LIBRARY: Library = {\n oak: {\n id: 'oak',\n kind: 'planks',\n scaleMetres: 0.6,\n roughness: 0.68,\n albedo: '#a27b52',\n albedo2: '#6a482b',\n params: { width: 0.14, rings: 0.55, rays: 0.6, knots: 0.6 },\n description: 'Oak boards: warm brown, dark latewood rings, pale ray flecks.',\n sources: [PBR_GUIDE, ROBLOX],\n },\n pine: {\n id: 'pine',\n kind: 'planks',\n scaleMetres: 0.6,\n roughness: 0.72,\n albedo: '#d2b183',\n albedo2: '#9b6a3c',\n params: { width: 0.16, rings: 0.75, knots: 2.5 },\n description: 'Pine boards: pale yellow, strong orange latewood, frequent knots.',\n sources: [PBR_GUIDE, ROBLOX],\n },\n wood_weathered: {\n id: 'wood_weathered',\n kind: 'planks',\n scaleMetres: 0.6,\n roughness: 0.86,\n albedo: '#9b968c',\n albedo2: '#4f463c',\n params: { width: 0.2, rings: 0.35, checks: 1, knots: 1.5, grime: 0.15 },\n description: 'Barn-grey weathered boards: silvered, eroded grain, open checks.',\n sources: [ROBLOX],\n },\n wood_painted: {\n id: 'wood_painted',\n kind: 'planks',\n scaleMetres: 0.6,\n roughness: 0.84,\n albedo: '#ededed',\n albedo2: '#a08c74',\n params: { width: 0.14, paint: 1, paintRough: 0.62, chips: 0.38, knots: 0.8, grime: 0.3 },\n description: 'Painted boards (vertex colour = paint) worn through to grey wood at the edges.',\n sources: [ROBLOX],\n },\n iron_rust: {\n id: 'iron_rust',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.55,\n metalness: 0.9,\n albedo: '#8e8a85',\n albedo2: '#764323',\n params: { oxide: 0.62, cast: 0.25, streaks: 0.5 },\n description: 'Weathered wrought/rolled iron, rust blooming in patches and runs.',\n sources: [PB, ROBLOX],\n },\n iron_cast: {\n id: 'iron_cast',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.68,\n metalness: 0.75,\n albedo: '#6c6966',\n albedo2: '#55372a',\n params: { cast: 1, oxide: 0.35 },\n description: 'Sand-cast iron (wheels, frames): dark pitted skin, dull oxide.',\n sources: [PB],\n },\n steel_painted: {\n id: 'steel_painted',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.4,\n metalness: 1,\n albedo: '#eeeeee',\n albedo2: '#5a3b2a',\n params: { paint: 1, paintRough: 0.42, chips: 0.2, streaks: 0.2, grime: 0.2 },\n description: 'Painted steel (vertex colour = paint): chips show rusty steel beneath.',\n sources: [ROBLOX],\n },\n steel_galvanised: {\n id: 'steel_galvanised',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.42,\n metalness: 1,\n albedo: '#d5dadc',\n albedo2: '#9a9c98',\n params: { spangle: 1, oxide: 0.12 },\n description: 'Hot-dip galvanised steel: zinc spangle, white-rust bloom.',\n sources: [PB],\n },\n brass: {\n id: 'brass',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.28,\n metalness: 1,\n albedo: '#f5e5ae',\n albedo2: '#6b5a3a',\n params: { brush: 0.3, oxide: 0.1 },\n description: 'Brass fittings: warm gold reflectance, dark tarnish in patches.',\n sources: [PB, ROBLOX],\n },\n copper: {\n id: 'copper',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.32,\n metalness: 1,\n albedo: '#f2b89c',\n albedo2: '#6fa58f',\n params: { oxide: 0.15 },\n description: 'Copper: salmon reflectance with verdigris patches.',\n sources: [PB],\n },\n aluminium: {\n id: 'aluminium',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.34,\n metalness: 1,\n albedo: '#e6e8e9',\n params: { brush: 1 },\n description: 'Brushed aluminium: bright, cool, streaked along U.',\n sources: [PB],\n },\n chrome: {\n id: 'chrome',\n kind: 'metal',\n scaleMetres: 0.5,\n roughness: 0.07,\n metalness: 1,\n albedo: '#d3d9dc',\n description: 'Chrome plate: near-mirror.',\n sources: [PB],\n },\n rubber: {\n id: 'rubber',\n kind: 'noise',\n scaleMetres: 0.5,\n roughness: 0.78,\n albedo: '#2c2c2c',\n params: { tone: 0.95, mottle: 0.06, relief: 0.0002, size: 0.05, grime: 0.2 },\n description: 'Vulcanised rubber (tyres, hoses, seals).',\n sources: [PB, ROBLOX],\n },\n canvas: {\n id: 'canvas',\n kind: 'weave',\n scaleMetres: 1,\n roughness: 0.88,\n albedo: '#cbbea2',\n albedo2: '#8a7c62',\n params: { pitch: 0.004, folds: 0.6, stains: 0.35 },\n description: 'Cotton duck canvas: natural, weave relief, folds and water stains.',\n sources: [ROBLOX],\n },\n leather: {\n id: 'leather',\n kind: 'leather',\n scaleMetres: 0.5,\n roughness: 0.58,\n albedo: '#7c5438',\n albedo2: '#3e281a',\n params: { creases: 0.5, wear: 0.4 },\n description: 'Worn brown leather: pebble grain, dark creases, burnished wear.',\n sources: [ROBLOX],\n },\n plastic: {\n id: 'plastic',\n kind: 'noise',\n scaleMetres: 0.5,\n roughness: 0.35,\n albedo: '#ececec',\n params: { tone: 0.97, mottle: 0.01, relief: 0.00004, size: 0.2 },\n description: 'Moulded plastic (vertex colour = the plastic colour): satin, even.',\n sources: [ROBLOX],\n },\n};\n",
7
+ "// Colour lives in vertex colour (linear RGB), multiplied over the greyscale trim sheet: a palette\n// swap is a recipe edit, never a new texture.\n\nimport type { Vec3 } from '../core/index.ts';\n\nexport type Palette = Readonly<Record<string, Vec3>>;\n\n/** sRGB hex → linear RGB, the space glTF vertex colours are in. */\nexport function hex(value: string): Vec3 {\n const n = Number.parseInt(value.replace('#', ''), 16);\n const lin = (c: number): number => {\n const s = c / 255;\n return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n };\n return [lin((n >> 16) & 255), lin((n >> 8) & 255), lin(n & 255)];\n}\n\n/** Vertex colour for material strips that carry their own colour (oak, brass, rubber…). */\nexport const NATURAL: Vec3 = [1, 1, 1];\n\nexport function definePalette(entries: Readonly<Record<string, string>>): Palette {\n return Object.fromEntries(Object.entries(entries).map(([k, v]) => [k, hex(v)]));\n}\n\n/** Era/region palettes ship as data; recipes extend them with object spread. */\nexport const palettes = {\n victorianRail: definePalette({\n paint: '#2f4a3a',\n trim: '#b08d57',\n iron: '#2b2b2e',\n brass: '#c9a24a',\n red: '#7a2a22',\n }),\n artDeco: definePalette({\n limestone: '#d8cfbd',\n steel: '#9aa3ad',\n glass: '#4a6a80',\n bronze: '#8a6a3c',\n }),\n modernGlass: definePalette({\n glass: '#6f8fa8',\n aluminium: '#c4c9cf',\n concrete: '#a7a39b',\n }),\n harbour: definePalette({ hull: '#1f2f45', deck: '#8a6f4e', white: '#e8e6df', red: '#a1302a' }),\n} as const;\n",
8
+ "// Image-backed strips: a CC0 PBR texture set (Poly Haven, ambientCG or a local file) declared as\n// data — URL + sha256 per map, licence, author page, real-world size. Compile and paint stay\n// offline: bytes come only from a content-addressed cache the caller provides (`provideTextures`,\n// filled by `bun run textures`); a missing map throws T3D_TEXTURE_MISSING with that command.\n\nimport { Ts23dError } from '../core/index.ts';\n\nexport interface TextureFile {\n /** Download URL (https) or, for `source: 'file'`, a path relative to the working directory. */\n readonly url: string;\n /** Lower-case hex sha256 of the file's bytes: the cache key and the integrity check. */\n readonly sha256: string;\n}\n\nexport interface TextureSource {\n readonly source: 'polyhaven' | 'ambientcg' | 'file';\n /** The set's id at the source, e.g. 'wood_planks_grey'. */\n readonly id: string;\n /** Only public-domain sets are accepted, so a generated asset never inherits a licence duty. */\n readonly license: 'CC0-1.0';\n /** Human page crediting the set (goes into the GLB's XMP credits). */\n readonly page: string;\n readonly author?: string;\n /** Real-world size the image covers, metres (U × V). Poly Haven lists it as `dimensions`. */\n readonly metres: readonly [number, number];\n readonly maps: {\n /** sRGB base colour. */\n readonly albedo: TextureFile;\n /** Tangent-space normal, OpenGL convention (+Y up in the image; Poly Haven `nor_gl`). */\n readonly normal?: TextureFile;\n /** Packed AO / roughness / metalness (Poly Haven `arm`, glTF ORM order). */\n readonly arm?: TextureFile;\n };\n}\n\n/** PNG bytes by sha256. */\nexport type TextureCache = ReadonlyMap<string, Uint8Array>;\n\nconst SHA = /^[0-9a-f]{64}$/;\nconst provided = new Map<string, Uint8Array>();\n\n/** Hand verified texture bytes to the painter (e.g. from `loadTextureCache()` in scripts). */\nexport function provideTextures(cache: TextureCache): void {\n for (const [k, v] of cache) provided.set(k, v);\n}\n\nexport function textureBytes(file: TextureFile, where: string): Uint8Array {\n const hit = provided.get(file.sha256);\n if (hit) return hit;\n throw new Ts23dError('T3D_TEXTURE_MISSING', {\n cause: `${where}: texture ${file.url} (sha256 ${file.sha256.slice(0, 12)}…) is not in the cache`,\n fix: 'run `bun run textures <module defining the material>` once (downloads + verifies into node_modules/.cache/ts23d/textures), then provideTextures(await loadTextureCache()) before painting',\n });\n}\n\nexport function validateTexture(id: string, t: TextureSource): void {\n const fail = (cause: string, fix: string): never => {\n throw new Ts23dError('T3D_MATERIAL_INVALID', { cause: `material '${id}': ${cause}`, fix });\n };\n if (!['polyhaven', 'ambientcg', 'file'].includes(t.source))\n fail(`texture.source '${t.source}'`, \"use 'polyhaven', 'ambientcg' or 'file'\");\n if (t.license !== 'CC0-1.0')\n fail(\n `texture.license '${t.license}'`,\n 'only CC0-1.0 sets are accepted (Poly Haven and ambientCG are CC0)',\n );\n if (!(t.metres.length === 2 && t.metres.every((m) => Number.isFinite(m) && m > 0)))\n fail(`texture.metres [${t.metres}]`, 'give the real size the image covers, e.g. [1.5, 1.5]');\n for (const [map, f] of Object.entries(t.maps)) {\n if (!f) continue;\n if (!SHA.test(f.sha256))\n fail(\n `texture.maps.${map}.sha256 '${f.sha256}'`,\n 'lower-case hex sha256 of the file (sha256sum)',\n );\n if (!/\\.png$/i.test(f.url))\n fail(\n `texture.maps.${map}.url '${f.url}'`,\n 'use the PNG download (8- or 16-bit); JPEG is not decoded',\n );\n }\n}\n\n/** One credit line for the GLB's XMP and the docs. */\nexport const creditOf = (t: TextureSource): string =>\n `${t.id}${t.author ? ` by ${t.author}` : ''} (${t.source}, ${t.license}) ${t.page}`;\n",
9
+ "// The material definition contract: what a project (or the house library) says about a strip —\n// PBR numbers, intrinsic colour, a base painter kind and an optional painter layer — and its\n// translation to the sheet's StripRecipe. Validation throws T3D_MATERIAL_INVALID with the fix.\n\nimport { Ts23dError, type Vec3 } from '../core/index.ts';\nimport type { MaterialPainter, StripKind, StripRecipe } from './paint/types.ts';\nimport { hex } from './palette.ts';\nimport { type TextureSource, validateTexture } from './texture-source.ts';\n\nexport interface MaterialDef {\n /** snake_case, unique; becomes the strip id recipes pass as `strip`. */\n readonly id: string;\n /** Base painter the strip starts from. Default 'noise' (a quiet surface). */\n readonly kind?: StripKind;\n /** World metres the strip's V span represents (typical face height). Default 1. */\n readonly scaleMetres?: number;\n /** Perceptual roughness 0..1 (glTF): 0 mirror, 1 chalk. */\n readonly roughness: number;\n /** 0 dielectric, 1 metal. Default 0. Avoid in-between values except for dirt/oxide blends. */\n readonly metalness?: number;\n /** Intrinsic base colour: sRGB '#rrggbb' or linear RGB. Default white (vertex colour = hue). */\n readonly albedo?: string | Vec3;\n /** Second colour the painter blends to (latewood, rust, verdigris, bare wood under paint). */\n readonly albedo2?: string | Vec3;\n /** Painter knobs for `kind` (see each painter's header in src/material/paint/). */\n readonly params?: Readonly<Record<string, number>>;\n /** Your own layer, painted after `kind`: write height/tone/rough/metal/mix per texel. */\n readonly paint?: MaterialPainter;\n /** Paint from a CC0 texture set (opt-in, needs `bun run textures`) instead of `kind`. */\n readonly texture?: TextureSource;\n readonly description?: string;\n /** Where the numbers come from (URLs). */\n readonly sources?: readonly string[];\n}\n\nconst ID = /^[a-z][a-z0-9_]{1,31}$/;\nconst unit = (v: number): boolean => Number.isFinite(v) && v >= 0 && v <= 1;\n\nfunction fail(id: string, cause: string, fix: string): never {\n throw new Ts23dError('T3D_MATERIAL_INVALID', { cause: `material '${id}': ${cause}`, fix });\n}\n\nfunction colour(id: string, key: string, v: string | Vec3 | undefined): Vec3 | undefined {\n if (v === undefined) return undefined;\n if (typeof v === 'string') {\n if (!/^#?[0-9a-fA-F]{6}$/.test(v))\n fail(id, `${key} '${v}' is not a hex colour`, \"use '#rrggbb'\");\n return hex(v);\n }\n if (!(v.length === 3 && v.every(unit)))\n fail(id, `${key} [${v}] is not linear RGB 0..1`, \"use '#rrggbb' or three numbers in 0..1\");\n return v;\n}\n\n/** Validate a definition and turn it into the strip recipe the sheet painter runs. */\nexport function toStripRecipe(d: MaterialDef): StripRecipe {\n const id = String(d.id);\n if (!ID.test(id))\n fail(id, 'id is not snake_case (2–32 chars, starts with a letter)', \"e.g. 'teak_deck'\");\n if (!unit(d.roughness)) fail(id, `roughness ${d.roughness}`, 'roughness is 0..1');\n if (d.metalness !== undefined && !unit(d.metalness))\n fail(id, `metalness ${d.metalness}`, 'metalness is 0..1 (0 dielectric, 1 metal)');\n const scale = d.scaleMetres ?? 1;\n if (!(Number.isFinite(scale) && scale > 0))\n fail(id, `scaleMetres ${scale}`, 'scaleMetres is the face height in metres, > 0');\n if (d.paint !== undefined && typeof d.paint !== 'function')\n fail(id, 'paint is not a function', 'paint is (surface, kit) => void');\n for (const [k, v] of Object.entries(d.params ?? {}))\n if (!Number.isFinite(v)) fail(id, `params.${k} is ${v}`, 'params are finite numbers');\n if (d.texture) validateTexture(id, d.texture);\n const albedo = colour(id, 'albedo', d.albedo);\n const albedo2 = colour(id, 'albedo2', d.albedo2);\n return {\n kind: d.kind ?? 'noise',\n scaleMetres: scale,\n roughness: d.roughness,\n ...(d.metalness !== undefined ? { metalness: d.metalness } : {}),\n ...(d.params ? { params: d.params } : {}),\n ...(albedo ? { albedo } : {}),\n ...(albedo2 ? { albedo2 } : {}),\n ...(d.paint ? { paint: d.paint } : {}),\n ...(d.texture ? { texture: d.texture } : {}),\n };\n}\n",
10
+ "// The house sheet: every strip and cell. Classic strips stay near-greyscale and bright (vertex\n// colour carries hue); the material library strips carry measured colour. Each strip reads at its\n// typical face height (`scaleMetres`). `HOUSE_STRIPS` is the one mutable table: defineMaterial()\n// adds project strips to it, so `DEFAULT_SHEET` always paints every strip the layout knows.\n\nimport { MATERIAL_LIBRARY } from '../library.ts';\nimport { toStripRecipe } from '../material-def.ts';\nimport type { StripId } from '../trim-sheet.ts';\nimport type { SheetRecipe, StripRecipe } from './types.ts';\n\nconst leaf: StripRecipe = { kind: 'flat', scaleMetres: 1, roughness: 0.6 };\n\nconst library = Object.fromEntries(\n Object.values(MATERIAL_LIBRARY).map((d) => [d.id, toStripRecipe(d)]),\n);\n\nexport const HOUSE_STRIPS: Partial<Record<StripId, StripRecipe>> = {\n plain: { kind: 'noise', scaleMetres: 1, roughness: 0.6 },\n brick: { kind: 'bond', scaleMetres: 0.45, roughness: 0.85, params: { grime: 0.2 } },\n stone: {\n kind: 'bond',\n scaleMetres: 0.9,\n roughness: 0.9,\n params: {\n course: 0.22,\n length: 0.4,\n mortar: 0.016,\n depth: 0.012,\n bevel: 0.025,\n irregular: 0.5,\n relief: 0.004,\n variation: 0.3,\n grime: 0.2,\n },\n },\n slate: { kind: 'slate', scaleMetres: 0.66, roughness: 0.7 },\n iron: { kind: 'plates', scaleMetres: 0.5, roughness: 0.55, metalness: 0 },\n wood: { kind: 'planks', scaleMetres: 0.6, roughness: 0.75 },\n glass: { kind: 'glass', scaleMetres: 1, roughness: 0.05 },\n concrete: { kind: 'concrete', scaleMetres: 1, roughness: 0.9, params: { grime: 0.3 } },\n ...library,\n};\n\nexport const DEFAULT_SHEET: SheetRecipe = {\n seed: 1,\n size: 2048,\n strips: HOUSE_STRIPS,\n cells: {\n window_sash: { kind: 'noise', scaleMetres: 1, roughness: 0.5 },\n door_panel: { kind: 'noise', scaleMetres: 1, roughness: 0.6 },\n clock: { kind: 'noise', scaleMetres: 1, roughness: 0.3 },\n smokebox: {\n kind: 'plates',\n scaleMetres: 1,\n roughness: 0.6,\n metalness: 0.2,\n params: { rust: 0.3 },\n },\n sign: { kind: 'noise', scaleMetres: 1, roughness: 0.5 },\n porthole: { kind: 'plates', scaleMetres: 1, roughness: 0.5 },\n foliage_broadleaf: leaf,\n foliage_maple: leaf,\n foliage_maple_autumn: leaf,\n foliage_birch: leaf,\n foliage_acacia: leaf,\n foliage_palm: leaf,\n foliage_spruce: leaf,\n foliage_spruce_snow: leaf,\n foliage_willow: leaf,\n foliage_reeds: leaf,\n foliage_needles: leaf,\n },\n};\n",
11
+ "// The custom-strip slot table: ids registered by `defineMaterial`, in registration order. A leaf\n// module (no imports) so the layout (trim-sheet.ts) and the registry (registry.ts) can both read it.\n\nconst custom: string[] = [];\n\n/** Slot index among the custom strips, or −1. */\nexport const customIndex = (id: string): number => custom.indexOf(id);\n\nexport const customIds = (): readonly string[] => custom;\n\nexport function pushCustom(id: string): number {\n custom.push(id);\n return custom.length - 1;\n}\n\nexport function clearCustom(): void {\n custom.length = 0;\n}\n",
12
+ "// The shared trim sheet: ONE 2048² atlas (albedo + normal + ORM) every asset maps into, so every\n// asset is one material and one draw call. Strips tile along U; cells are fixed decals.\n// Layout is data here; `paintTrimSheet` (generator.ts) paints it. V grows with world up on\n// box/planar faces. V 0–0.875 holds 28 strip rows (64 px each at 2048²): the 8 original strips,\n// 16 physically distinct materials (woods, metals, rubber, canvas, leather, plastic) and 4 slots\n// for project materials (`defineMaterial`). V 0.875–1 holds 128 px cells: decals, then foliage.\n\nimport { Ts23dError } from '../core/index.ts';\nimport { customIndex } from './slots.ts';\n\n/** The original eight strips: greyscale, tinted by vertex colour. */\nexport type ClassicStripId =\n | 'plain'\n | 'brick'\n | 'stone'\n | 'slate'\n | 'iron'\n | 'wood'\n | 'glass'\n | 'concrete';\n/** Material strips with measured colour: use a near-white vertex colour (`NATURAL`) for truth. */\nexport type MaterialStripId =\n | 'oak'\n | 'pine'\n | 'wood_weathered'\n | 'wood_painted'\n | 'iron_rust'\n | 'iron_cast'\n | 'steel_painted'\n | 'steel_galvanised'\n | 'brass'\n | 'copper'\n | 'aluminium'\n | 'chrome'\n | 'rubber'\n | 'canvas'\n | 'leather'\n | 'plastic';\nexport type BuiltinStripId = ClassicStripId | MaterialStripId;\n/** A project material's id, as returned by `defineMaterial` (a branded string). */\nexport type CustomStripId = string & { readonly __ts23dMaterial: true };\nexport type StripId = BuiltinStripId | CustomStripId;\nexport type DecalCellId = 'window_sash' | 'door_panel' | 'clock' | 'smokebox' | 'sign' | 'porthole';\n/** Cutout leaf cards: the anchor (twig base) is the cell's bottom-centre, growth toward +V. */\nexport type FoliageCellId =\n | 'foliage_broadleaf'\n | 'foliage_maple'\n | 'foliage_maple_autumn'\n | 'foliage_birch'\n | 'foliage_acacia'\n | 'foliage_palm'\n | 'foliage_spruce'\n | 'foliage_spruce_snow'\n | 'foliage_willow'\n | 'foliage_reeds'\n | 'foliage_needles';\nexport type CellId = DecalCellId | FoliageCellId;\n\nexport interface UvRect {\n readonly u0: number;\n readonly v0: number;\n readonly u1: number;\n readonly v1: number;\n /** Metres of world surface one full rect covers, so texel density is equal across assets. */\n readonly metres: number;\n}\n\n/** Strip rows in the atlas: built-ins first, then `CUSTOM_STRIP_SLOTS` project materials. */\nexport const STRIP_ROWS = 28;\nconst STRIP_H = 1 / 32;\nconst classic: readonly ClassicStripId[] = [\n 'plain',\n 'brick',\n 'stone',\n 'slate',\n 'iron',\n 'wood',\n 'glass',\n 'concrete',\n];\nconst material: readonly MaterialStripId[] = [\n 'oak',\n 'pine',\n 'wood_weathered',\n 'wood_painted',\n 'iron_rust',\n 'iron_cast',\n 'steel_painted',\n 'steel_galvanised',\n 'brass',\n 'copper',\n 'aluminium',\n 'chrome',\n 'rubber',\n 'canvas',\n 'leather',\n 'plastic',\n];\nconst strips: readonly BuiltinStripId[] = [...classic, ...material];\nexport const CUSTOM_STRIP_SLOTS = STRIP_ROWS - strips.length;\nconst decals: readonly DecalCellId[] = [\n 'window_sash',\n 'door_panel',\n 'clock',\n 'smokebox',\n 'sign',\n 'porthole',\n];\nconst foliage: readonly FoliageCellId[] = [\n 'foliage_broadleaf',\n 'foliage_maple',\n 'foliage_maple_autumn',\n 'foliage_birch',\n 'foliage_acacia',\n 'foliage_palm',\n 'foliage_spruce',\n 'foliage_spruce_snow',\n 'foliage_willow',\n 'foliage_reeds',\n 'foliage_needles',\n];\nconst cells: readonly CellId[] = [...decals, ...foliage];\n/** Cells are 1/16 of the sheet, 16 per row from V 0.875: decals at 0–5, foliage from slot 8. */\nconst CELL = 1 / 16;\nconst CELL_V0 = STRIP_ROWS * STRIP_H;\nconst FOLIAGE_SLOT = 8;\nconst slotOf = (id: CellId): number => {\n const d = decals.indexOf(id as DecalCellId);\n return d >= 0 ? d : FOLIAGE_SLOT + foliage.indexOf(id as FoliageCellId);\n};\n\nexport const TRIM_SHEET_SIZE = 2048;\n\n/** Atlas row of a strip id, or −1 when it is neither built in nor defined. */\nexport function stripRow(id: string): number {\n const b = strips.indexOf(id as BuiltinStripId);\n if (b >= 0) return b;\n const c = customIndex(id);\n return c >= 0 ? strips.length + c : -1;\n}\n\nexport function stripRect(id: StripId): UvRect {\n const i = stripRow(id);\n if (i < 0)\n throw new Ts23dError('T3D_MATERIAL_UNKNOWN', {\n cause: `strip '${id}' is neither built in nor defined`,\n fix: `use a built-in strip (${strips.join(', ')}) or register it first with defineMaterial({ id: '${id}', ... })`,\n });\n return { u0: 0, v0: i * STRIP_H, u1: 1, v1: (i + 1) * STRIP_H, metres: 2 };\n}\n\nexport function cellRect(id: CellId): UvRect {\n const i = slotOf(id);\n const u0 = (i % 16) * CELL;\n const v0 = CELL_V0 + Math.floor(i / 16) * CELL;\n return { u0, v0, u1: u0 + CELL, v1: v0 + CELL, metres: 1 };\n}\n\n/** Every built-in strip, classic first. */\nexport const STRIPS = strips;\nexport const CLASSIC_STRIPS = classic;\nexport const MATERIAL_STRIPS = material;\nexport const CELLS = cells;\nexport const DECAL_CELLS = decals;\nexport const FOLIAGE_CELLS = foliage;\nexport const isFoliage = (id: CellId): id is FoliageCellId => id.startsWith('foliage_');\n",
13
+ "// Project materials: `defineMaterial` validates a MaterialDef, gives it one of the sheet's custom\n// strip rows (in registration order: define materials in one shared module so every recipe sees\n// the same order) and adds it to the house sheet, so `DEFAULT_SHEET` paints it and primitives map\n// onto it. Redefining an id with the same definition is a no-op; a different one is a conflict.\n// `materialOf` answers what any strip is (built-in or defined) for docs, review and tests;\n// `textureSources` / `stripCredits` serve the CC0 image strips (fetch list, GLB credits).\n\nimport { Ts23dError } from '../core/index.ts';\nimport { MATERIAL_LIBRARY } from './library.ts';\nimport { type MaterialDef, toStripRecipe } from './material-def.ts';\nimport { HOUSE_STRIPS } from './paint/default-sheet.ts';\nimport type { StripRecipe } from './paint/types.ts';\nimport { clearCustom, customIds, customIndex, pushCustom } from './slots.ts';\nimport { creditOf, type TextureSource } from './texture-source.ts';\nimport {\n CLASSIC_STRIPS,\n CUSTOM_STRIP_SLOTS,\n type CustomStripId,\n STRIPS,\n type StripId,\n stripRect,\n} from './trim-sheet.ts';\n\nconst defined = new Map<string, MaterialDef>();\n\n/** The same definition, field by field (painters by identity, colours and params by value). */\nfunction same(a: MaterialDef, b: MaterialDef): boolean {\n return (\n JSON.stringify({ ...a, paint: 0 }) === JSON.stringify({ ...b, paint: 0 }) && a.paint === b.paint\n );\n}\n\n/**\n * Register a project material and return its strip id for `strip:` options.\n * @example\n * const teak = defineMaterial({ id: 'teak_deck', kind: 'planks', roughness: 0.6,\n * albedo: '#8a5a32', albedo2: '#5a3a1e', params: { width: 0.12, rings: 0.5 } });\n * box({ size: [4, 2, 0.05], strip: teak, color: NATURAL });\n */\nexport function defineMaterial(def: MaterialDef): CustomStripId {\n const recipe = toStripRecipe(def);\n const id = def.id;\n if ((STRIPS as readonly string[]).includes(id))\n throw new Ts23dError('T3D_MATERIAL_CONFLICT', {\n cause: `material '${id}' is a built-in strip`,\n fix: `pick another id (e.g. '${id}_custom'), or restyle the built-in via paintTrimSheet({ ...DEFAULT_SHEET, strips: { ...DEFAULT_SHEET.strips, ${id}: … } })`,\n });\n const prior = defined.get(id);\n if (prior) {\n if (same(prior, def)) return id as CustomStripId;\n throw new Ts23dError('T3D_MATERIAL_CONFLICT', {\n cause: `material '${id}' is already defined differently`,\n fix: 'define each material once in a shared module and import it, or give the variant its own id',\n });\n }\n if (customIds().length >= CUSTOM_STRIP_SLOTS)\n throw new Ts23dError('T3D_SHEET_FULL', {\n cause: `the trim sheet has ${CUSTOM_STRIP_SLOTS} custom strip rows, all taken (${customIds().join(', ')})`,\n fix: 'reuse a built-in strip with a vertex colour, or restyle an unused built-in strip in your SheetRecipe',\n });\n defined.set(id, def);\n pushCustom(id);\n (HOUSE_STRIPS as Record<string, StripRecipe>)[id] = recipe;\n return id as CustomStripId;\n}\n\n/**\n * Forget every defined material (tests; long-lived workers that reload recipes). Built-ins stay.\n * Meshes compiled before the reset keep UVs into rows that may be reassigned.\n */\nexport function resetMaterials(): void {\n for (const id of defined.keys()) delete (HOUSE_STRIPS as Record<string, StripRecipe>)[id];\n defined.clear();\n clearCustom();\n}\n\nexport interface MaterialInfo {\n readonly id: StripId;\n /** classic = greyscale strip tinted by vertex colour; library/defined carry their own colour. */\n readonly origin: 'classic' | 'library' | 'defined';\n readonly recipe: StripRecipe;\n readonly description: string;\n readonly sources: readonly string[];\n}\n\n/** What a strip is: its recipe, origin, description and sources. Unknown ids throw. */\nexport function materialOf(id: StripId): MaterialInfo {\n const recipe = HOUSE_STRIPS[id];\n const lib = (MATERIAL_LIBRARY as Readonly<Record<string, MaterialDef>>)[id];\n const def = lib ?? defined.get(id);\n if (!recipe || (customIndex(id) < 0 && !(STRIPS as readonly string[]).includes(id)))\n throw new Ts23dError('T3D_MATERIAL_UNKNOWN', {\n cause: `strip '${id}' is neither built in nor defined`,\n fix: `use one of ${STRIPS.join(', ')}, or defineMaterial({ id: '${id}', ... }) first`,\n });\n const classic = (CLASSIC_STRIPS as readonly string[]).includes(id);\n return {\n id,\n origin: classic ? 'classic' : lib ? 'library' : 'defined',\n recipe,\n description:\n def?.description ?? `classic ${recipe.kind} strip (greyscale, vertex colour tints)`,\n sources: def?.sources ?? [],\n };\n}\n\n/** Every texture set a defined material references (what `bun run textures` fetches). */\nexport function textureSources(): readonly TextureSource[] {\n return [...defined.values()].flatMap((d) => (d.texture ? [d.texture] : []));\n}\n\n/**\n * Credit lines for the image strips a mesh samples: any V coordinate inside such a strip's row\n * counts. Empty when no image strip is used (the GLB stays byte-identical).\n */\nexport function stripCredits(vs: ArrayLike<number>): string[] {\n const out: string[] = [];\n for (const [id, d] of defined) {\n if (!d.texture) continue;\n const r = stripRect(id as StripId);\n for (let i = 0; i < vs.length; i++) {\n const v = vs[i] ?? -1;\n if (v >= r.v0 && v <= r.v1) {\n out.push(creditOf(d.texture));\n break;\n }\n }\n }\n return out;\n}\n",
14
+ "// Seeded integer-hash value noise and fBm, periodic along X so strips tile seamlessly along U.\n// Pure functions of (coords, seed): no state, no allocation, safe in per-pixel loops.\n\n/** Integer hash of a lattice point to [0, 1). */\nexport function hash2(ix: number, iy: number, seed: number): number {\n let h = Math.imul(ix | 0, 0x27d4eb2d) ^ Math.imul(iy | 0, 0x165667b1) ^ seed;\n h = Math.imul(h ^ (h >>> 15), 0x85ebca6b);\n h = Math.imul(h ^ (h >>> 13), 0xc2b2ae35);\n return ((h ^ (h >>> 16)) >>> 0) / 4294967296;\n}\n\n/** Value noise in [0, 1] on a unit lattice, periodic in x with an integer `period` (cells). */\nexport function valueNoise(x: number, y: number, period: number, seed: number): number {\n const xi = Math.floor(x);\n const yi = Math.floor(y);\n const fx = x - xi;\n const fy = y - yi;\n const sx = fx * fx * (3 - 2 * fx);\n const sy = fy * fy * (3 - 2 * fy);\n const x0 = ((xi % period) + period) % period;\n const x1 = (x0 + 1) % period;\n const a = hash2(x0, yi, seed);\n const b = hash2(x1, yi, seed);\n const c = hash2(x0, yi + 1, seed);\n const d = hash2(x1, yi + 1, seed);\n return a + (b - a) * sx + (c - a + (d - c - b + a) * sx) * sy;\n}\n\n/**\n * Fractal Brownian motion in [-1, 1]: `octaves` layers of value noise, each at double frequency\n * and `gain` amplitude. Doubling keeps the period an integer, so the sum stays tileable.\n */\nexport function fbm(\n x: number,\n y: number,\n period: number,\n seed: number,\n octaves = 4,\n gain = 0.5,\n): number {\n let sum = 0;\n let amp = 1;\n let norm = 0;\n let f = 1;\n for (let o = 0; o < octaves; o++) {\n sum += amp * valueNoise(x * f, y * f, period * f, seed + o * 1013);\n norm += amp;\n amp *= gain;\n f *= 2;\n }\n return (sum / norm) * 2 - 1;\n}\n",
15
+ "// The painting surface for one sheet region (a strip or a cell): float layers in real metres.\n// Painters write height (metres of relief, + is out of the surface), linear grey tone,\n// roughness, metalness and a two-colour `mix`; `compose` turns them into albedo + normal + ORM.\n\nimport type { Vec3 } from '../../core/index.ts';\nimport { fbm } from './noise.ts';\n\nexport interface Canvas {\n readonly w: number;\n readonly h: number;\n /** World metres the canvas spans along U (x) and V (y). Row y grows with world up (+V). */\n readonly metresU: number;\n readonly metresV: number;\n /** Strips wrap along U (tile seamlessly); cells clamp. */\n readonly wrapU: boolean;\n readonly height: Float32Array;\n readonly tone: Float32Array;\n readonly rough: Float32Array;\n readonly metal: Float32Array;\n /** Extra occlusion multiplied into the cavity AO (foliage darkens toward the twig). */\n readonly occl: Float32Array;\n /** 0 = `colours[0]`, 1 = `colours[1]` (latewood, rust, bare wood under chipped paint…). */\n readonly mix: Float32Array;\n /** Linear albedo pair for material strips; null = greyscale (vertex colour carries hue). */\n colours: readonly [Vec3, Vec3] | null;\n /** sRGB RGBA override (stamped images, coloured foliage); null when painted greyscale. */\n rgba: Uint8Array | null;\n /** Tangent-space normal override (image strips); null = derived from `height`. */\n normalRgba: Uint8Array | null;\n}\n\nexport function createCanvas(\n w: number,\n h: number,\n metresU: number,\n metresV: number,\n wrapU: boolean,\n): Canvas {\n const n = w * h;\n return {\n w,\n h,\n metresU,\n metresV,\n wrapU,\n height: new Float32Array(n),\n tone: new Float32Array(n).fill(1),\n rough: new Float32Array(n).fill(0.8),\n metal: new Float32Array(n),\n occl: new Float32Array(n).fill(1),\n mix: new Float32Array(n),\n colours: null,\n rgba: null,\n normalRgba: null,\n };\n}\n\n/** Metres per pixel along x and y. */\nexport const pxU = (c: Canvas): number => c.metresU / c.w;\nexport const pxV = (c: Canvas): number => c.metresV / c.h;\n\n/** Noise period (lattice cells across the canvas width) for a feature size in metres. */\nexport function periodFor(c: Canvas, featureMetres: number): number {\n return c.wrapU ? Math.max(1, Math.round(c.metresU / featureMetres)) : 1 << 20;\n}\n\n/**\n * fBm sampled at metres (xm, ym) with feature size `sizeU` along U and `sizeV` along V,\n * snapped so it tiles along U. Returns [-1, 1].\n */\nexport function noiseAt(\n c: Canvas,\n xm: number,\n ym: number,\n sizeU: number,\n sizeV: number,\n seed: number,\n octaves = 4,\n): number {\n // Strips are coarse along V: never ask for a feature finer than ~1.5 texels on either axis,\n // or it aliases into streaks. Scale both axes together so the feature keeps its aspect.\n const finest = 1.5 * Math.max(c.metresU / c.w, c.metresV / c.h);\n const k = Math.max(1, finest / Math.min(sizeU, sizeV));\n const period = periodFor(c, sizeU * k);\n const cell = c.wrapU ? c.metresU / period : sizeU * k;\n return fbm(xm / cell, ym / (sizeV * k), period, seed, octaves);\n}\n\n/** Read a parameter with a default, rejecting nothing (validation happens in the generator). */\nexport const param = (\n params: Readonly<Record<string, number>> | undefined,\n key: string,\n fallback: number,\n): number => params?.[key] ?? fallback;\n\nexport const clamp01 = (v: number): number => Math.min(1, Math.max(0, v));\n\nexport const smooth = (e0: number, e1: number, v: number): number => {\n const t = clamp01((v - e0) / (e1 - e0));\n return t * t * (3 - 2 * t);\n};\n",
16
+ "// Tiny SDF-style helpers for cell motifs: distances in metres, no allocation.\n\n/** Distance from (px, py) to the segment (ax, ay)–(bx, by). */\nexport function segment(px: number, py: number, ax: number, ay: number, bx: number, by: number) {\n const dx = bx - ax;\n const dy = by - ay;\n const t = Math.max(0, Math.min(1, ((px - ax) * dx + (py - ay) * dy) / (dx * dx + dy * dy)));\n return Math.hypot(px - ax - t * dx, py - ay - t * dy);\n}\n\n/** Signed distance to an axis-aligned rectangle (negative inside). */\nexport function rect(px: number, py: number, x0: number, y0: number, x1: number, y1: number) {\n const qx = Math.max(x0 - px, px - x1);\n const qy = Math.max(y0 - py, py - y1);\n return qx > 0 || qy > 0 ? Math.hypot(Math.max(qx, 0), Math.max(qy, 0)) : Math.max(qx, qy);\n}\n\n/** Dome profile in [0, 1] for a round boss of radius `r` at distance `d`. */\nexport const dome = (d: number, r: number): number => (d < r ? Math.sqrt(1 - (d / r) ** 2) : 0);\n\n/** Distance to the nearest of `n` points evenly spaced on a circle of radius `ring`. */\nexport function boltRing(px: number, py: number, ring: number, n: number, phase = 0): number {\n const a = Math.atan2(py, px) - phase;\n const step = (Math.PI * 2) / n;\n const k = Math.round(a / step);\n const ba = k * step + phase;\n return Math.hypot(px - ring * Math.cos(ba), py - ring * Math.sin(ba));\n}\n",
17
+ "// Rectangular decal cells (1 m each), painted over a backdrop of the cell recipe's own kind:\n// window sash (glazing bars, dark panes the shaders' window glow keys on), four-panel door with\n// raised-and-fielded panels, sign blank with a moulded border and corner screws. Row y grows with\n// world up, so \"bottom rail\" is low y.\n// params (window_sash): cols 2 · rows 2 (panes per sash) · frame 0.07 · bar 0.022\n// params (door_panel): stile 0.12\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport { dome, rect } from './shapes.ts';\nimport type { StripRecipe } from './types.ts';\n\n/** Pane tone: dark enough that `luma < 0.3` marks glass for window glow. */\nexport const PANE_TONE = 0.12;\n\nexport function paintWindowSash(c: Canvas, r: StripRecipe, seed: number): void {\n const cols = param(r.params, 'cols', 2);\n const rows = param(r.params, 'rows', 2);\n const frame = param(r.params, 'frame', 0.07);\n const bar = param(r.params, 'bar', 0.022);\n const meet = 0.5;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const lower = ym < meet;\n const y0 = lower ? frame : meet + bar;\n const y1 = lower ? meet - bar : 1 - frame;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const i = y * c.w + x;\n // Distance into a pane: inside the sash opening, away from every glazing bar.\n const fx = ((xm - frame) / (1 - 2 * frame)) * cols;\n const fy = ((ym - y0) / (y1 - y0)) * rows;\n const inX = Math.min(fx - Math.floor(fx), Math.ceil(fx) - fx) * ((1 - 2 * frame) / cols);\n const inY = Math.min(fy - Math.floor(fy), Math.ceil(fy) - fy) * ((y1 - y0) / rows);\n const open = -rect(xm, ym, frame, y0, 1 - frame, y1);\n const pane = Math.min(open, inX - bar / 2, inY - bar / 2);\n const wood = noiseAt(c, xm, ym, 0.3, 0.02, seed, 3);\n if (pane > 0) {\n const sky = noiseAt(c, xm, ym, 0.6, 0.6, seed + 1, 2);\n c.height[i] = -0.012;\n c.tone[i] = PANE_TONE + 0.05 * (ym - y0) + 0.03 * sky;\n c.rough[i] = 0.05;\n c.metal[i] = 0;\n } else {\n const bevel = smooth(0, 0.01, -pane);\n c.height[i] = -0.012 * (1 - bevel) + 0.0003 * wood;\n c.tone[i] = 0.9 + 0.03 * wood;\n c.rough[i] = r.roughness;\n }\n }\n }\n}\n\nexport function paintDoorPanel(c: Canvas, r: StripRecipe, seed: number): void {\n const stile = param(r.params, 'stile', 0.12);\n const muntin = stile * 0.7;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n // Four panels: two tall above the lock rail, two short below. [x0, y0, x1, y1].\n const midX = 0.5;\n const panels = [\n [stile, 0.2, midX - muntin / 2, 0.42],\n [midX + muntin / 2, 0.2, 1 - stile, 0.42],\n [stile, 0.58, midX - muntin / 2, 1 - stile],\n [midX + muntin / 2, 0.58, 1 - stile, 1 - stile],\n ] as const;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const i = y * c.w + x;\n let d = 1;\n for (const [x0, y0, x1, y1] of panels) d = Math.min(d, rect(xm, ym, x0, y0, x1, y1));\n const grain = noiseAt(c, xm, ym, 0.02, 0.4, seed, 3);\n // Recess, then a bevel rising to the raised field 0.04 m in from the panel edge.\n const recess = d < 0 ? 1 : 1 - smooth(0, 0.006, d);\n const field = smooth(0.005, 0.04, -d);\n c.height[i] = -0.012 * recess + 0.008 * field + 0.0003 * grain;\n c.tone[i] = (0.8 + 0.08 * grain) * (d < 0 && d > -0.008 ? 0.65 : d < 0 ? 0.92 : 1);\n c.rough[i] = r.roughness + 0.05 * grain;\n }\n }\n}\n\nexport function paintSign(c: Canvas, r: StripRecipe, _seed: number): void {\n const border = param(r.params, 'border', 0.05);\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const screws = [0.07, 0.93];\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const i = y * c.w + x;\n const inner = -rect(xm, ym, border, border, 1 - border, 1 - border);\n const edge = Math.min(xm, ym, 1 - xm, 1 - ym);\n const moulding = inner < 0 ? dome(Math.abs(-inner - border / 2), border / 2) : 0;\n let screw = 0;\n for (const sx of screws)\n for (const sy of screws) screw = Math.max(screw, dome(Math.hypot(xm - sx, ym - sy), 0.012));\n c.height[i] = 0.006 * moulding + 0.002 * screw - 0.002 * (1 - smooth(0, 0.004, edge));\n c.tone[i] = inner > 0 ? 0.95 : 0.85 + 0.1 * moulding;\n if (screw > 0) {\n c.tone[i] = 0.6;\n c.metal[i] = 1;\n c.rough[i] = 0.35;\n }\n }\n }\n}\n",
18
+ "// Round decal cells (1 m each), centred, over the cell recipe's backdrop: station clock (bezel,\n// minute and hour ticks, hands at 10:10), locomotive smokebox door (flanged, bolted rim, hinge\n// straps, centre dart with handle), porthole (bolted brass ring, dark glass). Row y grows with\n// world up, so 12 o'clock is +y.\n\nimport { type Canvas, noiseAt, smooth } from './canvas.ts';\nimport { PANE_TONE } from './cells.ts';\nimport { boltRing, dome, segment } from './shapes.ts';\nimport type { StripRecipe } from './types.ts';\n\nconst TAU = Math.PI * 2;\n\n/** Hand from the centre at clock position `hours` (0..12), length `len`. */\nfunction hand(px: number, py: number, hours: number, len: number): number {\n const a = (hours / 12) * TAU;\n return segment(px, py, 0, 0, Math.sin(a) * len, Math.cos(a) * len);\n}\n\nexport function paintClock(c: Canvas, r: StripRecipe, _seed: number): void {\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const py = (y + 0.5) * pv - 0.5;\n for (let x = 0; x < c.w; x++) {\n const px = (x + 0.5) * pu - 0.5;\n const i = y * c.w + x;\n const d = Math.hypot(px, py);\n if (d > 0.48) continue;\n const i0 = i;\n if (d > 0.42) {\n c.height[i0] = 0.012 * dome(Math.abs(d - 0.45), 0.03);\n c.tone[i0] = 0.55;\n c.metal[i0] = 1;\n c.rough[i0] = 0.35;\n continue;\n }\n const a = Math.atan2(px, py);\n const minute = Math.abs((((a / TAU) * 60 + 60.5) % 1) - 0.5) * (TAU / 60) * d;\n const hour = Math.abs((((a / TAU) * 12 + 12.5) % 1) - 0.5) * (TAU / 12) * d;\n const tickM = d > 0.38 && d < 0.41 && minute < 0.003 ? 1 : 0;\n const tickH = d > 0.32 && d < 0.41 && hour < 0.008 ? 1 : 0;\n const hands = Math.min(\n hand(px, py, 10 + 10 / 60, 0.22) - 0.012,\n hand(px, py, 2, 0.34) - 0.007,\n );\n const ink = Math.max(tickM, tickH, hands < 0 ? 1 : 0, d < 0.02 ? 1 : 0);\n c.height[i0] = -0.004 + 0.002 * ink;\n c.tone[i0] = ink ? 0.08 : 0.96;\n c.rough[i0] = ink ? 0.5 : r.roughness;\n c.metal[i0] = 0;\n }\n }\n}\n\nexport function paintSmokebox(c: Canvas, r: StripRecipe, seed: number): void {\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const metal = r.metalness ?? 0;\n for (let y = 0; y < c.h; y++) {\n const py = (y + 0.5) * pv - 0.5;\n for (let x = 0; x < c.w; x++) {\n const px = (x + 0.5) * pu - 0.5;\n const i = y * c.w + x;\n const d = Math.hypot(px, py);\n if (d > 0.47) continue;\n const pit = noiseAt(c, px + 0.5, py + 0.5, 0.03, 0.03, seed, 3);\n // Slightly dished door, a raised flange, a bolt ring just inside it.\n let h = 0.01 * (1 - (d / 0.47) ** 2) + 0.0004 * pit;\n const flange = dome(Math.abs(d - 0.45), 0.02);\n h += 0.006 * flange;\n const bolt = dome(boltRing(px, py, 0.415, 28), 0.011);\n h += 0.006 * bolt;\n // Two hinge straps from the left rim to the dart's line, ending in a rounded tip.\n const strap = Math.min(\n segment(px, py, -0.47, 0.17, 0.12, 0.17),\n segment(px, py, -0.47, -0.17, 0.12, -0.17),\n );\n const strapH = smooth(0.024, 0.018, strap);\n h = Math.max(h, 0.014 * strapH + h * (1 - strapH));\n const boss = dome(d, 0.05);\n const handle = smooth(0.012, 0.008, segment(px, py, -0.13, 0, 0.13, 0));\n h += 0.02 * boss + 0.012 * handle;\n c.height[i] = h;\n c.tone[i] =\n (0.5 + 0.05 * pit) * (1 + 0.5 * Math.max(bolt, handle, strapH * 0.6, flange, boss));\n c.rough[i] = r.roughness - 0.15 * Math.max(bolt, handle, boss);\n c.metal[i] = metal + (1 - metal) * Math.max(handle, boss) * 0.8;\n }\n }\n}\n\nexport function paintPorthole(c: Canvas, r: StripRecipe, seed: number): void {\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const py = (y + 0.5) * pv - 0.5;\n for (let x = 0; x < c.w; x++) {\n const px = (x + 0.5) * pu - 0.5;\n const i = y * c.w + x;\n const d = Math.hypot(px, py);\n if (d > 0.44) continue;\n if (d < 0.29) {\n const sky = noiseAt(c, px + 0.5, py + 0.5, 0.5, 0.5, seed, 2);\n c.height[i] = -0.012;\n c.tone[i] = PANE_TONE + 0.04 * (py + 0.3) + 0.02 * sky;\n c.rough[i] = 0.05;\n c.metal[i] = 0;\n continue;\n }\n const ring = dome(Math.abs(d - 0.365), 0.075);\n const bolt = dome(boltRing(px, py, 0.405, 10, Math.PI / 10), 0.018);\n const lip = dome(Math.abs(d - 0.3), 0.012);\n c.height[i] = 0.016 * ring + 0.008 * bolt + 0.004 * lip;\n c.tone[i] = 0.75 + 0.15 * ring;\n c.rough[i] = Math.max(0.2, r.roughness - 0.2 * ring);\n c.metal[i] = 1;\n }\n }\n}\n",
19
+ "// Shared growth helpers for foliage cells: quadratic stem curves sampled into points, per-leaf\n// colour jitter and the leaf palettes (linear RGB). Allocation is per leaf/stem, never per pixel.\n\nimport type { Rng } from '../../core/index.ts';\nimport type { Foliage, Rgb } from './foliage-raster.ts';\n\n/** A quadratic Bézier from p0 via p1 to p2, metres in the cell (anchor usually 0.5, 0.02). */\nexport interface Curve {\n readonly x: readonly number[];\n readonly y: readonly number[];\n /** Tangent angle per sample (0 = +V, + toward +U), the convention `Foliage.leaf` takes. */\n readonly a: readonly number[];\n}\n\nexport function curve(\n x0: number,\n y0: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n n = 16,\n): Curve {\n const x: number[] = [];\n const y: number[] = [];\n const a: number[] = [];\n for (let i = 0; i <= n; i++) {\n const t = i / n;\n const u = 1 - t;\n x.push(u * u * x0 + 2 * u * t * x1 + t * t * x2);\n y.push(u * u * y0 + 2 * u * t * y1 + t * t * y2);\n const dx = 2 * u * (x1 - x0) + 2 * t * (x2 - x1);\n const dy = 2 * u * (y1 - y0) + 2 * t * (y2 - y1);\n a.push(Math.atan2(dx, dy));\n }\n return { x, y, a };\n}\n\n/** Sample index nearest parameter t ∈ [0, 1]. */\nexport const at = (c: Curve, t: number): number => Math.round(t * (c.x.length - 1));\n\n/** Draw a curve as a tapered stem. */\nexport function drawStem(f: Foliage, c: Curve, w0: number, w1: number, col: Rgb): void {\n const n = c.x.length - 1;\n for (let i = 0; i < n; i++) {\n const t0 = i / n;\n const t1 = (i + 1) / n;\n f.stem(\n c.x[i] ?? 0,\n c.y[i] ?? 0,\n c.x[i + 1] ?? 0,\n c.y[i + 1] ?? 0,\n w0 + (w1 - w0) * t0,\n w0 + (w1 - w0) * t1,\n col,\n );\n }\n}\n\n/** Jitter a colour per leaf: brightness ±amt and a small hue drift between R and G. */\nexport function vary(rng: Rng, col: Rgb, amt: number): Rgb {\n const k = 1 + amt * (rng.next() * 2 - 1);\n const drift = 1 + amt * 0.6 * (rng.next() * 2 - 1);\n return [col[0] * k * drift, col[1] * k, (col[2] * k) / drift];\n}\n\nexport const dim = (col: Rgb, k: number): Rgb => [col[0] * k, col[1] * k, col[2] * k];\n\n/** Leaf palettes, linear RGB (multiply by a near-white vertex colour on the card). */\nexport const LEAF = {\n beech: [0.09, 0.2, 0.035] as Rgb,\n maple: [0.1, 0.24, 0.04] as Rgb,\n birch: [0.16, 0.3, 0.05] as Rgb,\n acacia: [0.11, 0.2, 0.06] as Rgb,\n palm: [0.12, 0.22, 0.05] as Rgb,\n dry: [0.3, 0.2, 0.08] as Rgb,\n spruce: [0.035, 0.09, 0.04] as Rgb,\n pine: [0.06, 0.13, 0.04] as Rgb,\n willow: [0.2, 0.3, 0.08] as Rgb,\n reed: [0.2, 0.28, 0.08] as Rgb,\n snow: [0.85, 0.88, 0.92] as Rgb,\n bark: [0.08, 0.055, 0.035] as Rgb,\n twig: [0.12, 0.09, 0.05] as Rgb,\n} as const;\n\n/** Autumn maple: each leaf picks one of these, then gets jittered. */\nexport const AUTUMN: readonly Rgb[] = [\n [0.6, 0.08, 0.02],\n [0.75, 0.25, 0.02],\n [0.8, 0.45, 0.03],\n [0.45, 0.04, 0.03],\n [0.55, 0.35, 0.05],\n];\n",
20
+ "// ORM + albedo packing. Occlusion comes from the height cavity (blurred height minus height: deep\n// where a texel sits below its surroundings — mortar, seams, grain); roughness and metalness are\n// the painted layers. Albedo is the linear tone, sRGB-encoded, with a mild cavity darkening baked\n// in so engines that ignore the occlusion map still read the joints.\n\nimport type { Canvas } from './canvas.ts';\n\n/** Depth (metres) below the local mean that counts as fully occluded. */\nconst AO_DEPTH = 0.006;\nconst AO_STRENGTH = 0.75;\n/** Blur radius of the cavity estimate, metres. */\nconst AO_RADIUS = 0.02;\n\n/** Separable sliding-window box blur: O(1) per texel. Wraps along x when `wrap`, else clamps. */\nfunction boxBlur(\n src: Float32Array,\n w: number,\n h: number,\n rx: number,\n ry: number,\n wrap: boolean,\n): Float32Array {\n const tmp = new Float32Array(src.length);\n const out = new Float32Array(src.length);\n const ix = (i: number): number =>\n i < 0 ? (wrap ? (i % w) + w : 0) : i >= w ? (wrap ? i % w : w - 1) : i;\n for (let y = 0; y < h; y++) {\n const row = y * w;\n let s = 0;\n for (let k = -rx; k <= rx; k++) s += src[row + ix(k)] ?? 0;\n for (let x = 0; x < w; x++) {\n tmp[row + x] = s / (2 * rx + 1);\n s += (src[row + ix(x + rx + 1)] ?? 0) - (src[row + ix(x - rx)] ?? 0);\n }\n }\n const iy = (j: number): number => (j < 0 ? 0 : j >= h ? h - 1 : j);\n for (let x = 0; x < w; x++) {\n let s = 0;\n for (let k = -ry; k <= ry; k++) s += tmp[iy(k) * w + x] ?? 0;\n for (let y = 0; y < h; y++) {\n out[y * w + x] = s / (2 * ry + 1);\n s += (tmp[iy(y + ry + 1) * w + x] ?? 0) - (tmp[iy(y - ry) * w + x] ?? 0);\n }\n }\n return out;\n}\n\n/** Per-texel ambient occlusion in [1 - AO_STRENGTH, 1]. */\nexport function cavityOcclusion(c: Canvas): Float32Array {\n const rx = Math.max(1, Math.round(AO_RADIUS / (c.metresU / c.w)));\n const ry = Math.max(1, Math.round(AO_RADIUS / (c.metresV / c.h)));\n const blur = boxBlur(boxBlur(c.height, c.w, c.h, rx, ry, c.wrapU), c.w, c.h, rx, ry, c.wrapU);\n const ao = new Float32Array(c.height.length);\n for (let i = 0; i < ao.length; i++) {\n const cavity = (blur[i] ?? 0) - (c.height[i] ?? 0);\n const t = cavity <= 0 ? 0 : cavity >= AO_DEPTH ? 1 : cavity / AO_DEPTH;\n ao[i] = (1 - AO_STRENGTH * t) * (c.occl[i] ?? 1);\n }\n return ao;\n}\n\nexport const SRGB = new Uint8Array(4096).map((_, i) => {\n const l = i / 4095;\n const s = l <= 0.0031308 ? l * 12.92 : 1.055 * l ** (1 / 2.4) - 0.055;\n return Math.round(s * 255);\n});\n\nconst byte = (v: number): number => (v <= 0 ? 0 : v >= 1 ? 255 : Math.round(v * 255));\n\n/** RGBA8 ORM: R = occlusion, G = roughness, B = metalness, A = 255. */\nexport function packOrm(c: Canvas, ao: Float32Array): Uint8Array {\n const out = new Uint8Array(c.w * c.h * 4);\n for (let i = 0, o = 0; i < ao.length; i++, o += 4) {\n out[o] = byte(ao[i] ?? 1);\n out[o + 1] = byte(c.rough[i] ?? 0.8);\n out[o + 2] = byte(c.metal[i] ?? 0);\n out[o + 3] = 255;\n }\n return out;\n}\n\nconst enc = (t: number): number => SRGB[t <= 0 ? 0 : t >= 1 ? 4095 : Math.round(t * 4095)] ?? 255;\n\n/** RGBA8 sRGB albedo: the stamped image if any, else (colour pair by mix or grey) × tone × cavity. */\nexport function packAlbedo(c: Canvas, ao: Float32Array): Uint8Array {\n if (c.rgba) return c.rgba;\n const out = new Uint8Array(c.w * c.h * 4);\n const pair = c.colours;\n if (pair) {\n const [a, b] = pair;\n for (let i = 0, o = 0; i < ao.length; i++, o += 4) {\n const t = (c.tone[i] ?? 1) * (0.8 + 0.2 * (ao[i] ?? 1));\n const m = Math.min(1, Math.max(0, c.mix[i] ?? 0));\n for (let k = 0; k < 3; k++) out[o + k] = enc(((a[k] ?? 1) * (1 - m) + (b[k] ?? 1) * m) * t);\n out[o + 3] = 255;\n }\n return out;\n }\n for (let i = 0, o = 0; i < ao.length; i++, o += 4) {\n const t = (c.tone[i] ?? 1) * (0.8 + 0.2 * (ao[i] ?? 1));\n const g = SRGB[t <= 0 ? 0 : t >= 1 ? 4095 : Math.round(t * 4095)] ?? 255;\n out[o] = g;\n out[o + 1] = g;\n out[o + 2] = g;\n out[o + 3] = 255;\n }\n return out;\n}\n",
21
+ "// Rasteriser for foliage cells: tapered stems and leaf shapes composited back-to-front into\n// linear colour + coverage, with leaf-dome and midrib relief. `finish` writes sRGB RGBA (alpha =\n// leaf mask, transparent texels bled with leaf colour so mips don't halo), height, roughness and\n// an occlusion term that darkens toward the twig axis. Shapes iterate only their pixel bounds.\n\nimport { type Canvas, clamp01, smooth } from './canvas.ts';\nimport { SRGB } from './orm.ts';\nimport { segment } from './shapes.ts';\n\nexport type Rgb = readonly [number, number, number];\n/** Width profile of a leaf along its length t ∈ [0, 1]; 1 = full half-width. */\nexport type LeafShape = 'ovate' | 'lance' | 'needle' | 'blade' | 'palmate';\n\nconst total = (a: Float32Array): number => a.reduce((s, v) => s + v, 0);\n\n/** Angle between palmate lobe axes. */\nconst LOBE = (Math.PI * 2) / 5;\n\nexport class Foliage {\n private readonly r: Float32Array;\n private readonly g: Float32Array;\n private readonly b: Float32Array;\n private readonly a: Float32Array;\n private readonly c: Canvas;\n private readonly px: number;\n\n constructor(c: Canvas) {\n this.c = c;\n const n = c.w * c.h;\n this.r = new Float32Array(n);\n this.g = new Float32Array(n);\n this.b = new Float32Array(n);\n this.a = new Float32Array(n);\n this.px = c.metresU / c.w;\n c.height.fill(0);\n }\n\n /** Composite `cov` of colour (cr, cg, cb) × shade over texel i. */\n private put(i: number, cov: number, col: Rgb, shade: number, h: number, rough: number): void {\n if (cov <= 0) return;\n const k = 1 - cov;\n const s = shade * cov;\n this.r[i] = (this.r[i] ?? 0) * k + col[0] * s;\n this.g[i] = (this.g[i] ?? 0) * k + col[1] * s;\n this.b[i] = (this.b[i] ?? 0) * k + col[2] * s;\n this.a[i] = (this.a[i] ?? 0) * k + cov;\n this.c.height[i] = (this.c.height[i] ?? 0) * k + h * cov;\n this.c.rough[i] = (this.c.rough[i] ?? 0.8) * k + rough * cov;\n }\n\n /** Pixel bounds of a metre-space box, clipped to the canvas. */\n private span(x0: number, y0: number, x1: number, y1: number): readonly number[] {\n const { w, h } = this.c;\n const p = this.px;\n return [\n Math.max(0, Math.floor(x0 / p) - 1),\n Math.max(0, Math.floor(y0 / p) - 1),\n Math.min(w - 1, Math.ceil(x1 / p) + 1),\n Math.min(h - 1, Math.ceil(y1 / p) + 1),\n ];\n }\n\n /** A tapered stem / twig / rachis from (ax, ay) width w0 to (bx, by) width w1, metres. */\n stem(ax: number, ay: number, bx: number, by: number, w0: number, w1: number, col: Rgb): void {\n const m = Math.max(w0, w1);\n const [sx0 = 0, sy0 = 0, sx1 = 0, sy1 = 0] = this.span(\n Math.min(ax, bx) - m,\n Math.min(ay, by) - m,\n Math.max(ax, bx) + m,\n Math.max(ay, by) + m,\n );\n const lx = bx - ax;\n const ly = by - ay;\n const l2 = lx * lx + ly * ly || 1;\n for (let y = sy0; y <= sy1; y++) {\n const ym = (y + 0.5) * this.px;\n for (let x = sx0; x <= sx1; x++) {\n const xm = (x + 0.5) * this.px;\n const t = clamp01(((xm - ax) * lx + (ym - ay) * ly) / l2);\n const half = (w0 + (w1 - w0) * t) / 2;\n const d = segment(xm, ym, ax, ay, bx, by);\n const cov = clamp01(0.5 - (d - half) / this.px);\n const round = half > 0 ? Math.sqrt(Math.max(0, 1 - (d / half) ** 2)) : 0;\n this.put(y * this.c.w + x, cov, col, 1, 0.0015 + half * 0.4 * round, 0.85);\n }\n }\n }\n\n /**\n * A leaf from its base (bx, by) along `angle` (radians, 0 = +V, positive = toward +U), `len`\n * long and `wid` wide at its widest. `serrate` adds teeth; `lift` raises it over earlier layers.\n */\n leaf(\n shape: LeafShape,\n bx: number,\n by: number,\n angle: number,\n len: number,\n wid: number,\n col: Rgb,\n serrate = 0,\n lift = 0,\n ): void {\n const ux = Math.sin(angle);\n const uy = Math.cos(angle);\n // Bounds: the base-to-tip segment padded by the half-width (palmate: the whole blade disc).\n const tx = bx + ux * len;\n const ty = by + uy * len;\n const pad = shape === 'palmate' ? len : wid;\n const [sx0 = 0, sy0 = 0, sx1 = 0, sy1 = 0] = this.span(\n Math.min(bx, tx) - pad,\n Math.min(by, ty) - pad,\n Math.max(bx, tx) + pad,\n Math.max(by, ty) + pad,\n );\n for (let y = sy0; y <= sy1; y++) {\n const ym = (y + 0.5) * this.px - by;\n for (let x = sx0; x <= sx1; x++) {\n const xm = (x + 0.5) * this.px - bx;\n const along = xm * ux + ym * uy;\n const across = xm * uy - ym * ux;\n let sd: number;\n let rib: number;\n if (shape === 'palmate') {\n // Five pointed lobes around the petiole tip; notch at the stem side.\n const rr = Math.hypot(along - len * 0.45, across);\n const th = Math.atan2(across, along - len * 0.45);\n const lobe = 1 - Math.abs(Math.sin(2.5 * th)) ** 0.6;\n const edge =\n len * 0.5 * (0.35 + 0.65 * lobe) * (1 + serrate * Math.abs(Math.sin(18 * th)));\n sd = rr - edge;\n const axis = Math.round(th / LOBE) * LOBE;\n rib = rr * Math.abs(Math.sin(th - axis));\n } else {\n const t = along / len;\n if (t < 0 || t > 1) {\n sd = Math.max(-along, along - len) + Math.abs(across) * 0.5;\n } else {\n const prof =\n shape === 'ovate'\n ? Math.sin(Math.PI * t ** 0.8) ** 0.9\n : shape === 'lance'\n ? Math.sin(Math.PI * t ** 0.6)\n : shape === 'blade'\n ? (1 - t) ** 0.4\n : 1 - 0.6 * t;\n const teeth = 1 - serrate * Math.abs(Math.sin(t * 40));\n sd = Math.abs(across) - (wid / 2) * prof * teeth;\n }\n rib = Math.abs(across);\n }\n const cov = clamp01(0.5 - sd / this.px);\n if (cov <= 0) continue;\n const inside = clamp01(-sd / (wid * 0.5 + 1e-6));\n const vein = 1 - smooth(0, this.px * 1.5, rib);\n const shade = 0.85 + 0.15 * inside;\n this.put(\n y * this.c.w + x,\n cov,\n col,\n shade,\n 0.002 + lift + 0.0015 * inside + 0.0006 * vein,\n 0.6,\n );\n }\n }\n }\n\n /** Write the layers to the canvas: sRGB RGBA with bled colour, occlusion toward the twig. */\n finish(axisX = 0.5, reach = 0.35): void {\n const { w, h } = this.c;\n const n = w * h;\n const sa = total(this.a);\n const mean: Rgb =\n sa > 0 ? [total(this.r) / sa, total(this.g) / sa, total(this.b) / sa] : [0.1, 0.2, 0.05];\n const out = new Uint8Array(n * 4);\n const enc = (v: number): number => SRGB[Math.round(clamp01(v) * 4095)] ?? 0;\n for (let y = 0; y < h; y++) {\n for (let x = 0; x < w; x++) {\n const i = y * w + x;\n const a = this.a[i] ?? 0;\n // Un-premultiply; transparent texels take the mean leaf colour (mip-safe bleed).\n const k = a > 0.02 ? 1 / a : 0;\n const mix = clamp01(a * 4);\n out[i * 4] = enc((this.r[i] ?? 0) * k * mix + mean[0] * (1 - mix));\n out[i * 4 + 1] = enc((this.g[i] ?? 0) * k * mix + mean[1] * (1 - mix));\n out[i * 4 + 2] = enc((this.b[i] ?? 0) * k * mix + mean[2] * (1 - mix));\n out[i * 4 + 3] = Math.round(clamp01(a) * 255);\n const d = Math.abs((x + 0.5) * this.px - axisX);\n this.c.occl[i] = 0.55 + 0.45 * smooth(0, reach, d + (y + 0.5) * this.px * 0.4);\n }\n }\n this.c.rgba = out;\n this.c.metal.fill(0);\n }\n}\n",
22
+ "// Broadleaf foliage cells: a twig grows from the bottom-centre anchor toward +V, side twigs\n// alternate off it, leaves sit at the nodes. A darker back layer of leaves fills the crown first\n// for depth. Variants: beech/oak cluster (ovate, fine teeth), palmate maple, autumn maple\n// (red/orange/yellow per leaf), birch (small serrated leaves on thin drooping twigs).\n\nimport { createRng, type Rng } from '../../core/index.ts';\nimport type { Canvas } from './canvas.ts';\nimport { AUTUMN, at, curve, dim, drawStem, LEAF, vary } from './foliage-common.ts';\nimport { Foliage, type LeafShape, type Rgb } from './foliage-raster.ts';\n\ninterface ClusterSpec {\n readonly shape: LeafShape;\n readonly len: number;\n readonly wid: number;\n readonly serrate: number;\n readonly twigs: number;\n readonly perTwig: number;\n readonly back: number;\n /** Side-twig droop: 0 = straight out, 1 = bends back down. */\n readonly droop: number;\n readonly colour: (rng: Rng) => Rgb;\n}\n\nfunction cluster(c: Canvas, seed: number, s: ClusterSpec): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n const leafAt = (x: number, y: number, a: number, k: number, lift: number): void => {\n const len = s.len * rng.range(0.8, 1.15) * k;\n f.leaf(s.shape, x, y, a, len, s.wid * (len / s.len), s.colour(rng), s.serrate, lift);\n };\n // Back layer: darker, unattached leaves filling the crown silhouette.\n for (let i = 0; i < s.back; i++) {\n const x = 0.5 + rng.range(-0.33, 0.33);\n const y = rng.range(0.3, 0.85);\n const col = dim(s.colour(rng), 0.5);\n const len = s.len * rng.range(0.8, 1.1);\n f.leaf(s.shape, x, y, rng.range(-1.4, 1.4), len, s.wid * (len / s.len), col, s.serrate);\n }\n const main = curve(\n 0.5,\n 0.02,\n 0.5 + rng.range(-0.1, 0.1),\n 0.45,\n 0.5 + rng.range(-0.08, 0.08),\n 0.8,\n );\n drawStem(f, main, 0.016, 0.004, LEAF.twig);\n for (let k = 0; k < s.twigs; k++) {\n const t = 0.22 + (k / Math.max(1, s.twigs - 1)) * 0.6;\n const side = k % 2 === 0 ? 1 : -1;\n const i = at(main, t);\n const bx = main.x[i] ?? 0.5;\n const by = main.y[i] ?? 0.5;\n const a = (main.a[i] ?? 0) + side * rng.range(0.7, 1.1);\n const len = 0.3 * (1 - t * 0.45);\n const ex = bx + Math.sin(a) * len;\n const ey = by + Math.cos(a) * len - s.droop * len * 0.4;\n const twig = curve(bx, by, (bx + ex) / 2, (by + ey) / 2 + len * 0.15, ex, ey, 8);\n drawStem(f, twig, 0.007, 0.002, LEAF.twig);\n for (let q = 1; q <= s.perTwig; q++) {\n const j = at(twig, q / s.perTwig);\n const alt = q % 2 === 0 ? 1 : -1;\n const ta = (twig.a[j] ?? 0) + (q === s.perTwig ? 0 : alt * rng.range(0.5, 0.9));\n leafAt(twig.x[j] ?? 0, twig.y[j] ?? 0, ta, 1 - 0.15 * (1 - q / s.perTwig), 0.002);\n }\n }\n const tip = main.x.length - 1;\n leafAt(main.x[tip] ?? 0.5, main.y[tip] ?? 0.8, main.a[tip] ?? 0, 1.1, 0.003);\n f.finish(0.5, 0.35);\n}\n\nexport function paintBroadleaf(c: Canvas, seed: number): void {\n cluster(c, seed, {\n shape: 'ovate',\n len: 0.15,\n wid: 0.085,\n serrate: 0.03,\n twigs: 6,\n perTwig: 3,\n back: 16,\n droop: 0.1,\n colour: (rng) => vary(rng, LEAF.beech, 0.18),\n });\n}\n\nexport function paintMaple(c: Canvas, seed: number): void {\n cluster(c, seed, {\n shape: 'palmate',\n len: 0.24,\n wid: 0.24,\n serrate: 0.04,\n twigs: 4,\n perTwig: 2,\n back: 7,\n droop: 0,\n colour: (rng) => vary(rng, LEAF.maple, 0.15),\n });\n}\n\nexport function paintMapleAutumn(c: Canvas, seed: number): void {\n cluster(c, seed, {\n shape: 'palmate',\n len: 0.24,\n wid: 0.24,\n serrate: 0.04,\n twigs: 4,\n perTwig: 2,\n back: 7,\n droop: 0,\n colour: (rng) => vary(rng, rng.pick(AUTUMN), 0.12),\n });\n}\n\nexport function paintBirch(c: Canvas, seed: number): void {\n cluster(c, seed, {\n shape: 'ovate',\n len: 0.085,\n wid: 0.06,\n serrate: 0.12,\n twigs: 8,\n perTwig: 5,\n back: 22,\n droop: 0.6,\n colour: (rng) => vary(rng, LEAF.birch, 0.2),\n });\n}\n",
23
+ "// Compound and strand foliage cells, all growing from the bottom-centre anchor toward +V:\n// pinnate acacia (rachis, paired pinnae, tiny leaflets), palm frond (arched rachis, lance\n// leaflets both sides, some dry brown tips), willow curtain (long fine strands of narrow leaves;\n// hang it by mapping the card with V down). A dimmed back layer goes down first.\n\nimport { createRng } from '../../core/index.ts';\nimport type { Canvas } from './canvas.ts';\nimport { at, curve, dim, drawStem, LEAF, vary } from './foliage-common.ts';\nimport { Foliage } from './foliage-raster.ts';\n\nexport function paintAcacia(c: Canvas, seed: number): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n const rachis = curve(0.5, 0.02, 0.48 + rng.range(-0.05, 0.05), 0.5, 0.5, 0.95);\n for (let layer = 0; layer < 2; layer++) {\n const k = layer === 0 ? 0.5 : 1;\n if (layer === 1) drawStem(f, rachis, 0.01, 0.003, LEAF.twig);\n const pairs = layer === 0 ? 6 : 8;\n for (let p = 0; p < pairs; p++) {\n const t = 0.15 + (p / pairs) * 0.8 + (layer === 0 ? 0.05 : 0);\n const i = at(rachis, t);\n for (const side of [-1, 1]) {\n const a = (rachis.a[i] ?? 0) + side * rng.range(0.9, 1.2);\n const len = 0.22 * (1 - t * 0.5);\n const bx = rachis.x[i] ?? 0.5;\n const by = rachis.y[i] ?? 0.5;\n const pinna = curve(\n bx,\n by,\n bx + Math.sin(a) * len * 0.5,\n by + Math.cos(a) * len * 0.5 + 0.02,\n bx + Math.sin(a) * len,\n by + Math.cos(a) * len,\n 6,\n );\n drawStem(f, pinna, 0.003, 0.0015, dim(LEAF.twig, k));\n for (let q = 1; q <= 12; q++) {\n const j = at(pinna, q / 12.5);\n const col = dim(vary(rng, LEAF.acacia, 0.15), k);\n for (const s2 of [-1, 1])\n f.leaf(\n 'ovate',\n pinna.x[j] ?? 0,\n pinna.y[j] ?? 0,\n (pinna.a[j] ?? 0) + s2 * 1.1,\n 0.03,\n 0.011,\n col,\n 0,\n layer * 0.002,\n );\n }\n }\n }\n }\n f.finish(0.5, 0.25);\n}\n\nexport function paintPalm(c: Canvas, seed: number): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n const rachis = curve(0.5, 0.02, 0.3, 0.7, 0.78, 0.96, 24);\n for (let layer = 0; layer < 2; layer++) {\n const k = layer === 0 ? 0.55 : 1;\n const n = 26;\n for (let q = 0; q < n; q++) {\n const t = 0.1 + (q / n) * 0.9 + (layer === 0 ? 0.015 : 0);\n const i = at(rachis, Math.min(1, t));\n const bx = rachis.x[i] ?? 0.5;\n const by = rachis.y[i] ?? 0.5;\n for (const side of [-1, 1]) {\n const a = (rachis.a[i] ?? 0) + side * rng.range(0.75, 1.0);\n const len = 0.3 * Math.sin(Math.PI * (0.2 + 0.75 * t)) * rng.range(0.85, 1.05);\n const wid = 0.03;\n f.leaf('lance', bx, by, a, len, wid, dim(vary(rng, LEAF.palm, 0.15), k), 0, layer * 0.002);\n if (rng.next() < 0.3) {\n const tx = bx + Math.sin(a) * len * 0.72;\n const ty = by + Math.cos(a) * len * 0.72;\n f.leaf(\n 'blade',\n tx,\n ty,\n a,\n len * 0.28,\n wid * 0.55,\n dim(vary(rng, LEAF.dry, 0.2), k),\n 0,\n layer * 0.002 + 0.0002,\n );\n }\n }\n }\n if (layer === 0) drawStem(f, rachis, 0.018, 0.004, dim(LEAF.palm, 0.8));\n }\n f.finish(0.5, 0.2);\n}\n\nexport function paintWillow(c: Canvas, seed: number): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n const strands = 9;\n for (let s = 0; s < strands; s++) {\n const back = s < 3;\n const k = back ? 0.55 : 1;\n const ex = 0.5 + rng.range(-0.4, 0.4);\n const strand = curve(\n 0.5 + rng.range(-0.03, 0.03),\n 0.02,\n (0.5 + ex) / 2 + rng.range(-0.1, 0.1),\n 0.5,\n ex,\n rng.range(0.85, 0.97),\n 24,\n );\n drawStem(f, strand, 0.006, 0.0015, dim(LEAF.twig, k));\n for (let q = 2; q < 30; q++) {\n const j = at(strand, q / 30);\n const side = q % 2 === 0 ? 1 : -1;\n const a = (strand.a[j] ?? 0) + side * rng.range(0.2, 0.45);\n const col = dim(vary(rng, LEAF.willow, 0.18), k);\n f.leaf(\n 'lance',\n strand.x[j] ?? 0,\n strand.y[j] ?? 0,\n a,\n rng.range(0.07, 0.1),\n 0.014,\n col,\n 0,\n back ? 0 : 0.002,\n );\n }\n }\n f.finish(0.5, 0.2);\n}\n",
24
+ "// Needle and blade foliage cells, growing from the bottom-centre anchor toward +V: spruce comb\n// (needle tufts off both sides of an axis and its side shoots), snow-loaded spruce (the same with\n// snow lumps riding the upper side of each shoot), conifer needle spray (pine bundles fanning from\n// twig tips) and reeds/grass (tapering blades, some dry).\n\nimport { createRng, type Rng } from '../../core/index.ts';\nimport type { Canvas } from './canvas.ts';\nimport { at, type Curve, curve, dim, drawStem, LEAF, vary } from './foliage-common.ts';\nimport { Foliage } from './foliage-raster.ts';\n\n/** Needles off both sides of a shoot, angled forward, densest mid-shoot. */\nfunction comb(f: Foliage, rng: Rng, shoot: Curve, len: number, k: number, lift: number): void {\n const n = shoot.x.length - 1;\n for (let i = 0; i <= n; i++) {\n for (const side of [-1, 1]) {\n const a = (shoot.a[i] ?? 0) + side * rng.range(0.7, 1.0);\n const col = dim(vary(rng, LEAF.spruce, 0.2), k);\n f.leaf(\n 'needle',\n shoot.x[i] ?? 0,\n shoot.y[i] ?? 0,\n a,\n len * rng.range(0.8, 1.1),\n 0.006,\n col,\n 0,\n lift,\n );\n }\n }\n}\n\nfunction spruce(c: Canvas, seed: number, snow: boolean): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n const axis = curve(0.5, 0.02, 0.5 + rng.range(-0.04, 0.04), 0.5, 0.5, 0.95, 60);\n const shoots: Curve[] = [];\n for (let s = 0; s < 8; s++) {\n const t = 0.15 + (s / 8) * 0.75;\n const i = at(axis, t);\n const side = s % 2 === 0 ? 1 : -1;\n const bx = axis.x[i] ?? 0.5;\n const by = axis.y[i] ?? 0.5;\n const len = 0.32 * (1 - t * 0.6);\n const a = side * rng.range(0.9, 1.2);\n shoots.push(\n curve(\n bx,\n by,\n bx + Math.sin(a) * len * 0.5,\n by + Math.cos(a) * len * 0.5,\n bx + Math.sin(a) * len,\n by + Math.cos(a) * len + 0.03,\n 24,\n ),\n );\n }\n for (const sh of shoots) comb(f, rng, sh, 0.045, 0.55, 0);\n drawStem(f, axis, 0.012, 0.004, LEAF.bark);\n for (const sh of shoots) drawStem(f, sh, 0.005, 0.002, LEAF.bark);\n comb(f, rng, axis, 0.05, 1, 0.002);\n for (const sh of shoots) comb(f, rng, sh, 0.04, 1, 0.002);\n if (snow) {\n for (const sh of [axis, ...shoots]) {\n const n = sh.x.length - 1;\n for (let i = 2; i < n; i += 3) {\n const col = vary(rng, LEAF.snow, 0.05);\n f.leaf(\n 'ovate',\n (sh.x[i] ?? 0) - 0.02,\n (sh.y[i] ?? 0) + 0.008,\n Math.PI / 2 + rng.range(-0.3, 0.3),\n rng.range(0.04, 0.07),\n rng.range(0.025, 0.04),\n col,\n 0,\n 0.006,\n );\n }\n }\n }\n f.finish(0.5, 0.25);\n}\n\nexport const paintSpruce = (c: Canvas, seed: number): void => spruce(c, seed, false);\nexport const paintSpruceSnow = (c: Canvas, seed: number): void => spruce(c, seed, true);\n\nexport function paintNeedles(c: Canvas, seed: number): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n const twigs: Curve[] = [];\n for (let s = 0; s < 5; s++) {\n const ex = 0.5 + (s - 2) * 0.13 + rng.range(-0.03, 0.03);\n twigs.push(curve(0.5, 0.02, 0.5 + (ex - 0.5) * 0.4, 0.3, ex, rng.range(0.55, 0.7), 12));\n }\n for (const [s, tw] of twigs.entries()) {\n drawStem(f, tw, 0.012, 0.006, LEAF.bark);\n const k = s % 2 === 0 ? 0.6 : 1;\n // Bundles along the outer third and a full brush at the tip, fanning forward.\n for (let i = 6; i < tw.x.length; i++) {\n const fan = i === tw.x.length - 1 ? 14 : 4;\n for (let q = 0; q < fan; q++) {\n const a = (tw.a[i] ?? 0) + rng.range(-1.1, 1.1) * (fan > 4 ? 0.8 : 1.2);\n const col = dim(vary(rng, LEAF.pine, 0.2), k);\n f.leaf(\n 'needle',\n tw.x[i] ?? 0,\n tw.y[i] ?? 0,\n a,\n rng.range(0.12, 0.2),\n 0.006,\n col,\n 0,\n k * 0.002,\n );\n }\n }\n }\n f.finish(0.5, 0.3);\n}\n\nexport function paintReeds(c: Canvas, seed: number): void {\n const rng = createRng(seed);\n const f = new Foliage(c);\n for (let b = 0; b < 22; b++) {\n const back = b < 8;\n const x = 0.5 + rng.range(-0.2, 0.2);\n const tilt = (x - 0.5) * 1.2 + rng.range(-0.25, 0.25);\n const col = dim(vary(rng, rng.next() < 0.2 ? LEAF.dry : LEAF.reed, 0.2), back ? 0.55 : 1);\n f.leaf(\n 'blade',\n x,\n 0.0,\n tilt,\n rng.range(0.55, 0.97),\n rng.range(0.018, 0.032),\n col,\n 0,\n back ? 0 : 0.002,\n );\n }\n f.finish(0.5, 0.15);\n}\n",
25
+ "// Foliage cell dispatch: FoliageCellId → painter. Each paints colour + alpha mask (cutout leaf\n// cards), anchor at the cell's bottom-centre, growth toward +V.\n\nimport type { FoliageCellId } from '../trim-sheet.ts';\nimport type { Canvas } from './canvas.ts';\nimport { paintBirch, paintBroadleaf, paintMaple, paintMapleAutumn } from './foliage-broad.ts';\nimport { paintAcacia, paintPalm, paintWillow } from './foliage-compound.ts';\nimport { paintNeedles, paintReeds, paintSpruce, paintSpruceSnow } from './foliage-conifer.ts';\n\nexport const FOLIAGE_PAINTERS: Readonly<Record<FoliageCellId, (c: Canvas, seed: number) => void>> =\n {\n foliage_broadleaf: paintBroadleaf,\n foliage_maple: paintMaple,\n foliage_maple_autumn: paintMapleAutumn,\n foliage_birch: paintBirch,\n foliage_acacia: paintAcacia,\n foliage_palm: paintPalm,\n foliage_spruce: paintSpruce,\n foliage_spruce_snow: paintSpruceSnow,\n foliage_willow: paintWillow,\n foliage_reeds: paintReeds,\n foliage_needles: paintNeedles,\n };\n",
26
+ "// Minimal PNG decoder for stamping supplied images into cells and image strips: 8- or 16-bit grey,\n// grey+alpha, RGB, RGBA (16-bit keeps the high byte) and 8-bit palette (with tRNS), non-interlaced. Zero dependencies beyond node:zlib. Anything else\n// throws T3D_RECIPE_INVALID with the conversion to make.\n\nimport { inflateSync } from 'node:zlib';\nimport { Ts23dError } from '../../core/index.ts';\n\nexport interface Rgba {\n readonly width: number;\n readonly height: number;\n readonly data: Uint8Array;\n}\n\nconst SIG = [137, 80, 78, 71, 13, 10, 26, 10];\nconst CHANNELS: Readonly<Record<number, number>> = { 0: 1, 2: 3, 3: 1, 4: 2, 6: 4 };\n\nfunction bad(cause: string): never {\n throw new Ts23dError('T3D_RECIPE_INVALID', {\n cause: `cell image: ${cause}`,\n fix: 'pass PNG bytes, 8 or 16 bits per channel, non-interlaced (e.g. re-save as RGBA8 PNG)',\n });\n}\n\nfunction paeth(a: number, b: number, c: number): number {\n const p = a + b - c;\n const pa = Math.abs(p - a);\n const pb = Math.abs(p - b);\n const pc = Math.abs(p - c);\n return pa <= pb && pa <= pc ? a : pb <= pc ? b : c;\n}\n\nexport function decodePng(bytes: Uint8Array): Rgba {\n if (bytes.length < 33 || SIG.some((s, i) => bytes[i] !== s)) bad('not a PNG (bad signature)');\n const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n let width = 0;\n let height = 0;\n let type = -1;\n let depth = 8;\n let palette: Uint8Array = new Uint8Array();\n let trns: Uint8Array = new Uint8Array();\n const idat: Uint8Array[] = [];\n for (let o = 8; o + 8 <= bytes.length; ) {\n const len = dv.getUint32(o);\n const name = String.fromCharCode(...bytes.subarray(o + 4, o + 8));\n const body = bytes.subarray(o + 8, o + 8 + len);\n if (name === 'IHDR') {\n width = dv.getUint32(o + 8);\n height = dv.getUint32(o + 12);\n type = body[9] ?? -1;\n depth = body[8] ?? 0;\n if (depth !== 8 && !(depth === 16 && type !== 3))\n bad(`bit depth ${depth} (8, or 16 for non-palette images, is supported)`);\n if (body[12] !== 0) bad('interlaced');\n } else if (name === 'PLTE') palette = body;\n else if (name === 'tRNS') trns = body;\n else if (name === 'IDAT') idat.push(body);\n else if (name === 'IEND') break;\n o += 12 + len;\n }\n const ch = CHANNELS[type];\n if (!ch || width === 0 || height === 0) bad(`colour type ${type} or empty image`);\n const raw = new Uint8Array(inflateSync(Buffer.concat(idat)));\n const B = depth / 8;\n const bpp = ch * B;\n const stride = width * bpp;\n if (raw.length < height * (stride + 1)) bad('truncated image data');\n const px = new Uint8Array(height * stride);\n for (let y = 0; y < height; y++) {\n const f = raw[y * (stride + 1)] ?? 0;\n const src = y * (stride + 1) + 1;\n const row = y * stride;\n for (let x = 0; x < stride; x++) {\n const a = x >= bpp ? (px[row + x - bpp] ?? 0) : 0;\n const b = y > 0 ? (px[row - stride + x] ?? 0) : 0;\n const c = x >= bpp && y > 0 ? (px[row - stride + x - bpp] ?? 0) : 0;\n const v = raw[src + x] ?? 0;\n const pred =\n f === 1 ? a : f === 2 ? b : f === 3 ? (a + b) >> 1 : f === 4 ? paeth(a, b, c) : 0;\n px[row + x] = (v + pred) & 255;\n }\n }\n const data = new Uint8Array(width * height * 4);\n for (let i = 0; i < width * height; i++) {\n const s = i * bpp;\n const at = (k: number): number => px[s + k * B] ?? 0;\n const g = at(0);\n const o = i * 4;\n if (type === 3) {\n data[o] = palette[g * 3] ?? 0;\n data[o + 1] = palette[g * 3 + 1] ?? 0;\n data[o + 2] = palette[g * 3 + 2] ?? 0;\n data[o + 3] = trns[g] ?? 255;\n } else if (ch >= 3) {\n data[o] = g;\n data[o + 1] = at(1);\n data[o + 2] = at(2);\n data[o + 3] = ch === 4 ? at(3) : 255;\n } else {\n data[o] = g;\n data[o + 1] = g;\n data[o + 2] = g;\n data[o + 3] = ch === 2 ? at(1) : 255;\n }\n }\n return { width, height, data };\n}\n",
27
+ "// Stamp a supplied PNG into a cell canvas: bilinear resample to the cell, flipped so the image's\n// top row lands at world-up (high V, where box/planar put a face's top). Flat relief, the\n// recipe-free roughness default; the image's own colour is kept (vertex colour still multiplies).\n\nimport type { Canvas } from './canvas.ts';\nimport { decodePng } from './decode-png.ts';\n\nexport const STAMP_ROUGHNESS = 0.6;\n\nexport function stampImage(c: Canvas, png: Uint8Array): void {\n const img = decodePng(png);\n const out = new Uint8Array(c.w * c.h * 4);\n for (let y = 0; y < c.h; y++) {\n const sy = Math.min(\n img.height - 1,\n Math.max(0, ((c.h - 1 - y + 0.5) / c.h) * img.height - 0.5),\n );\n const y0 = Math.floor(sy);\n const y1 = Math.min(img.height - 1, y0 + 1);\n const fy = sy - y0;\n for (let x = 0; x < c.w; x++) {\n const sx = Math.min(img.width - 1, Math.max(0, ((x + 0.5) / c.w) * img.width - 0.5));\n const x0 = Math.floor(sx);\n const x1 = Math.min(img.width - 1, x0 + 1);\n const fx = sx - x0;\n for (let k = 0; k < 4; k++) {\n const a = img.data[(y0 * img.width + x0) * 4 + k] ?? 0;\n const b = img.data[(y0 * img.width + x1) * 4 + k] ?? 0;\n const d = img.data[(y1 * img.width + x0) * 4 + k] ?? 0;\n const e = img.data[(y1 * img.width + x1) * 4 + k] ?? 0;\n const top = a + (b - a) * fx;\n out[(y * c.w + x) * 4 + k] = Math.round(top + (d + (e - d) * fx - top) * fy);\n }\n }\n }\n c.rgba = out;\n c.height.fill(0);\n c.rough.fill(STAMP_ROUGHNESS);\n c.metal.fill(0);\n}\n",
28
+ "// Running-bond layout shared by bricks, stone, planks, slates and plates: horizontal courses\n// (rows along V) split into tiles by vertical joints, staggered per course and periodic along U.\n// Per-course column tables are filled once per course, so the per-pixel loop only reads arrays.\n\nimport { createRng } from '../../core/index.ts';\nimport type { Canvas } from './canvas.ts';\n\nexport interface CourseSpec {\n /** Course height, metres (along V). */\n readonly course: number;\n /** Mean tile length, metres (along U). */\n readonly length: number;\n /** 0 = regular; 0.5 = sizes vary ±25 %. */\n readonly irregular: number;\n /** Fraction of a tile each odd course shifts; random offsets when irregular. */\n readonly stagger: number;\n readonly seed: number;\n}\n\nexport class Courses {\n /** Tile index within the current course, per column. */\n readonly id: Int32Array;\n /** Distance to the nearest vertical joint, metres, per column. */\n readonly dx: Float32Array;\n /** Distance from the tile's left joint, metres, per column. */\n readonly ux: Float32Array;\n /** The current course: index and its bottom / top in metres. */\n index = -1;\n y0 = 0;\n y1 = 0;\n private readonly bounds: number[] = [0];\n private readonly c: Canvas;\n private readonly spec: CourseSpec;\n\n constructor(c: Canvas, spec: CourseSpec) {\n this.c = c;\n this.spec = spec;\n this.id = new Int32Array(c.w);\n this.dx = new Float32Array(c.w);\n this.ux = new Float32Array(c.w);\n const rng = createRng(spec.seed).fork('rows');\n let y = 0;\n while (y < c.metresV) {\n y += spec.course * (1 + spec.irregular * (rng.next() - 0.5));\n this.bounds.push(y);\n }\n }\n\n /** Point the tables at the course containing metres `ym`; returns the course index. */\n at(ym: number): number {\n if (this.index >= 0 && ym >= this.y0 && ym < this.y1) return this.index;\n let k = 0;\n while (k < this.bounds.length - 2 && ym >= (this.bounds[k + 1] ?? 0)) k++;\n this.index = k;\n this.y0 = this.bounds[k] ?? 0;\n this.y1 = this.bounds[k + 1] ?? this.c.metresV;\n this.fill(k);\n return k;\n }\n\n private fill(k: number): void {\n const { w, metresU } = this.c;\n const s = this.spec;\n const rng = createRng(s.seed).fork(`course${k}`);\n const n = Math.max(1, Math.round(metresU / s.length));\n const lens: number[] = [];\n for (let i = 0; i < n; i++) lens.push(1 + s.irregular * (rng.next() - 0.5));\n const total = lens.reduce((a, b) => a + b, 0);\n const joints = [0];\n for (const l of lens) joints.push((joints[joints.length - 1] ?? 0) + (l / total) * metresU);\n const shift = s.irregular > 0 ? rng.next() * metresU : (k % 2) * s.stagger * (metresU / n);\n const px = metresU / w;\n for (let x = 0; x < w; x++) {\n let u = ((x + 0.5) * px - shift) % metresU;\n if (u < 0) u += metresU;\n let t = 0;\n while (t < n - 1 && u >= (joints[t + 1] ?? metresU)) t++;\n const a = joints[t] ?? 0;\n const b = joints[t + 1] ?? metresU;\n this.id[x] = t;\n this.ux[x] = u - a;\n this.dx[x] = Math.min(u - a, b - u);\n }\n }\n}\n",
29
+ "// Brick and stone bond (kind 'bond'): staggered courses, recessed mortar with chipped edges,\n// per-unit tone and tilt, face pitting. Stone is the same bond with `irregular` > 0 and bigger,\n// rougher units.\n// params: course 0.075 · length 0.225 · mortar 0.01 · depth 0.006 · bevel 0.004 · irregular 0\n// stagger 0.5 · relief 0.0008 (face roughness amplitude, m) · variation 0.3 (tone spread)\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport { Courses } from './courses.ts';\nimport { hash2 } from './noise.ts';\nimport type { StripRecipe } from './types.ts';\n\nexport function paintBond(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const mortar = param(p, 'mortar', 0.01);\n const depth = param(p, 'depth', 0.006);\n const bevel = param(p, 'bevel', 0.004);\n const relief = param(p, 'relief', 0.0008);\n const variation = param(p, 'variation', 0.3);\n const course = param(p, 'course', 0.075);\n const length = param(p, 'length', 0.225);\n const courses = new Courses(c, {\n course,\n length,\n irregular: param(p, 'irregular', 0),\n stagger: param(p, 'stagger', 0.5),\n seed,\n });\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const half = mortar / 2;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const k = courses.at(ym);\n const dy = Math.min(ym - courses.y0, courses.y1 - ym);\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const unit = courses.id[x] ?? 0;\n const chip = noiseAt(c, xm, ym, 0.02, 0.02, seed + 7, 3) * mortar * 0.6;\n const d = Math.min(courses.dx[x] ?? 0, dy) + chip;\n const fine = noiseAt(c, xm, ym, 0.006, 0.006, seed + 11, 2);\n if (d < half) {\n c.height[i] = -depth + fine * 0.0006;\n c.tone[i] = 0.95 + 0.04 * fine;\n c.rough[i] = Math.min(1, r.roughness + 0.08);\n continue;\n }\n const h = hash2(k, unit, seed);\n const h2 = hash2(unit, k, seed + 3);\n const big = noiseAt(c, xm, ym, length * 0.6, course * 0.8, seed + 5, 3);\n const edge = smooth(0, bevel, d - half);\n const tilt = ((h2 - 0.5) * (courses.ux[x] ?? 0) * 0.02 + (h - 0.5) * 0.001) * edge;\n const pit = fine > 0.55 ? (fine - 0.55) * 0.004 : 0;\n c.height[i] = -depth * (1 - edge) + relief * big + tilt - pit;\n c.tone[i] =\n (0.62 - variation * 0.5 + variation * h) * (1 + 0.15 * big + 0.05 * fine) - pit * 40;\n c.rough[i] = r.roughness + 0.06 * fine;\n }\n }\n}\n",
30
+ "// Cast concrete (kind 'concrete'): mottled cement tone, air-void pores, pour-lift lines and\n// formwork tie holes on a grid.\n// params: pores 0.35 (fraction of 8 mm cells holding a void) · ties 0.6 (tie grid, m; 0 = none)\n// lift 0.6 (pour lift spacing, m; 0 = none) · mottle 0.1\n\nimport { type Canvas, noiseAt, param, periodFor, smooth } from './canvas.ts';\nimport { hash2 } from './noise.ts';\nimport type { StripRecipe } from './types.ts';\n\nconst PORE_CELL = 0.008;\n\nexport function paintConcrete(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const pores = param(p, 'pores', 0.35);\n const ties = param(p, 'ties', 0.6);\n const lift = param(p, 'lift', 0.6);\n const mottle = param(p, 'mottle', 0.1);\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const cellM = Math.max(PORE_CELL, 2.5 * Math.max(pu, pv));\n const pPer = periodFor(c, cellM);\n const pCell = c.wrapU ? c.metresU / pPer : cellM;\n const tPer = ties > 0 ? periodFor(c, ties) : 1;\n const tCell = c.wrapU ? c.metresU / tPer : ties;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const liftD = lift > 0 ? Math.abs(ym - Math.round(ym / lift) * lift) : 1;\n const liftGroove = 1 - smooth(0, 0.003, liftD);\n const liftBand = lift > 0 ? hash2(Math.floor(ym / lift), 0, seed + 4) - 0.5 : 0;\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const big = noiseAt(c, xm, ym, 0.25, 0.25, seed, 4);\n const fine = noiseAt(c, xm, ym, 0.004, 0.004, seed + 2, 2);\n const ix = Math.floor(xm / pCell) % pPer;\n const iy = Math.floor(ym / pCell);\n let pit = 0;\n if (hash2(ix, iy, seed + 5) < pores) {\n const cx = (ix + 0.2 + 0.6 * hash2(ix, iy, seed + 6)) * pCell;\n const cy = (iy + 0.2 + 0.6 * hash2(ix, iy, seed + 7)) * pCell;\n const rad = pCell * (0.12 + 0.25 * hash2(ix, iy, seed + 8));\n const d = Math.hypot(xm - cx, ym - cy);\n pit = d < rad ? 1 - d / rad : 0;\n }\n let tie = 0;\n if (ties > 0) {\n const tx = xm - (Math.floor(xm / tCell) + 0.5) * tCell;\n const ty = ym - (Math.floor(ym / ties) + 0.5) * ties;\n const d = Math.hypot(tx, ty);\n tie = d < 0.012 ? 1 : 0;\n }\n c.height[i] =\n 0.0005 * big + 0.00015 * fine - 0.0015 * pit - 0.006 * tie - 0.0012 * liftGroove;\n c.tone[i] =\n (0.78 + mottle * big + 0.05 * liftBand) *\n (1 + 0.04 * fine) *\n (1 - 0.4 * pit) *\n (1 - 0.5 * tie);\n c.rough[i] = r.roughness + 0.05 * fine + 0.05 * big;\n }\n }\n}\n",
31
+ "// Soft goods. 'weave': canvas / duck cloth — an over-under thread lattice (warp along U, weft\n// along V, never finer than the texel), slubbed threads, soft folds and water stains toward the\n// bottom. 'leather': pebbled grain, creases running across the hide and burnished wear where it\n// is handled (smoother, a little lighter, darker in the creases).\n// params (weave): pitch 0.004 · folds 0.6 · stains 0.3\n// params (leather): pebble 0.004 · creases 0.5 · wear 0.4\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport type { StripRecipe } from './types.ts';\n\nexport function paintWeave(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n // Threads below ~2 texels alias into moiré: keep the lattice resolvable on both axes.\n const pitchU = Math.max(param(p, 'pitch', 0.004), 2 * pu);\n const pitchV = Math.max(param(p, 'pitch', 0.004), 2 * pv);\n const folds = param(p, 'folds', 0.6);\n const stains = param(p, 'stains', 0.3);\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const wy = Math.sin((ym / pitchV) * Math.PI * 2);\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const wx = Math.sin((xm / pitchU) * Math.PI * 2);\n const over = Math.floor(xm / pitchU) + Math.floor(ym / pitchV);\n const thread = over % 2 === 0 ? Math.abs(wy) : Math.abs(wx);\n const slub = noiseAt(c, xm, ym, 0.05, 0.01, seed, 2);\n const fold = noiseAt(c, xm, ym, 0.5, 0.35, seed + 1, 3);\n const stain = stains * smooth(0.1, 0.6, noiseAt(c, xm, ym, 0.2, 0.15, seed + 2, 4));\n c.height[i] = 0.0002 * thread + 0.003 * folds * fold;\n c.tone[i] = (0.9 + 0.06 * thread + 0.05 * slub) * (1 - 0.25 * stain);\n c.rough[i] = Math.min(1, r.roughness + 0.04 * slub - 0.03 * thread);\n c.metal[i] = 0;\n c.mix[i] = stain;\n }\n }\n}\n\nexport function paintLeather(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const pebble = param(p, 'pebble', 0.004);\n const creases = param(p, 'creases', 0.5);\n const wear = param(p, 'wear', 0.4);\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const grain = noiseAt(c, xm, ym, pebble, pebble, seed, 3);\n const crease = smooth(0.4, 0.6, noiseAt(c, xm, ym, 0.12, 0.012, seed + 1, 3)) * creases;\n const rub = wear * smooth(0, 0.6, noiseAt(c, xm, ym, 0.3, 0.3, seed + 2, 4));\n c.height[i] = 0.00025 * grain - 0.0008 * crease;\n c.tone[i] = (0.95 + 0.05 * grain) * (1 - 0.45 * crease) * (1 + 0.12 * rub);\n c.rough[i] = Math.min(1, Math.max(0, r.roughness + 0.06 * grain - 0.2 * rub + 0.1 * crease));\n c.metal[i] = 0;\n c.mix[i] = crease;\n }\n }\n}\n",
32
+ "// Paint a strip from a CC0 texture set: decode the cached PNGs, box-filter them onto the strip's\n// texel grid at true scale (the set's `metres`, snapped so a whole number of repeats spans the\n// strip's U length — it still tiles), V flipped so the image's top is world up. Albedo stays sRGB\n// colour (tint with NATURAL); the OpenGL normal's green is flipped to the sheet's +Y = −V; `arm`\n// fills occlusion / roughness / metalness, else the recipe's constants.\n\nimport type { TextureFile, TextureSource } from '../texture-source.ts';\nimport { textureBytes } from '../texture-source.ts';\nimport type { Canvas } from './canvas.ts';\nimport { decodePng, type Rgba } from './decode-png.ts';\nimport type { StripRecipe } from './types.ts';\n\nconst decoded = new Map<string, Rgba>();\nfunction image(f: TextureFile, where: string): Rgba {\n const hit = decoded.get(f.sha256);\n if (hit) return hit;\n const img = decodePng(textureBytes(f, where));\n decoded.set(f.sha256, img);\n return img;\n}\n\n/** Average of `img` over the canvas texel footprint, per channel, into out[0..3]. */\nfunction resample(\n c: Canvas,\n t: TextureSource,\n img: Rgba,\n fn: (i: number, px: Float32Array) => void,\n) {\n const reps = Math.max(1, Math.round(c.metresU / (t.metres[0] ?? 1)));\n const su = c.metresU / reps;\n const sv = t.metres[1] ?? 1;\n const W = img.width;\n const H = img.height;\n const px = new Float32Array(4);\n for (let y = 0; y < c.h; y++) {\n const v0 = ((y * c.metresV) / c.h / sv) * H;\n const v1 = (((y + 1) * c.metresV) / c.h / sv) * H;\n for (let x = 0; x < c.w; x++) {\n const u0 = ((x * c.metresU) / c.w / su) * W;\n const u1 = (((x + 1) * c.metresU) / c.w / su) * W;\n px.fill(0);\n let n = 0;\n for (let sy = Math.floor(v0); sy < Math.max(Math.floor(v0) + 1, Math.ceil(v1)); sy++) {\n const row = H - 1 - (((sy % H) + H) % H);\n for (let sx = Math.floor(u0); sx < Math.max(Math.floor(u0) + 1, Math.ceil(u1)); sx++) {\n const o = (row * W + (((sx % W) + W) % W)) * 4;\n for (let k = 0; k < 4; k++) px[k] = (px[k] ?? 0) + (img.data[o + k] ?? 0);\n n++;\n }\n }\n for (let k = 0; k < 4; k++) px[k] = (px[k] ?? 0) / n;\n fn(y * c.w + x, px);\n }\n }\n}\n\nexport function paintImageStrip(c: Canvas, r: StripRecipe, t: TextureSource, where: string): void {\n const albedo = new Uint8Array(c.w * c.h * 4);\n resample(c, t, image(t.maps.albedo, where), (i, p) => {\n albedo.set([p[0] ?? 0, p[1] ?? 0, p[2] ?? 0, 255], i * 4);\n });\n c.rgba = albedo;\n c.height.fill(0);\n if (t.maps.normal) {\n const nrm = new Uint8Array(c.w * c.h * 4);\n resample(c, t, image(t.maps.normal, where), (i, p) => {\n const x = (p[0] ?? 128) / 127.5 - 1;\n const y = -((p[1] ?? 128) / 127.5 - 1);\n const z = (p[2] ?? 255) / 127.5 - 1;\n const l = Math.hypot(x, y, z) || 1;\n nrm.set(\n [(x / l) * 127.5 + 127.5, (y / l) * 127.5 + 127.5, (z / l) * 127.5 + 127.5, 255],\n i * 4,\n );\n });\n c.normalRgba = nrm;\n }\n if (t.maps.arm) {\n resample(c, t, image(t.maps.arm, where), (i, p) => {\n c.occl[i] = (p[0] ?? 255) / 255;\n c.rough[i] = (p[1] ?? 204) / 255;\n c.metal[i] = (p[2] ?? 0) / 255;\n });\n } else {\n c.rough.fill(r.roughness);\n c.metal.fill(r.metalness ?? 0);\n }\n}\n",
33
+ "// The helper kit a project painter (`defineMaterial({ paint })`) receives, and the post-check that\n// its layers stayed finite: a NaN written by user code fails loudly instead of corrupting a sheet.\n\nimport { Ts23dError } from '../../core/index.ts';\nimport { type Canvas, noiseAt, smooth } from './canvas.ts';\nimport { hash2 } from './noise.ts';\nimport type { PaintKit } from './types.ts';\n\nexport function paintKit(c: Canvas, seed: number): PaintKit {\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n return {\n seed,\n noise: (xm, ym, sizeU, sizeV, salt = 0, octaves = 4) =>\n noiseAt(c, xm, ym, sizeU, sizeV, seed + salt * 7919, octaves),\n hash: (a, b, salt = 0) => hash2(a, b, seed + salt),\n smooth,\n each(fn) {\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) fn(y * c.w + x, (x + 0.5) * pu, ym);\n }\n },\n };\n}\n\n/** Throw T3D_MATERIAL_INVALID if any layer holds a non-finite value. */\nexport function checkFinite(c: Canvas, where: string): void {\n const layers = { height: c.height, tone: c.tone, rough: c.rough, metal: c.metal, mix: c.mix };\n for (const [name, a] of Object.entries(layers))\n for (let i = 0; i < a.length; i++)\n if (!Number.isFinite(a[i] ?? 0))\n throw new Ts23dError('T3D_MATERIAL_INVALID', {\n cause: `${where}: the painter wrote ${a[i]} into '${name}' at texel ${i}`,\n fix: 'write finite numbers only (guard divisions; clamp with Math.min/Math.max)',\n });\n}\n",
34
+ "// Weathering masks applied over a painted canvas: rust streaks (vertical runs from a patchy\n// source, darker and rougher, killing metalness) and grime (dirt pooling toward the bottom of the\n// region — world-down is low V — plus soft vertical rain streaks). Rust also pushes `mix` toward\n// albedo2, which only shows on material strips that carry a colour pair.\n\nimport { type Canvas, noiseAt, smooth } from './canvas.ts';\n\nexport function rustStreaks(c: Canvas, amount: number, seed: number): void {\n if (amount <= 0) return;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const run = noiseAt(c, xm, ym, 0.025, 0.6, seed, 3);\n const patch = noiseAt(c, xm, ym, 0.3, 0.3, seed + 1, 2);\n const m = amount * smooth(0.15, 0.6, run) * smooth(-0.1, 0.4, patch);\n if (m <= 0) continue;\n const i = y * c.w + x;\n c.tone[i] = (c.tone[i] ?? 1) * (1 - 0.4 * m);\n c.rough[i] = Math.min(1, (c.rough[i] ?? 0.8) + 0.2 * m);\n c.metal[i] = (c.metal[i] ?? 0) * (1 - m);\n c.mix[i] = Math.min(1, (c.mix[i] ?? 0) + m);\n }\n }\n}\n\nexport function grime(c: Canvas, amount: number, seed: number): void {\n if (amount <= 0) return;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const low = (1 - ym / c.metresV) ** 2;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const streak = smooth(0, 0.7, noiseAt(c, xm, ym, 0.05, 0.5, seed, 3));\n const blot = 0.6 + 0.4 * noiseAt(c, xm, ym, 0.2, 0.2, seed + 1, 3);\n const m = amount * Math.min(1, low * blot + 0.35 * streak);\n const i = y * c.w + x;\n c.tone[i] = (c.tone[i] ?? 1) * (1 - 0.3 * m);\n c.rough[i] = Math.min(1, (c.rough[i] ?? 0.8) + 0.1 * m);\n }\n }\n}\n",
35
+ "// Bare and finished metal sheet (kind 'metal'): a continuous metallic base with polish mottling,\n// then optional finishes, each a param in 0..1 — `brush` (fine streaks along U, brushed aluminium),\n// `cast` (sand-cast pits and a rougher skin), `spangle` (galvanised zinc crystals), `oxide`\n// (patches of rust / verdigris: blend to albedo2, dielectric, rough, slightly raised) and `paint`\n// (a dielectric paint film over it whose `chips` reveal the oxidised metal). Rust runs down from\n// the oxide (`streaks`).\n// params: brush 0 · cast 0 · spangle 0 · oxide 0 · paint 0 · paintRough 0.45 · chips 0.25\n// crystal 0.03 (spangle size, m) · streaks 0\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport { rustStreaks } from './masks.ts';\nimport { hash2 } from './noise.ts';\nimport type { StripRecipe } from './types.ts';\n\n/** Nearest jittered grid point id on a `size` m lattice that wraps after `wrapU` metres. */\nfunction crystal(xm: number, ym: number, size: number, cellsU: number, seed: number): number {\n const gx = Math.floor(xm / size);\n const gy = Math.floor(ym / size);\n let best = 1e9;\n let id = 0;\n for (let j = -1; j <= 1; j++)\n for (let i = -1; i <= 1; i++) {\n const cx = (((gx + i) % cellsU) + cellsU) % cellsU;\n const px = (gx + i + hash2(cx, gy + j, seed)) * size;\n const py = (gy + j + hash2(cx, gy + j, seed + 1)) * size;\n const d = (xm - px) ** 2 + (ym - py) ** 2;\n if (d < best) {\n best = d;\n id = hash2(cx, gy + j, seed + 2) * 1e6;\n }\n }\n return id;\n}\n\nexport function paintMetal(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const brush = param(p, 'brush', 0);\n const cast = param(p, 'cast', 0);\n const spangle = param(p, 'spangle', 0);\n const oxide = param(p, 'oxide', 0);\n const paint = param(p, 'paint', 0);\n const paintRough = param(p, 'paintRough', 0.45);\n const chips = param(p, 'chips', 0.25);\n const size = param(p, 'crystal', 0.03);\n const metal = r.metalness ?? 1;\n const cellsU = Math.max(1, Math.round(c.metresU / size));\n const cs = c.metresU / cellsU;\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const big = noiseAt(c, xm, ym, 0.25, 0.25, seed, 4);\n const fine = noiseAt(c, xm, ym, 0.01, 0.01, seed + 1, 2);\n let tone = 1 + 0.05 * big;\n let rough = r.roughness + 0.06 * big + 0.03 * fine;\n let h = 0.00015 * big;\n if (brush > 0) {\n const s = noiseAt(c, xm, ym, 0.6, 0.002, seed + 2, 3);\n tone *= 1 + 0.06 * brush * s;\n rough += 0.08 * brush * s;\n h += 0.00003 * brush * s;\n }\n if (cast > 0) {\n const pit = noiseAt(c, xm, ym, 0.012, 0.012, seed + 3, 3);\n const lump = noiseAt(c, xm, ym, 0.08, 0.08, seed + 4, 3);\n h += cast * (0.0006 * pit + 0.0008 * lump);\n rough += cast * (0.1 + 0.12 * pit);\n tone *= 1 + cast * (0.16 * pit + 0.08 * lump - 0.04);\n }\n if (spangle > 0) {\n const k = crystal(xm, ym, cs, cellsU, seed + 5);\n const v = hash2(k, 7, seed) * 2 - 1;\n tone *= 1 + 0.12 * spangle * v;\n rough += 0.12 * spangle * v;\n }\n // Oxide: patchy, gathering in low-frequency blotches; dielectric, rough and a touch proud.\n let ox = 0;\n if (oxide > 0) {\n const blot = noiseAt(c, xm, ym, 0.18, 0.18, seed + 6, 5);\n const grain = noiseAt(c, xm, ym, 0.02, 0.02, seed + 7, 3);\n ox = smooth(0.45, 0.75, blot * 0.5 + 0.5 + oxide - 0.5 + 0.15 * grain);\n h += ox * 0.0004 * (1 + grain);\n }\n let m = metal * (1 - ox);\n let mix = ox;\n rough = rough * (1 - ox) + (0.88 + 0.06 * fine) * ox;\n if (paint > 0) {\n // Chips gather where the noise peaks; the film is everywhere else.\n const n = noiseAt(c, xm, ym, 0.05, 0.05, seed + 8, 4);\n const chip = smooth(0.42, 0.5, n * 0.5 + 0.5 - (1 - chips) * 0.5 + 0.1);\n const film = paint * (1 - chip);\n m *= 1 - film;\n mix = mix * (1 - film) + chip * paint;\n rough = rough * (1 - film) + (paintRough + 0.05 * big) * film;\n tone = tone * (1 - film) + (0.96 + 0.03 * big) * film;\n h -= chip * paint * 0.00015;\n }\n c.height[i] = h;\n c.tone[i] = tone;\n c.rough[i] = Math.min(1, Math.max(0, rough));\n c.metal[i] = Math.min(1, Math.max(0, m));\n c.mix[i] = mix;\n }\n }\n rustStreaks(c, param(p, 'streaks', 0), seed + 77);\n}\n",
36
+ "// Timber boards (kind 'planks'): boards run along U, butt joints staggered at random, dark gaps,\n// stretched grain with growth-ring streaks, occasional knots, per-board tone. Species and finish\n// come from params on top: `rings` blends latewood to albedo2, `rays` adds oak's ray flecks,\n// `checks` weathers (eroded soft grain, splits along it, silvering), `paint` lays a film over the\n// grain whose `chips` reveal bare wood (albedo2), mostly along board edges.\n// params: width 0.15 · length 1.0 · gap 0.004 · depth 0.004 · knots 1.5 (per board-metre)\n// rings 0 · rays 0 · checks 0 · paint 0 · paintRough 0.5 · chips 0.3\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport { Courses } from './courses.ts';\nimport { hash2 } from './noise.ts';\nimport type { StripRecipe } from './types.ts';\n\nexport function paintPlanks(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const width = param(p, 'width', 0.15);\n const length = param(p, 'length', 1);\n const gap = param(p, 'gap', 0.004);\n const depth = param(p, 'depth', 0.004);\n const knots = param(p, 'knots', 1.5);\n const rings = param(p, 'rings', 0);\n const rays = param(p, 'rays', 0);\n const checks = param(p, 'checks', 0);\n const paint = param(p, 'paint', 0);\n const paintRough = param(p, 'paintRough', 0.5);\n const chips = param(p, 'chips', 0.3);\n const boards = new Courses(c, { course: width, length, irregular: 0.6, stagger: 0, seed });\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const ringsN = Math.max(1, Math.min(9, Math.floor(width / pv / 4)));\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const k = boards.at(ym);\n const dy = Math.min(ym - boards.y0, boards.y1 - ym);\n const vy = (ym - boards.y0) / (boards.y1 - boards.y0);\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const id = boards.id[x] ?? 0;\n const h = hash2(k, id, seed);\n const d = Math.min((boards.dx[x] ?? 0) * 1.5, dy);\n const edge = smooth(gap * 0.5, gap * 1.5, d);\n // Grain: rings warped by a long, thin noise; the board's own seed shifts its figure.\n const warp = noiseAt(c, xm, ym, 0.4, 0.05, seed + id * 31 + k * 7, 3);\n const ring = Math.sin((vy * 9 + warp * 3 + h * 6) * Math.PI * 2);\n const fibre = noiseAt(c, xm, ym, 0.08, 0.002, seed + 17, 2);\n let knot = 0;\n const nk = Math.floor(knots * length * h * 2);\n for (let q = 0; q < nk; q++) {\n const kx = hash2(k * 13 + q, id, seed + 41) * c.metresU;\n const ky =\n boards.y0 + (0.25 + 0.5 * hash2(k, id * 5 + q, seed + 43)) * (boards.y1 - boards.y0);\n let ddx = Math.abs(xm - kx);\n if (c.wrapU) ddx = Math.min(ddx, c.metresU - ddx);\n const rr = Math.sqrt((ddx / 2.2) ** 2 + (ym - ky) ** 2) / (width * 0.12);\n if (rr < 1) knot = Math.max(knot, 1 - rr);\n }\n let height = -depth * (1 - edge) + 0.0004 * ring * edge + 0.0003 * fibre - 0.0008 * knot;\n let tone =\n (0.66 + 0.22 * h) *\n (1 + 0.08 * ring + 0.06 * fibre) *\n (1 - 0.5 * knot) *\n (0.5 + 0.5 * edge);\n let rough = r.roughness + 0.05 * fibre + 0.1 * (1 - edge);\n // Colour rings at a frequency the strip's V texels can hold (≥ ~4 texels per ring).\n const ring2 = Math.sin((vy * ringsN + warp * 2.5 + h * 6) * Math.PI * 2);\n const late = smooth(0.1, 0.8, ring2) * (0.75 + 0.25 * fibre);\n let mix = rings * Math.max(late, knot);\n if (rays > 0) {\n const fleck = smooth(0.55, 0.8, noiseAt(c, xm, ym, 0.03, 0.004, seed + 23, 2));\n tone *= 1 + 0.25 * rays * fleck;\n mix *= 1 - rays * fleck;\n }\n if (checks > 0) {\n // Soft earlywood erodes, leaving latewood ridges; splits open along the grain.\n const split = smooth(0.45, 0.6, noiseAt(c, xm, ym, 0.3, 0.003, seed + 29 + id, 3));\n height += checks * (0.0006 * late - 0.002 * split);\n tone *= 1 - checks * (0.45 * split + 0.08 * (1 - late));\n rough += checks * 0.1 * (1 - late);\n mix = Math.max(mix, checks * split);\n }\n if (paint > 0) {\n // Paint fails first at board edges and ends, then in blotches across the face.\n const n = noiseAt(c, xm, ym, 0.04, 0.03, seed + 31, 4) * 0.5 + 0.5;\n const nearEdge = 1 - smooth(gap, gap * 6, d);\n const chip = smooth(0.5, 0.56, n + chips * 0.5 + nearEdge * 0.15 - 0.45);\n const film = paint * (1 - chip);\n height = height * (1 - 0.4 * film) - chip * paint * 0.0002;\n // The film follows the grain: board tone and rings still read through it, faintly.\n const under = (0.9 + 0.06 * h) * (1 + 0.05 * ring + 0.04 * fibre) * (0.55 + 0.45 * edge);\n tone = tone * (1 - film) + under * film;\n rough = rough * (1 - film) + (paintRough + 0.04 * fibre) * film;\n mix = mix * (1 - film) + paint * chip;\n }\n c.height[i] = height;\n c.tone[i] = tone;\n c.rough[i] = Math.min(1, rough);\n c.mix[i] = mix;\n }\n }\n}\n",
37
+ "// Riveted iron plates (kind 'plates'): lapped plates (each overlaps its left neighbour by a\n// step), domed rivet rows along every seam, hammered surface, rust streaks running down from\n// rivets, chipped paint showing bare metal on edges.\n// params: width 1.0 · height 0.5 · lap 0.003 · rivet 0.014 (radius) · pitch 0.09 · inset 0.05\n// rust 0.4 · chips 0.3\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport { Courses } from './courses.ts';\nimport { rustStreaks } from './masks.ts';\nimport { hash2 } from './noise.ts';\nimport type { StripRecipe } from './types.ts';\n\n/** Distance (m) from `q` to the nearest multiple of `pitch`. */\nfunction along(q: number, pitch: number): number {\n const t = q / pitch;\n return Math.abs(t - Math.round(t)) * pitch;\n}\n\nexport function paintPlates(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const lap = param(p, 'lap', 0.003);\n const rivet = param(p, 'rivet', 0.014);\n const pitch = param(p, 'pitch', 0.09);\n const inset = param(p, 'inset', 0.05);\n const chips = param(p, 'chips', 0.3);\n const metal = r.metalness ?? 0;\n const plates = new Courses(c, {\n course: param(p, 'height', 0.5),\n length: param(p, 'width', 1),\n irregular: 0,\n stagger: 0.5,\n seed,\n });\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const k = plates.at(ym);\n const dy = Math.min(ym - plates.y0, plates.y1 - ym);\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const ux = plates.ux[x] ?? 0;\n const dx = plates.dx[x] ?? 0;\n const id = plates.id[x] ?? 0;\n const hammer = noiseAt(c, xm, ym, 0.05, 0.05, seed + 3, 3);\n const fine = noiseAt(c, xm, ym, 0.004, 0.004, seed + 9, 2);\n // Lap: the plate sits `lap` proud of the one to its left; a tiny groove on every seam.\n const seam = Math.min(dx, dy);\n let h = lap * smooth(0, 0.004, ux) + 0.0004 * hammer - 0.001 * (1 - smooth(0, 0.0015, seam));\n // Rivet rows: `inset` from each vertical seam and from each course edge, every `pitch`.\n const ry = Math.abs(dy - inset);\n const rx = Math.abs(dx - inset);\n const d1 = Math.sqrt(rx * rx + along(ym - plates.y0, pitch) ** 2);\n const d2 = Math.sqrt(ry * ry + along(xm, pitch) ** 2);\n const d = Math.min(dx > inset * 2 ? 1 : d1, dy > inset * 2 ? 1 : d2);\n const dome = d < rivet ? Math.sqrt(1 - (d / rivet) ** 2) : 0;\n h += dome * rivet * 0.5;\n const chip = smooth(\n 0.35,\n 0.45,\n noiseAt(c, xm, ym, 0.03, 0.03, seed + 21, 4) - (seam * 6 + 0.2) + chips * 0.3,\n );\n c.height[i] = h - chip * 0.0003;\n c.tone[i] =\n (0.8 + 0.06 * hash2(k, id, seed)) * (1 + 0.06 * hammer + 0.03 * fine) * (1 + 0.15 * dome);\n c.rough[i] = r.roughness + 0.08 * fine - 0.25 * chip;\n c.metal[i] = metal + (1 - metal) * chip;\n }\n }\n rustStreaks(c, param(p, 'rust', 0.4), seed + 77);\n}\n",
38
+ "// Roof slate (kind 'slate'): overlapping courses — each visible slate rises from where it slides\n// under the course above to a thick, chipped lower edge that casts the shadow line — staggered\n// vertical gaps, riven (laminar) face, per-slate tone and tilt.\n// params: course 0.11 (exposure) · length 0.25 · gap 0.003 · thick 0.007 · variation 0.3\n\nimport { type Canvas, noiseAt, param, smooth } from './canvas.ts';\nimport { Courses } from './courses.ts';\nimport { hash2 } from './noise.ts';\nimport type { StripRecipe } from './types.ts';\n\nexport function paintSlate(c: Canvas, r: StripRecipe, seed: number): void {\n const p = r.params;\n const course = param(p, 'course', 0.11);\n const gap = param(p, 'gap', 0.003);\n const thick = param(p, 'thick', 0.007);\n const variation = param(p, 'variation', 0.3);\n const rows = new Courses(c, {\n course,\n length: param(p, 'length', 0.25),\n irregular: 0.15,\n stagger: 0.5,\n seed,\n });\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n const k = rows.at(ym);\n const span = rows.y1 - rows.y0;\n for (let x = 0; x < c.w; x++) {\n const i = y * c.w + x;\n const xm = (x + 0.5) * pu;\n const id = rows.id[x] ?? 0;\n const h = hash2(k, id, seed);\n const chip = (noiseAt(c, xm, ym, 0.015, 0.01, seed + 5, 3) + 0.3) * span * 0.08;\n const uy = Math.max(0, ym - rows.y0 - Math.max(0, chip));\n const t = uy / span;\n const lam = noiseAt(c, xm, ym, 0.12, 0.004, seed + 9, 3);\n const fine = noiseAt(c, xm, ym, 0.005, 0.005, seed + 13, 2);\n const sideGap = smooth(gap * 0.5, gap * 1.2, rows.dx[x] ?? 0);\n const bevel = smooth(0, 0.004, uy);\n const tilt = (hash2(id, k, seed + 1) - 0.5) * 0.002 * ((rows.ux[x] ?? 0) / 0.25);\n c.height[i] =\n (thick * (1 - t) * bevel + 0.0005 * lam + tilt) * sideGap - thick * (1 - sideGap);\n c.tone[i] =\n (0.62 - variation * 0.5 + variation * h) *\n (1 + 0.08 * lam + 0.04 * fine) *\n (0.55 + 0.45 * sideGap);\n c.rough[i] = r.roughness + 0.08 * lam + 0.05 * fine;\n }\n }\n}\n",
39
+ "// The simple kinds: 'noise' (a quiet painted/plain surface: soft tone and roughness mottling,\n// faint relief), 'flat' (constant) and 'glass' (near-white, very smooth, faint ripples, smudges,\n// grime toward the bottom edge).\n// params (noise): tone 0.93 · mottle 0.03 · relief 0.0002 · size 0.3\n// params (glass): ripple 0.0002 · smudge 0.08 · grime 0.4\n\nimport { type Canvas, noiseAt, param } from './canvas.ts';\nimport { grime } from './masks.ts';\nimport type { StripRecipe } from './types.ts';\n\nexport function paintFlat(c: Canvas, r: StripRecipe): void {\n c.tone.fill(param(r.params, 'tone', 1));\n c.rough.fill(r.roughness);\n c.metal.fill(r.metalness ?? 0);\n c.height.fill(0);\n}\n\nexport function paintNoise(c: Canvas, r: StripRecipe, seed: number): void {\n const tone = param(r.params, 'tone', 0.93);\n const mottle = param(r.params, 'mottle', 0.03);\n const relief = param(r.params, 'relief', 0.0002);\n const size = param(r.params, 'size', 0.3);\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n const metal = r.metalness ?? 0;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const big = noiseAt(c, xm, ym, size, size, seed, 4);\n const fine = noiseAt(c, xm, ym, 0.01, 0.01, seed + 1, 2);\n const i = y * c.w + x;\n c.tone[i] = tone + mottle * big;\n c.rough[i] = r.roughness + 0.06 * big + 0.03 * fine;\n c.metal[i] = metal;\n c.height[i] = relief * (big + 0.3 * fine);\n }\n }\n}\n\nexport function paintGlass(c: Canvas, r: StripRecipe, seed: number): void {\n const ripple = param(r.params, 'ripple', 0.0002);\n const smudge = param(r.params, 'smudge', 0.08);\n const pu = c.metresU / c.w;\n const pv = c.metresV / c.h;\n for (let y = 0; y < c.h; y++) {\n const ym = (y + 0.5) * pv;\n for (let x = 0; x < c.w; x++) {\n const xm = (x + 0.5) * pu;\n const wave = noiseAt(c, xm, ym, 0.15, 0.4, seed, 3);\n const smear = noiseAt(c, xm, ym, 0.08, 0.08, seed + 1, 4);\n const i = y * c.w + x;\n c.tone[i] = 0.92 + 0.02 * wave;\n c.rough[i] = r.roughness + smudge * Math.max(0, smear);\n c.metal[i] = 0;\n c.height[i] = ripple * wave;\n }\n }\n grime(c, param(r.params, 'grime', 0.4), seed + 9);\n}\n",
40
+ "// Dispatch a StripRecipe to its painter, then the shared grime pass (`params.grime`, 0..1), then\n// the recipe's own `paint` layer (project materials), checked for finite output. A `texture`\n// recipe paints from its cached CC0 image set instead of a kind (no grime: the photo has its own).\n\nimport { paintBond } from './bond.ts';\nimport type { Canvas } from './canvas.ts';\nimport { param } from './canvas.ts';\nimport { paintConcrete } from './concrete.ts';\nimport { paintLeather, paintWeave } from './fabric.ts';\nimport { paintImageStrip } from './image-strip.ts';\nimport { checkFinite, paintKit } from './kit.ts';\nimport { grime } from './masks.ts';\nimport { paintMetal } from './metal.ts';\nimport { paintPlanks } from './planks.ts';\nimport { paintPlates } from './plates.ts';\nimport { paintSlate } from './slate.ts';\nimport { paintFlat, paintGlass, paintNoise } from './surface.ts';\nimport type { StripKind, StripRecipe } from './types.ts';\n\ntype Painter = (c: Canvas, r: StripRecipe, seed: number) => void;\n\nconst PAINTERS: Readonly<Record<StripKind, Painter>> = {\n bond: paintBond,\n planks: paintPlanks,\n plates: paintPlates,\n slate: paintSlate,\n concrete: paintConcrete,\n metal: paintMetal,\n weave: paintWeave,\n leather: paintLeather,\n noise: paintNoise,\n glass: paintGlass,\n flat: (c, r) => paintFlat(c, r),\n};\n\nexport function paintStrip(c: Canvas, r: StripRecipe, seed: number, where = 'strip'): void {\n if (r.texture) paintImageStrip(c, r, r.texture, where);\n else {\n if (r.albedo || r.albedo2)\n c.colours = [r.albedo ?? [1, 1, 1], r.albedo2 ?? r.albedo ?? [1, 1, 1]];\n PAINTERS[r.kind](c, r, seed);\n if (r.kind !== 'glass' && r.kind !== 'flat') grime(c, param(r.params, 'grime', 0), seed + 101);\n }\n if (r.paint) {\n r.paint(c, paintKit(c, seed + 211));\n checkFinite(c, where);\n }\n}\n",
41
+ "// Paint one cell: a stamped image, a foliage card (its own painter; the recipe's roughness scales\n// the leaves), or a decal motif over a backdrop of the recipe's kind.\n\nimport { type CellId, isFoliage } from '../trim-sheet.ts';\nimport type { Canvas } from './canvas.ts';\nimport { paintDoorPanel, paintSign, paintWindowSash } from './cells.ts';\nimport { paintClock, paintPorthole, paintSmokebox } from './cells-round.ts';\nimport { FOLIAGE_PAINTERS } from './foliage.ts';\nimport { stampImage } from './stamp.ts';\nimport { paintStrip } from './strip.ts';\nimport type { CellImage, StripRecipe } from './types.ts';\n\ntype Motif = (c: Canvas, r: StripRecipe, seed: number) => void;\nconst MOTIFS: Readonly<Record<string, Motif>> = {\n window_sash: paintWindowSash,\n door_panel: paintDoorPanel,\n clock: paintClock,\n smokebox: paintSmokebox,\n sign: paintSign,\n porthole: paintPorthole,\n};\n\n/** Roughness the foliage painter assumes; a recipe's own roughness rescales it. */\nconst LEAF_ROUGHNESS = 0.6;\n\nexport function paintCell(c: Canvas, id: CellId, entry: StripRecipe | CellImage, seed: number) {\n if ('image' in entry) {\n stampImage(c, entry.image);\n return;\n }\n if (isFoliage(id)) {\n FOLIAGE_PAINTERS[id](c, seed);\n const k = entry.roughness / LEAF_ROUGHNESS;\n for (let i = 0; i < c.rough.length; i++) c.rough[i] = Math.min(1, (c.rough[i] ?? 0.6) * k);\n return;\n }\n paintStrip(c, entry, seed);\n MOTIFS[id]?.(c, entry, seed + 1);\n}\n",
42
+ "// Normal from height: a Sobel gradient of the canvas height (metres) over its texel size (metres),\n// so relief reads at true scale. glTF tangent space, +Y = toward decreasing V (OpenGL \"green up\").\n// Wraps along U for strips, clamps for cells and along V.\n\nimport type { Canvas } from './canvas.ts';\n\n/** Neighbour column indices, precomputed so the hot loop does no modulo. */\nexport function neighbours(n: number, wrap: boolean): { lo: Int32Array; hi: Int32Array } {\n const lo = new Int32Array(n);\n const hi = new Int32Array(n);\n for (let i = 0; i < n; i++) {\n lo[i] = i > 0 ? i - 1 : wrap ? n - 1 : 0;\n hi[i] = i < n - 1 ? i + 1 : wrap ? 0 : n - 1;\n }\n return { lo, hi };\n}\n\n/** RGBA8 tangent-space normals for the canvas; `strength` scales the slope. */\nexport function sobelNormals(c: Canvas, strength = 1): Uint8Array {\n const { w, h, height } = c;\n const out = new Uint8Array(w * h * 4);\n const cx = neighbours(w, c.wrapU);\n const cy = neighbours(h, false);\n const sx = strength / (8 * (c.metresU / w));\n const sy = strength / (8 * (c.metresV / h));\n for (let y = 0; y < h; y++) {\n const r0 = (cy.lo[y] ?? 0) * w;\n const r1 = y * w;\n const r2 = (cy.hi[y] ?? 0) * w;\n for (let x = 0; x < w; x++) {\n const xl = cx.lo[x] ?? 0;\n const xr = cx.hi[x] ?? 0;\n const tl = height[r0 + xl] ?? 0;\n const tc = height[r0 + x] ?? 0;\n const tr = height[r0 + xr] ?? 0;\n const ml = height[r1 + xl] ?? 0;\n const mr = height[r1 + xr] ?? 0;\n const bl = height[r2 + xl] ?? 0;\n const bc = height[r2 + x] ?? 0;\n const br = height[r2 + xr] ?? 0;\n const gx = (tr + 2 * mr + br - tl - 2 * ml - bl) * sx;\n const gy = (bl + 2 * bc + br - tl - 2 * tc - tr) * sy;\n const inv = 1 / Math.sqrt(gx * gx + gy * gy + 1);\n const o = (r1 + x) * 4;\n out[o] = Math.round((-gx * inv * 0.5 + 0.5) * 255);\n out[o + 1] = Math.round((gy * inv * 0.5 + 0.5) * 255);\n out[o + 2] = Math.round((inv * 0.5 + 0.5) * 255);\n out[o + 3] = 255;\n }\n }\n return out;\n}\n",
43
+ "// Finish a region canvas (AO, normal, ORM, albedo) and blit it into the sheet. Edge texels are\n// replicated `pad` deep (rows for strips, rows + columns for cells) so the first mip levels never\n// sample a neighbouring region.\n\nimport type { Canvas } from './canvas.ts';\nimport { sobelNormals } from './normal.ts';\nimport { cavityOcclusion, packAlbedo, packOrm } from './orm.ts';\nimport type { PaintedSheet } from './types.ts';\n\n/** An empty sheet: white albedo (vertex colour reads true), flat normal, AO 1, rough 0.8. */\nexport function blankSheet(size: number): PaintedSheet {\n const n = size * size * 4;\n const albedo = new Uint8Array(n).fill(255);\n const normal = new Uint8Array(n);\n const orm = new Uint8Array(n);\n const flat = new Uint8Array([128, 128, 255, 255]);\n const base = new Uint8Array([255, 204, 0, 255]);\n for (let i = 0; i < n; i += 4) {\n normal.set(flat, i);\n orm.set(base, i);\n }\n return { size, albedo, normal, orm };\n}\n\nexport function composeRegion(\n sheet: PaintedSheet,\n c: Canvas,\n x0: number,\n y0: number,\n pad: number,\n): void {\n const ao = cavityOcclusion(c);\n const maps = [\n [sheet.albedo, packAlbedo(c, ao)],\n [sheet.normal, c.normalRgba ?? sobelNormals(c)],\n [sheet.orm, packOrm(c, ao)],\n ] as const;\n const padX = c.wrapU ? 0 : pad;\n for (let y = 0; y < c.h; y++) {\n const sy = Math.min(c.h - 1 - pad, Math.max(pad, y));\n const dst = ((y0 + y) * sheet.size + x0) * 4;\n const src = sy * c.w;\n const l = (src + padX) * 4;\n const r = (src + c.w - 1 - padX) * 4;\n for (const [to, from] of maps) {\n to.set(from.subarray(l, r + 4), dst + padX * 4);\n for (let x = 0; x < padX; x++) {\n to.set(from.subarray(l, l + 4), dst + x * 4);\n to.set(from.subarray(r, r + 4), dst + (c.w - 1 - x) * 4);\n }\n }\n }\n}\n",
44
+ "// Recipe validation: every bad input throws T3D_RECIPE_INVALID with the fix, before any painting.\n\nimport { Ts23dError } from '../../core/index.ts';\nimport { CELLS, STRIPS, stripRow } from '../trim-sheet.ts';\nimport type { CellImage, SheetRecipe, StripKind, StripRecipe } from './types.ts';\n\nconst KINDS: readonly StripKind[] = [\n 'bond',\n 'planks',\n 'plates',\n 'noise',\n 'flat',\n 'slate',\n 'concrete',\n 'glass',\n 'metal',\n 'weave',\n 'leather',\n];\nconst SIZES = [512, 1024, 2048];\n\nfunction fail(cause: string, fix: string): never {\n throw new Ts23dError('T3D_RECIPE_INVALID', { cause: `sheet recipe: ${cause}`, fix });\n}\n\nconst unit = (v: number): boolean => Number.isFinite(v) && v >= 0 && v <= 1;\n\nexport function validateStrip(where: string, r: StripRecipe): void {\n if (!KINDS.includes(r.kind))\n fail(`${where}.kind '${r.kind}' is unknown`, `use one of ${KINDS.join(' | ')}`);\n if (!(Number.isFinite(r.scaleMetres) && r.scaleMetres > 0))\n fail(\n `${where}.scaleMetres is ${r.scaleMetres}`,\n 'set the metres the strip V span represents, > 0 (e.g. 0.6 for brick)',\n );\n if (!unit(r.roughness)) fail(`${where}.roughness is ${r.roughness}`, 'roughness is 0..1');\n if (r.metalness !== undefined && !unit(r.metalness))\n fail(`${where}.metalness is ${r.metalness}`, 'metalness is 0..1');\n for (const key of ['albedo', 'albedo2'] as const) {\n const a = r[key];\n if (a !== undefined && !(a.length === 3 && a.every(unit)))\n fail(\n `${where}.${key} is [${a}]`,\n `${key} is linear RGB, three numbers 0..1 (use hex('#rrggbb'))`,\n );\n }\n if (r.paint !== undefined && typeof r.paint !== 'function')\n fail(`${where}.paint is not a function`, 'paint is (surface, kit) => void');\n for (const [k, v] of Object.entries(r.params ?? {}))\n if (!Number.isFinite(v)) fail(`${where}.params.${k} is ${v}`, 'params are finite numbers');\n}\n\nexport function validateSheet(recipe: SheetRecipe): void {\n if (!Number.isInteger(recipe.seed)) fail(`seed ${recipe.seed}`, 'seed is an integer');\n if (recipe.size !== undefined && !SIZES.includes(recipe.size))\n fail(`size ${recipe.size}`, 'size is 512, 1024 or 2048');\n for (const [id, r] of Object.entries(recipe.strips)) {\n if (stripRow(id) < 0)\n fail(\n `strip '${id}' is not in the layout`,\n `strips are ${STRIPS.join(', ')} or a defineMaterial() id`,\n );\n if (r) validateStrip(`strips.${id}`, r);\n }\n for (const [id, e] of Object.entries(recipe.cells ?? {})) {\n if (!(CELLS as readonly string[]).includes(id))\n fail(`cell '${id}' is not in the layout`, `cells are ${CELLS.join(', ')}`);\n if (!e) continue;\n if ('image' in e) {\n if (!((e as CellImage).image instanceof Uint8Array))\n fail(`cells.${id}.image is not bytes`, 'pass PNG file bytes as a Uint8Array');\n } else validateStrip(`cells.${id}`, e);\n }\n}\n",
45
+ "// Procedural material generator: paints the shared trim sheet (albedo, normal, ORM) from code —\n// brick bonds, plank grain (oak, pine, weathered, painted), riveted plates, bare/cast/painted/\n// galvanised metal, canvas, leather, slate, concrete, glass, decal cells and cutout foliage cards\n// — at a fixed seed, so the texture is as deterministic as the meshes. Supplied PNGs (reference\n// photos, kubeez.com generations) can stamp cells; they are inputs, never the only path.\n//\n// Conventions: V (image row) grows with world up, as box/planar map faces; strips tile seamlessly\n// along U and span `stripRect().metres` there and `scaleMetres` along V; classic strips are\n// near-greyscale sRGB (vertex colour tints them); library/defined material strips, foliage and\n// stamped cells carry colour. Project strips (`defineMaterial`) paint after the built-ins.\n\nimport { createRng } from '../core/index.ts';\nimport { createCanvas } from './paint/canvas.ts';\nimport { paintCell } from './paint/cell.ts';\nimport { blankSheet, composeRegion } from './paint/compose.ts';\nimport { DEFAULT_SHEET } from './paint/default-sheet.ts';\nimport { paintStrip } from './paint/strip.ts';\nimport type { PaintedSheet, SheetRecipe } from './paint/types.ts';\nimport { validateSheet, validateStrip } from './paint/validate.ts';\nimport { customIds } from './slots.ts';\nimport { CELLS, cellRect, STRIPS, type StripId, stripRect } from './trim-sheet.ts';\n\nexport { DEFAULT_SHEET } from './paint/default-sheet.ts';\nexport type {\n CellImage,\n MaterialPainter,\n MaterialSurface,\n PaintedSheet,\n PaintKit,\n SheetRecipe,\n StripKind,\n StripRecipe,\n} from './paint/types.ts';\n\nconst FALLBACK = { kind: 'noise', scaleMetres: 1, roughness: 0.6 } as const;\n\nexport function paintTrimSheet(recipe: SheetRecipe = DEFAULT_SHEET): PaintedSheet {\n validateSheet(recipe);\n const size = recipe.size ?? 2048;\n const sheet = blankSheet(size);\n const rng = createRng(recipe.seed);\n const seedOf = (name: string): number => rng.fork(name).int(0, 0x7fffffff);\n const pad = Math.max(2, size / 256);\n const all = [...STRIPS, ...(customIds() as readonly StripId[])];\n for (const id of all) {\n const r = recipe.strips[id] ?? DEFAULT_SHEET.strips[id] ?? FALLBACK;\n validateStrip(`strips.${id}`, r);\n const rect = stripRect(id);\n const h = Math.round((rect.v1 - rect.v0) * size);\n const c = createCanvas(size, h, rect.metres, r.scaleMetres, true);\n paintStrip(c, r, seedOf(id), `strips.${id}`);\n composeRegion(sheet, c, 0, Math.round(rect.v0 * size), pad);\n }\n for (const id of CELLS) {\n const e = recipe.cells?.[id] ?? DEFAULT_SHEET.cells?.[id] ?? FALLBACK;\n const rect = cellRect(id);\n const w = Math.round((rect.u1 - rect.u0) * size);\n const c = createCanvas(w, w, rect.metres, rect.metres, false);\n paintCell(c, id, e, seedOf(id));\n composeRegion(sheet, c, Math.round(rect.u0 * size), Math.round(rect.v0 * size), pad);\n }\n return sheet;\n}\n",
46
+ "// The Godot 4 emitter behind `godotShaderSource`: prints a spatial .gdshader with the same uniforms\n// as the three.js module. Values come pre-validated from shader.ts.\n\nimport type { ShaderParams } from './shader.ts';\nimport type { UvRect } from './trim-sheet.ts';\n\nconst f = (n: number): string => (Number.isInteger(n) ? `${n}.0` : `${+n.toFixed(6)}`);\nconst rect = (r: UvRect): string =>\n `in_rect(UV, vec4(${f(r.u0)}, ${f(r.v0)}, ${f(r.u1)}, ${f(r.v1)}))`;\n\nexport function godotSource(p: ShaderParams): string {\n const modes = ['blend_mix', 'depth_draw_opaque', p.cutout ? 'cull_disabled' : 'cull_back'];\n const weight = p.windAttribute\n ? 'CUSTOM0.x /* import _WIND into CUSTOM0 (glTF import: custom attribute mapping) */'\n : 'smoothstep(0.0, wind_height, VERTEX.z)';\n return `// Generated by @developerz.ai/ts23d godotShaderSource(). A starting point your project owns:\n// assign it to a ShaderMaterial and set albedo_tex / normal_tex / orm_tex from the GLB's\n// ts23d_* material (or the shared trim_sheet_{albedo,normal,orm}.png). Godot 4.x.\nshader_type spatial;\nrender_mode ${modes.join(', ')};\n\nuniform sampler2D albedo_tex : source_color, filter_linear_mipmap, repeat_enable;\nuniform sampler2D normal_tex : hint_normal, filter_linear_mipmap, repeat_enable;\nuniform sampler2D orm_tex : hint_default_white, filter_linear_mipmap, repeat_enable;\n\nuniform float night : hint_range(0.0, 1.0) = 0.0;\nuniform float wind_strength = ${f(p.windStrength)};\nuniform float wind_height = ${f(p.windHeight)};\nuniform float wind_hz = ${f(p.windHz)};\nuniform vec3 glow_color : source_color = vec3(${f(p.glow[0])}, ${f(p.glow[1])}, ${f(p.glow[2])});\nuniform float glow_ratio : hint_range(0.0, 1.0) = ${f(p.glowRatio)};\nuniform float glow_intensity = ${f(p.glowIntensity)};\nuniform float wear : hint_range(0.0, 1.0) = ${f(p.wear)};\nuniform float grime_height = ${f(p.grimeHeight)};\n\nvarying vec3 world_pos;\n\nfloat in_rect(vec2 uv, vec4 r) {\n\tfloat u = fract(uv.x);\n\treturn step(r.x, u) * step(u, r.z) * step(r.y, uv.y) * step(uv.y, r.w);\n}\n\nfloat hash13(vec3 p) {\n\tp = fract(p * 0.1031);\n\tp += dot(p, p.zyx + 31.32);\n\treturn fract((p.x + p.y) * p.z);\n}\n\nvoid vertex() {\n\t// Wind sway: mesh-local Z is the authored up axis; sway in local XY.\n\tfloat weight = ${weight};\n\tfloat phase = VERTEX.x * 0.7 + VERTEX.y * 0.45;\n\tfloat sway = sin(TIME * wind_hz * 6.2832 + phase) * wind_strength * weight * 0.1;\n\tVERTEX.xy += vec2(sway, sway * 0.6);\n\tworld_pos = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;\n}\n\nvoid fragment() {\n\tvec4 base = texture(albedo_tex, UV);\n\tvec3 orm = texture(orm_tex, UV).rgb;\n\tfloat ground = 1.0 - smoothstep(0.0, grime_height, world_pos.y);\n\tfloat grime = clamp(wear * max((1.0 - orm.r) * 1.5, ground), 0.0, 1.0);\n\tALBEDO = base.rgb * COLOR.rgb * (1.0 - grime * 0.45);\n\tAO = orm.r;\n\tROUGHNESS = clamp(orm.g + grime * 0.2, 0.0, 1.0);\n\tMETALLIC = orm.b * (1.0 - grime);\n\tNORMAL_MAP = texture(normal_tex, UV).rgb;\n${p.cutout ? '\\tALPHA = base.a;\\n\\tALPHA_SCISSOR_THRESHOLD = 0.5;\\n' : p.blend ? '\\tALPHA = base.a * 0.6;\\n' : ''}\n\t// Window glow: dark panes in window cells, or the glass strip; 1.5 m world slots, glow_ratio lit.\n\tfloat luma = dot(base.rgb, vec3(0.2126, 0.7152, 0.0722));\n\tfloat panes = (${p.glowRects.map(rect).join(' + ')}) * step(luma, 0.3);\n\tfloat mask = max(panes, ${rect(p.glassRect)});\n\tfloat lit = step(hash13(floor(world_pos / 1.5)), glow_ratio);\n\tEMISSION = glow_color * mask * lit * night * glow_intensity;\n}\n`;\n}\n",
47
+ "// The three.js TSL emitter behind `threeMaterialSource`: prints a self-contained TypeScript module\n// for three r18x (`three/webgpu` + `three/tsl`). Values come pre-validated from shader.ts.\n\nimport type { ShaderParams } from './shader.ts';\nimport type { UvRect } from './trim-sheet.ts';\n\nconst f = (n: number): string => (Number.isInteger(n) ? `${n}.0` : `${+n.toFixed(6)}`);\n\nconst rectNode = (r: UvRect): string => `inRect(${f(r.u0)}, ${f(r.v0)}, ${f(r.u1)}, ${f(r.v1)})`;\n\nexport function threeSource(p: ShaderParams): string {\n const weight = p.windAttribute\n ? \"attribute('_wind', 'float')\"\n : 'smoothstep(float(0), uWindHeight, positionLocal.z)';\n const glowCells = p.glowRects.map(rectNode).join('.add(') + ')'.repeat(p.glowRects.length - 1);\n return `// Generated by @developerz.ai/ts23d threeMaterialSource(). A starting point your project owns:\n// edit freely. Needs three r18x (WebGPURenderer + TSL). ts23d itself has no three dependency.\n//\n// Usage: const gltf = await loader.loadAsync('tank.glb'); upgradeTrimMaterials(gltf.scene);\n// trim.uniforms.night.value = 1; // at dusk\n\nimport { DoubleSide, type Material, type Mesh, MeshStandardMaterial, MeshStandardNodeMaterial, type Object3D, type Texture } from 'three/webgpu';\nimport { attribute, color, float, floor, fract, hash, max, normalMap, positionLocal, positionWorld, sin, smoothstep, step, texture, time, uniform, uv, vec3, vertexColor } from 'three/tsl';\n\nexport interface TrimMaps {\n readonly albedo: Texture;\n readonly normal: Texture | null;\n readonly orm: Texture | null;\n}\n\n/** Shared uniforms: one set drives every trim material, so a scene-wide night switch is one write. */\nexport const uniforms = {\n night: uniform(0),\n windStrength: uniform(${f(p.windStrength)}),\n windHeight: uniform(${f(p.windHeight)}),\n windHz: uniform(${f(p.windHz)}),\n glowColor: uniform(color(${f(p.glow[0])}, ${f(p.glow[1])}, ${f(p.glow[2])})),\n glowRatio: uniform(${f(p.glowRatio)}),\n glowIntensity: uniform(${f(p.glowIntensity)}),\n wear: uniform(${f(p.wear)}),\n grimeHeight: uniform(${f(p.grimeHeight)}),\n};\n\n/** 1 inside a trim-sheet UV rect (U wraps: strips tile along U). */\nfunction inRect(u0: number, v0: number, u1: number, v1: number) {\n const t = uv();\n const u = fract(t.x);\n return step(u0, u).mul(step(u, u1)).mul(step(v0, t.y)).mul(step(t.y, v1));\n}\n\nexport function createTrimMaterial(maps: TrimMaps, cutout = ${p.cutout}): MeshStandardNodeMaterial {\n const { night, windStrength: uWindStrength, windHeight: uWindHeight, windHz, glowColor, glowRatio, glowIntensity, wear, grimeHeight } = uniforms;\n const m = new MeshStandardNodeMaterial();\n const base = texture(maps.albedo, uv());\n const orm = maps.orm ? texture(maps.orm, uv()) : vec3(1, 0.8, 0);\n const tint = vertexColor();\n\n // Wear / grime: cavities (low AO) and the first metres above the ground get darker and rougher.\n const ground = float(1).sub(smoothstep(float(0), grimeHeight, positionWorld.y));\n const grime = wear.mul(max(float(1).sub(orm.x).mul(1.5), ground)).clamp(0, 1);\n m.colorNode = base.rgb.mul(tint.rgb).mul(float(1).sub(grime.mul(0.45)));\n m.roughnessNode = orm.y.add(grime.mul(0.2)).clamp(0, 1);\n m.metalnessNode = orm.z.mul(float(1).sub(grime));\n m.aoNode = orm.x;\n if (maps.normal) m.normalNode = normalMap(texture(maps.normal, uv()));\n if (cutout) {\n m.opacityNode = base.a;\n m.alphaTest = 0.5;\n m.side = DoubleSide;\n }\n\n // Wind sway (authored Z-up, so sway in local XY), phase-shifted across the crown.\n const windWeight = ${weight};\n const phase = positionLocal.x.mul(0.7).add(positionLocal.y.mul(0.45));\n const sway = sin(time.mul(windHz).mul(6.2832).add(phase)).mul(uWindStrength).mul(windWeight).mul(0.1);\n m.positionNode = positionLocal.add(vec3(sway, sway.mul(0.6), 0));\n\n // Window glow: dark pane texels in window cells, or the glass strip; a world-space hash lights\n // \\`glowRatio\\` of the 1.5 m window slots; scaled by \\`night\\`.\n const luma = base.r.mul(0.2126).add(base.g.mul(0.7152)).add(base.b.mul(0.0722));\n const panes = ${glowCells}.mul(step(luma, 0.3));\n const mask = max(panes, ${rectNode(p.glassRect)});\n const slot = floor(positionWorld.div(1.5));\n const lit = step(hash(slot.x.mul(73).add(slot.y.mul(157)).add(slot.z.mul(311))), glowRatio);\n m.emissiveNode = glowColor.mul(mask).mul(lit).mul(night).mul(glowIntensity);\n return m;\n}\n\n/** Replace every ts23d_* material under \\`root\\` with the node material, reusing the GLB's maps. */\nexport function upgradeTrimMaterials(root: Object3D): void {\n const cache = new Map<Material, MeshStandardNodeMaterial>();\n root.traverse((o) => {\n const mesh = o as Mesh;\n const old = mesh.isMesh ? mesh.material : null;\n if (!(old instanceof MeshStandardMaterial) || !old.name.startsWith('ts23d') || !old.map) return;\n const next = cache.get(old) ?? createTrimMaterial({ albedo: old.map, normal: old.normalMap, orm: old.roughnessMap }, old.alphaTest > 0);\n next.name = old.name;\n cache.set(old, next);\n mesh.material = next;\n });\n}\n`;\n}\n",
48
+ "// Engine shader sources for the trim-sheet material: per-asset effects that stay on the one shared\n// material — vertex-colour tint, wind sway, night window glow, wear/grime. Both functions return\n// plain source strings (a three.js TSL module, a Godot 4 .gdshader). They are STARTING POINTS an\n// engine project loads and owns, not runtime dependencies: ts23d never imports three or Godot.\n//\n// Shared conventions both sources implement:\n// tint albedo.rgb × COLOR_0.rgb (linear), alpha from albedo.a (cutout leaf masks)\n// ORM R occlusion · G roughness · B metalness (one texture, as the GLB binds it)\n// wind weight from the `_WIND` vertex attribute (three: `_wind`) or, by default, the\n// mesh-local height (authored Z-up), smoothstep(0, wind.height, z); sway in local XY\n// glow emissive on window panes: window_sash/porthole texels darker than luma 0.3, and the\n// whole glass strip; a world-space 1.5 m hash lights `ratio` of windows; × `night`\n// wear darkens + roughens cavities (1 − AO) and the first `grimeHeight` metres of world height\n\nimport type { Surface } from '../core/index.ts';\nimport { Ts23dError } from '../core/index.ts';\nimport { godotSource } from './shader-godot.ts';\nimport { threeSource } from './shader-three.ts';\nimport { cellRect, stripRect, type UvRect } from './trim-sheet.ts';\n\nexport interface ShaderHints {\n /** Vertex sway for vegetation. Weight from the `_WIND` attribute or mesh-local height. */\n readonly wind?: {\n readonly strength: number;\n readonly source?: 'attribute' | 'height';\n /** Metres of height at which sway reaches full weight (height source). Default 4. */\n readonly height?: number;\n readonly hz?: number;\n };\n /** Emissive mask on window cells at night: `ratio` of windows lit. */\n readonly windowGlow?: {\n readonly color: string;\n readonly ratio: number;\n readonly intensity?: number;\n };\n /** Wear/grime mask strength 0..1 and how high ground grime climbs (metres). */\n readonly wear?: { readonly amount: number; readonly grimeHeight?: number };\n /** The surface the material is for: 'cutout' adds alpha test + double-sided. */\n readonly surface?: Surface;\n}\n\n/** Resolved, validated numbers both emitters print. */\nexport interface ShaderParams {\n readonly windStrength: number;\n readonly windAttribute: boolean;\n readonly windHeight: number;\n readonly windHz: number;\n readonly glow: readonly [number, number, number];\n readonly glowRatio: number;\n readonly glowIntensity: number;\n readonly wear: number;\n readonly grimeHeight: number;\n readonly cutout: boolean;\n readonly blend: boolean;\n readonly glowRects: readonly UvRect[];\n readonly glassRect: UvRect;\n}\n\nfunction fail(cause: string, fix: string): never {\n throw new Ts23dError('T3D_RECIPE_INVALID', { cause: `shader hints: ${cause}`, fix });\n}\n\nfunction srgbHex(value: string): [number, number, number] {\n if (!/^#[0-9a-fA-F]{6}$/.test(value)) fail(`colour '${value}'`, \"use '#rrggbb' sRGB hex\");\n const n = Number.parseInt(value.slice(1), 16);\n return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];\n}\n\nexport function resolveHints(h: ShaderHints): ShaderParams {\n const unit = (v: number, what: string): number =>\n Number.isFinite(v) && v >= 0 && v <= 1 ? v : fail(`${what} is ${v}`, `${what} is 0..1`);\n const pos = (v: number, what: string): number =>\n Number.isFinite(v) && v > 0 ? v : fail(`${what} is ${v}`, `${what} is a positive number`);\n const strength = h.wind ? pos(h.wind.strength, 'wind.strength') : 0;\n return {\n windStrength: strength,\n windAttribute: h.wind?.source === 'attribute',\n windHeight: pos(h.wind?.height ?? 4, 'wind.height'),\n windHz: pos(h.wind?.hz ?? 0.4, 'wind.hz'),\n glow: h.windowGlow ? srgbHex(h.windowGlow.color) : [1, 0.75, 0.4],\n glowRatio: h.windowGlow ? unit(h.windowGlow.ratio, 'windowGlow.ratio') : 0,\n glowIntensity: pos(h.windowGlow?.intensity ?? 2, 'windowGlow.intensity'),\n wear: h.wear ? unit(h.wear.amount, 'wear.amount') : 0,\n grimeHeight: pos(h.wear?.grimeHeight ?? 0.6, 'wear.grimeHeight'),\n cutout: h.surface === 'cutout',\n blend: h.surface === 'glass' || h.surface === 'translucent',\n glowRects: [cellRect('window_sash'), cellRect('porthole')],\n glassRect: stripRect('glass'),\n };\n}\n\n/** A three.js (r18x, WebGPU/TSL) TypeScript module: `createTrimMaterial(maps)` + `upgradeTrimMaterials(root)`. */\nexport function threeMaterialSource(hints: ShaderHints = {}): string {\n return threeSource(resolveHints(hints));\n}\n\n/** A Godot 4 spatial shader (.gdshader) with the same features and uniform names. */\nexport function godotShaderSource(hints: ShaderHints = {}): string {\n return godotSource(resolveHints(hints));\n}\n"
49
+ ],
50
+ "mappings": "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",
51
+ "debugId": "06EA6C9948471A9664756E2164756E21",
52
+ "names": []
53
+ }