@call-me-sensei/toonlab 0.2.0 → 0.3.1

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 (205) hide show
  1. package/AGENTS.md +127 -4
  2. package/ATTRIBUTION.md +41 -3
  3. package/README.md +231 -34
  4. package/docs/characters.md +144 -0
  5. package/docs/debug-panel.md +126 -0
  6. package/docs/docs.css +589 -0
  7. package/docs/environment.md +186 -0
  8. package/docs/getting-started.md +180 -0
  9. package/docs/index.html +14 -0
  10. package/docs/lab-architecture.md +100 -0
  11. package/docs/lighting.md +825 -0
  12. package/docs/main.jsx +752 -0
  13. package/docs/mcp.md +97 -0
  14. package/docs/post-processing.md +98 -0
  15. package/docs/settings-reference.md +1878 -0
  16. package/docs/shader-constants.md +77 -0
  17. package/docs/sky.md +182 -0
  18. package/docs/style-labs.md +309 -0
  19. package/docs/texture-lab.md +135 -0
  20. package/docs/toon-shading.md +183 -0
  21. package/docs/tsl-conventions.md +167 -0
  22. package/docs/vegetation-sky.md +275 -0
  23. package/docs/water.md +430 -0
  24. package/docs/weather.md +200 -0
  25. package/docs/world-scale.md +111 -0
  26. package/mcp/server.mjs +610 -0
  27. package/mcp/style-lab-tools.mjs +371 -0
  28. package/mcp/vite-plugin.mjs +174 -0
  29. package/mcp/workspace.mjs +397 -0
  30. package/package.json +64 -5
  31. package/src/ambientfx/INTEGRATION.md +164 -0
  32. package/src/ambientfx/ambientFxPresets.js +83 -0
  33. package/src/ambientfx/ambientFxSettings.js +368 -0
  34. package/src/ambientfx/emitters.js +169 -0
  35. package/src/ambientfx/index.js +5 -0
  36. package/src/ambientfx/particleBackbone.js +493 -0
  37. package/src/ambientfx/stylizedAmbientFx.js +450 -0
  38. package/src/assetlib/ambientcg.js +117 -0
  39. package/src/assetlib/assetRef.js +91 -0
  40. package/src/assetlib/importedEntry.js +40 -0
  41. package/src/assetlib/index.js +23 -0
  42. package/src/assetlib/kaykit.js +192 -0
  43. package/src/assetlib/kaykitStaticIndex.js +700 -0
  44. package/src/assetlib/loadImported.js +143 -0
  45. package/src/assetlib/opensource3d.js +113 -0
  46. package/src/assetlib/polyhaven.js +182 -0
  47. package/src/assetlib/polypizza.js +115 -0
  48. package/src/assetlib/smithsonian.js +214 -0
  49. package/src/assetlib/sources.js +279 -0
  50. package/src/assetlib/zip.js +58 -0
  51. package/src/biome/biomeGenerator.js +385 -0
  52. package/src/biome/biomeRuntime.js +299 -0
  53. package/src/biome/index.js +2 -0
  54. package/src/buildinggen/buildingAsset.js +44 -0
  55. package/src/buildinggen/buildingGrammar.js +311 -0
  56. package/src/buildinggen/buildingMesh.js +451 -0
  57. package/src/buildinggen/buildingPresets.js +46 -0
  58. package/src/buildinggen/buildingRecipe.js +100 -0
  59. package/src/buildinggen/buildingSettings.js +238 -0
  60. package/src/buildinggen/index.js +6 -0
  61. package/src/camera/cameraDirector.js +157 -0
  62. package/src/camera/cameraGenerator.js +367 -0
  63. package/src/camera/cameraRig.js +570 -0
  64. package/src/camera/cameraSettings.js +236 -0
  65. package/src/camera/index.js +7 -0
  66. package/src/catalog/builtinEntries.js +245 -0
  67. package/src/catalog/catalog.js +210 -0
  68. package/src/catalog/index.js +3 -0
  69. package/src/catalog/manifest.js +84 -0
  70. package/src/core/generation.js +529 -0
  71. package/src/environment/environmentRigs.js +21 -1
  72. package/src/environment/environmentSettings.js +4 -0
  73. package/src/environment/environmentSunShadowPass.js +8 -0
  74. package/src/fauna/INTEGRATION.md +174 -0
  75. package/src/fauna/boids.js +861 -0
  76. package/src/fauna/faunaBodies.js +492 -0
  77. package/src/fauna/faunaPresets.js +52 -0
  78. package/src/fauna/faunaSettings.js +525 -0
  79. package/src/fauna/index.js +5 -0
  80. package/src/fauna/stylizedFauna.js +395 -0
  81. package/src/game-feel/gameFeelGenerator.js +402 -0
  82. package/src/game-feel/gameFeelRuntime.js +549 -0
  83. package/src/game-feel/index.js +2 -0
  84. package/src/index.js +17 -6
  85. package/src/lighting/colorIntensity.js +177 -0
  86. package/src/lighting/index.js +161 -0
  87. package/src/lighting/lightDescriptors.js +249 -0
  88. package/src/lighting/lightingCapabilities.js +79 -0
  89. package/src/lighting/lightingDocuments.js +247 -0
  90. package/src/lighting/lightingFixtures.js +446 -0
  91. package/src/lighting/lightingGenerator.js +449 -0
  92. package/src/lighting/lightingPresets.js +319 -0
  93. package/src/lighting/lightingRuntime.js +723 -0
  94. package/src/lighting/lightingStyle.js +386 -0
  95. package/src/lighting/lightingSystem.js +774 -0
  96. package/src/lighting/unrealExport.js +186 -0
  97. package/src/lighting/utils.js +87 -0
  98. package/src/motion/index.js +5 -0
  99. package/src/motion/motionClip.js +441 -0
  100. package/src/motion/motionController.js +628 -0
  101. package/src/motion/motionDocuments.js +225 -0
  102. package/src/motion/motionGraph.js +307 -0
  103. package/src/motion/motionSettings.js +222 -0
  104. package/src/pathgen/index.js +7 -0
  105. package/src/pathgen/pathBridge.js +232 -0
  106. package/src/pathgen/pathPresets.js +35 -0
  107. package/src/pathgen/pathRibbon.js +410 -0
  108. package/src/pathgen/pathRouter.js +380 -0
  109. package/src/pathgen/pathSettings.js +335 -0
  110. package/src/pathgen/pathTextures.js +123 -0
  111. package/src/pathgen/stylizedPaths.js +453 -0
  112. package/src/post/index.js +1 -0
  113. package/src/post/postGenerator.js +177 -0
  114. package/src/post/postProcessing.js +41 -0
  115. package/src/propgen/generatorsWave1.js +379 -0
  116. package/src/propgen/generatorsWave2.js +462 -0
  117. package/src/propgen/index.js +5 -0
  118. package/src/propgen/propAsset.js +323 -0
  119. package/src/propgen/propParts.js +170 -0
  120. package/src/propgen/propPlacement.js +459 -0
  121. package/src/propgen/propPresets.js +82 -0
  122. package/src/propgen/propSettings.js +395 -0
  123. package/src/shaders-tsl/chunks/projected-water-caustics.js +242 -0
  124. package/src/shaders-tsl/chunks/vegetation-style.js +360 -0
  125. package/src/shaders-tsl/chunks/water-shore-state.js +31 -0
  126. package/src/shaders-tsl/chunks/water-waves.js +90 -11
  127. package/src/shaders-tsl/environment.js +15 -1
  128. package/src/shaders-tsl/flower.js +279 -30
  129. package/src/shaders-tsl/grass.js +60 -33
  130. package/src/shaders-tsl/sky.js +125 -31
  131. package/src/shaders-tsl/tree-leaf.js +61 -25
  132. package/src/shaders-tsl/water-breaker.js +7 -4
  133. package/src/shaders-tsl/water-shore-state-simulation.js +523 -0
  134. package/src/shaders-tsl/water.js +439 -49
  135. package/src/shaders-tsl/woody-surface.js +154 -0
  136. package/src/sky/sceneOverrideLayers.js +10 -0
  137. package/src/sky/skyQuality.js +26 -0
  138. package/src/sky/stylizedSky.js +753 -45
  139. package/src/soundscape/index.js +4 -0
  140. package/src/soundscape/soundscapeGenerator.js +179 -0
  141. package/src/soundscape/soundscapeRuntime.js +806 -0
  142. package/src/soundscape/soundscapeSettings.js +292 -0
  143. package/src/styles/index.js +13 -0
  144. package/src/styles/styleBundle.js +325 -0
  145. package/src/stylizedTerrain.js +32 -2
  146. package/src/stylizedWorld.js +423 -20
  147. package/src/texgen/evaluateTexture.js +675 -0
  148. package/src/texgen/index.js +60 -0
  149. package/src/texgen/noise2.js +210 -0
  150. package/src/texgen/textureAi.js +436 -0
  151. package/src/texgen/textureGenerators.js +516 -0
  152. package/src/texgen/texturePresets.js +490 -0
  153. package/src/texgen/textureSettings.js +342 -0
  154. package/src/texgen/textureThree.js +59 -0
  155. package/src/vegetation/flowerSpecies.js +15 -3
  156. package/src/vegetation/grassPalettes.js +153 -0
  157. package/src/vegetation/index.js +6 -0
  158. package/src/vegetation/stylizedBush.js +2 -0
  159. package/src/vegetation/stylizedFlower.js +82 -0
  160. package/src/vegetation/stylizedFlowers.js +48 -7
  161. package/src/vegetation/stylizedForest.js +29 -1
  162. package/src/vegetation/stylizedGrass.js +291 -56
  163. package/src/vegetation/stylizedTree.js +38 -2
  164. package/src/vegetation/stylizedTreeFoliage.js +2 -1
  165. package/src/vegetation/vegetationShaders.js +1110 -0
  166. package/src/vfxgen/INTEGRATION.md +145 -0
  167. package/src/vfxgen/core/burstBackbone.js +380 -0
  168. package/src/vfxgen/core/projectileCore.js +92 -0
  169. package/src/vfxgen/core/spriteShapes.js +98 -0
  170. package/src/vfxgen/core/trailRibbon.js +272 -0
  171. package/src/vfxgen/core/vfxRandom.js +29 -0
  172. package/src/vfxgen/effects/emitHelpers.js +37 -0
  173. package/src/vfxgen/effects/magicEffects.js +162 -0
  174. package/src/vfxgen/effects/movementEffects.js +87 -0
  175. package/src/vfxgen/effects/weaponEffects.js +118 -0
  176. package/src/vfxgen/index.js +18 -0
  177. package/src/vfxgen/moves/moveController.js +146 -0
  178. package/src/vfxgen/moves/moveLibrary.js +335 -0
  179. package/src/vfxgen/vfxPresets.js +98 -0
  180. package/src/vfxgen/vfxSettings.js +384 -0
  181. package/src/vfxgen/vfxSystem.js +449 -0
  182. package/src/vfxgen/weapons/stylizedWeapons.js +137 -0
  183. package/src/villagegen/index.js +4 -0
  184. package/src/villagegen/stylizedVillage.js +490 -0
  185. package/src/villagegen/villageArchetypes.js +160 -0
  186. package/src/villagegen/villageNames.js +40 -0
  187. package/src/villagegen/villageSites.js +105 -0
  188. package/src/water/sceneOverrideLayers.js +23 -0
  189. package/src/water/water.js +5 -0
  190. package/src/water/waterBreakerSystem.js +15 -1
  191. package/src/water/waterCurrentField.js +447 -0
  192. package/src/water/waterMaterial.js +12 -0
  193. package/src/water/waterNearshorePhase.js +320 -0
  194. package/src/water/waterScenePasses.js +83 -30
  195. package/src/water/waterSettings.js +325 -13
  196. package/src/water/waterShoreMaterial.js +322 -0
  197. package/src/water/waterShoreStateField.js +605 -0
  198. package/src/water/waterSurface.js +797 -28
  199. package/src/weather/index.js +6 -0
  200. package/src/weather/weatherPrecipitation.js +221 -0
  201. package/src/weather/weatherPresets.js +258 -0
  202. package/src/weather/weatherSettings.js +269 -0
  203. package/src/weather/weatherSystem.js +871 -0
  204. package/src/worldMinimap.js +62 -0
  205. package/src/worldPresets.js +4 -1
@@ -0,0 +1,490 @@
1
+ // Built-in material presets for the texture generator. Each entry is a
2
+ // partial settings document (merged over DEFAULT_TEXTURE_SETTINGS by
3
+ // createTextureSettings) plus tags used by the offline prompt mapper and
4
+ // the AI archetype catalog. Colors are hex — the settings factory converts.
5
+
6
+ export const TEXTURE_PRESET_CATEGORIES = Object.freeze([
7
+ Object.freeze({ id: 'stone', label: 'Stone & masonry' }),
8
+ Object.freeze({ id: 'ground', label: 'Ground & terrain' }),
9
+ Object.freeze({ id: 'wood', label: 'Wood' }),
10
+ Object.freeze({ id: 'metal', label: 'Metal' }),
11
+ Object.freeze({ id: 'fabric', label: 'Fabric & leather' }),
12
+ Object.freeze({ id: 'ceramic', label: 'Ceramic & man-made' }),
13
+ Object.freeze({ id: 'organic', label: 'Organic & creature' }),
14
+ Object.freeze({ id: 'liquid', label: 'Liquid, ice & fire' }),
15
+ Object.freeze({ id: 'scifi', label: 'Sci-fi & glow' }),
16
+ Object.freeze({ id: 'stylized', label: 'Stylized & graphic' }),
17
+ ]);
18
+
19
+ const ramp = (color0, color1, color2, color3, color4) => ({ color0, color1, color2, color3, color4 });
20
+
21
+ const preset = (id, label, category, tags, settings) => Object.freeze({ category, id, label, settings, tags });
22
+
23
+ export const BUILT_IN_TEXTURE_PRESETS = Object.freeze([
24
+ // ------------------------------------------------------------- stone
25
+ preset('cliff-rock', 'Cliff rock', 'stone', ['rock', 'cliff', 'mountain', 'boulder', 'granite'], {
26
+ base: { generator: 'ridged', scale: 5, detail: 5, stretchY: 1.6, warp: 0.25, contrast: 0.15 },
27
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.4, scale: 16 },
28
+ color: { ...ramp('#2e2a28', '#4d4742', '#6e675e', '#8a8378', '#a89f90'), cavity: 0.5, sheen: 0.22, jitterHue: 0.03 },
29
+ surface: { heightScale: 0.65, roughness: 0.85, roughnessContrast: 0.4 },
30
+ }),
31
+ preset('castle-bricks', 'Castle bricks', 'stone', ['brick', 'castle', 'wall', 'medieval', 'dungeon', 'fortress'], {
32
+ base: { generator: 'bricks', columns: 4, rows: 8, gap: 0.07, bevel: 0.14, cellVariation: 0.45 },
33
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.3, scale: 14 },
34
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.12, scale: 32, cellVariation: 0.5 },
35
+ color: { ...ramp('#241f1c', '#4a423b', '#6b6156', '#847a6c', '#9d9384'), jitterCells: true, jitterValue: 0.14, cavity: 0.55, sheen: 0.15 },
36
+ surface: { heightScale: 0.6, roughness: 0.9, roughnessContrast: 0.35 },
37
+ }),
38
+ preset('mossy-bricks', 'Mossy bricks', 'stone', ['moss', 'brick', 'ruin', 'overgrown', 'ancient', 'swamp'], {
39
+ base: { generator: 'bricks', columns: 4, rows: 8, gap: 0.07, bevel: 0.14, cellVariation: 0.4 },
40
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.3, scale: 14 },
41
+ color: { ...ramp('#241f1c', '#48413a', '#665d52', '#7d7466', '#948a7b'), jitterCells: true, jitterValue: 0.12, cavity: 0.55 },
42
+ accentA: {
43
+ enabled: true, generator: 'fbm', scale: 6, warp: 0.4, coverage: 0.45, softness: 0.22, creviceBias: 0.7,
44
+ color: '#3f5a26', colorB: '#6c8a38', blend: 'normal', roughnessShift: 0.2, heightShift: 0.05,
45
+ },
46
+ surface: { heightScale: 0.6, roughness: 0.9, roughnessContrast: 0.3 },
47
+ }),
48
+ preset('cobblestone', 'Cobblestone', 'stone', ['cobble', 'street', 'road', 'path', 'village'], {
49
+ base: { generator: 'worley', scale: 7, cellJitter: 0.85, cellVariation: 0.4, contrast: 0.05 },
50
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.25, scale: 18 },
51
+ color: { ...ramp('#1f1d1c', '#3d3a37', '#5b5651', '#736d64', '#8d8679'), pos1: 0.16, jitterCells: true, jitterValue: 0.12, cavity: 0.6, sheen: 0.2 },
52
+ surface: { heightScale: 0.7, roughness: 0.85, roughnessContrast: 0.4 },
53
+ }),
54
+ preset('white-marble', 'White marble', 'stone', ['marble', 'polished', 'luxury', 'palace', 'statue', 'bathroom'], {
55
+ base: { generator: 'marble', scale: 4, detail: 5, rings: 3, grain: 0.75, warp: 0.2 },
56
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.15, scale: 9 },
57
+ color: { ...ramp('#8f8d95', '#c9c7cc', '#e8e6e8', '#f2f0f0', '#fbfaf8'), cavity: 0.12, sheen: 0.25, jitterValue: 0.04 },
58
+ surface: { heightScale: 0.12, roughness: 0.22, roughnessContrast: 0.15, aoStrength: 0.25 },
59
+ }),
60
+ preset('black-gold-marble', 'Black & gold marble', 'stone', ['marble', 'gold', 'black', 'luxury', 'expensive', 'lobby'], {
61
+ base: { generator: 'marble', scale: 4, detail: 5, rings: 4, grain: 0.85, warp: 0.3 },
62
+ color: { ...ramp('#101216', '#181b21', '#22262d', '#8a6c26', '#e0b34c'), pos3: 0.88, rampSmooth: 0.8, cavity: 0.1, sheen: 0.3 },
63
+ surface: { heightScale: 0.1, roughness: 0.2, roughnessContrast: 0.1, aoStrength: 0.2 },
64
+ }),
65
+ preset('granite', 'Speckled granite', 'stone', ['granite', 'speckle', 'counter', 'kitchen'], {
66
+ base: { generator: 'fbm', scale: 6, detail: 4, contrast: -0.3 },
67
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.5, scale: 36, cellVariation: 0.75, edgeWidth: 0.22 },
68
+ color: { ...ramp('#26242a', '#4b4750', '#6d6870', '#8b8590', '#b0aab2'), jitterValue: 0.1, cavity: 0.15 },
69
+ surface: { heightScale: 0.15, roughness: 0.45, roughnessContrast: 0.1 },
70
+ }),
71
+ preset('sandstone-strata', 'Sandstone strata', 'stone', ['sandstone', 'canyon', 'desert', 'strata', 'layered', 'mesa'], {
72
+ base: { generator: 'stripes', columns: 9, rotate90: true, warp: 0.4, warpScale: 4, contrast: -0.15 },
73
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.35, scale: 12, stretchX: 3 },
74
+ color: { ...ramp('#6e4526', '#95602f', '#b57e42', '#cf9d5c', '#e5bd7e'), jitterValue: 0.1, cavity: 0.35, sheen: 0.2 },
75
+ surface: { heightScale: 0.45, roughness: 0.85, roughnessContrast: 0.3 },
76
+ }),
77
+ preset('slate', 'Slate', 'stone', ['slate', 'shale', 'dark', 'flagstone'], {
78
+ base: { generator: 'ridged', scale: 6, detail: 4, stretchX: 2.6, contrast: 0.2 },
79
+ color: { ...ramp('#171a20', '#242833', '#333947', '#475062', '#5d677c'), cavity: 0.45, sheen: 0.3, jitterHue: 0.03 },
80
+ surface: { heightScale: 0.4, roughness: 0.6, roughnessContrast: 0.35 },
81
+ }),
82
+ preset('basalt', 'Volcanic basalt', 'stone', ['basalt', 'volcanic', 'black', 'lava rock'], {
83
+ base: { generator: 'turbulence', scale: 7, detail: 5, warp: 0.2, contrast: 0.1 },
84
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.2, scale: 30, cellVariation: 0.6 },
85
+ color: { ...ramp('#0c0c0e', '#1b1a1d', '#2a292c', '#3a383b', '#4d4a4c'), cavity: 0.5, sheen: 0.12 },
86
+ surface: { heightScale: 0.5, roughness: 0.95, roughnessContrast: 0.25 },
87
+ }),
88
+
89
+ // ------------------------------------------------------------- ground
90
+ preset('meadow-grass', 'Meadow grass', 'ground', ['grass', 'lawn', 'meadow', 'field', 'green'], {
91
+ base: { generator: 'fbm', scale: 12, detail: 5, detailGain: 0.55, stretchY: 1.6 },
92
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.25, scale: 40, cellVariation: 0.6 },
93
+ color: { ...ramp('#1d3a14', '#2f5719', '#447722', '#5f942c', '#82b13e'), jitterHue: 0.07, jitterValue: 0.12, cavity: 0.3 },
94
+ surface: { heightScale: 0.35, roughness: 1, roughnessContrast: 0.1 },
95
+ }),
96
+ preset('dry-dirt', 'Dry dirt', 'ground', ['dirt', 'soil', 'earth', 'dusty', 'trail'], {
97
+ base: { generator: 'fbm', scale: 8, detail: 5, warp: 0.15 },
98
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.3, scale: 30, cellVariation: 0.55 },
99
+ color: { ...ramp('#3a2a1c', '#55402a', '#6f5638', '#856a47', '#9c8158'), jitterValue: 0.1, cavity: 0.4 },
100
+ surface: { heightScale: 0.4, roughness: 0.95, roughnessContrast: 0.2 },
101
+ }),
102
+ preset('cracked-mud', 'Cracked mud', 'ground', ['mud', 'cracked', 'drought', 'dry lake', 'wasteland'], {
103
+ base: { generator: 'cracks', scale: 5, edgeWidth: 0.09, cellJitter: 0.9, cellVariation: 0.25, warp: 0.25 },
104
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.25, scale: 14 },
105
+ color: { ...ramp('#33231a', '#5b4530', '#7d6244', '#977a55', '#ac9066'), cavity: 0.65, sheen: 0.12, jitterValue: 0.08 },
106
+ surface: { heightScale: 0.55, roughness: 0.9, roughnessContrast: 0.45 },
107
+ }),
108
+ preset('desert-sand', 'Desert dunes', 'ground', ['sand', 'desert', 'dune', 'beach', 'ripple'], {
109
+ base: { generator: 'fbm', scale: 7, detail: 3, stretchX: 4, warp: 0.2 },
110
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.12, scale: 44, cellVariation: 0.4, edgeWidth: 0.1 },
111
+ color: { ...ramp('#8a5f33', '#b07f45', '#cc9a58', '#e0b26c', '#f0c983'), jitterValue: 0.06, cavity: 0.3, sheen: 0.3 },
112
+ surface: { heightScale: 0.35, roughness: 0.85, roughnessContrast: 0.15 },
113
+ }),
114
+ preset('fresh-snow', 'Fresh snow', 'ground', ['snow', 'winter', 'ice', 'arctic', 'white'], {
115
+ base: { generator: 'fbm', scale: 5, detail: 3, contrast: -0.35 },
116
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.18, scale: 48, cellVariation: 0.35, edgeWidth: 0.08 },
117
+ color: { ...ramp('#9fb6d8', '#c3d3ea', '#e0eaf6', '#f2f7fc', '#ffffff'), cavity: 0.2, cavityTint: '#7d9cc9', sheen: 0.4 },
118
+ surface: { heightScale: 0.3, roughness: 0.4, roughnessContrast: -0.2, aoStrength: 0.35 },
119
+ }),
120
+ preset('forest-floor', 'Forest floor', 'ground', ['forest', 'leaf', 'litter', 'undergrowth', 'woodland'], {
121
+ base: { generator: 'turbulence', scale: 9, detail: 5, warp: 0.3 },
122
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.35, scale: 26, cellVariation: 0.7, edgeWidth: 0.24 },
123
+ color: { ...ramp('#241a10', '#3e2c19', '#564023', '#6d5730', '#82683a'), jitterHue: 0.06, jitterValue: 0.14, cavity: 0.5 },
124
+ accentA: {
125
+ enabled: true, generator: 'fbm', scale: 5, warp: 0.4, coverage: 0.35, softness: 0.25, creviceBias: 0.4,
126
+ color: '#37501f', colorB: '#59742c', blend: 'normal', roughnessShift: 0.1, heightShift: 0.03,
127
+ },
128
+ surface: { heightScale: 0.45, roughness: 1, roughnessContrast: 0.2 },
129
+ }),
130
+ preset('wet-mud', 'Wet mud', 'ground', ['mud', 'wet', 'swamp', 'bog', 'slick'], {
131
+ base: { generator: 'fbm', scale: 6, detail: 4, warp: 0.35 },
132
+ color: { ...ramp('#1c130c', '#2e2013', '#40301c', '#524026', '#665233'), cavity: 0.5, sheen: 0.35, sheenTint: '#cfd8e0' },
133
+ surface: { heightScale: 0.4, roughness: 0.35, roughnessContrast: 0.5 },
134
+ }),
135
+ preset('asphalt', 'Asphalt', 'ground', ['asphalt', 'road', 'tarmac', 'street', 'parking'], {
136
+ base: { generator: 'fbm', scale: 10, detail: 4, contrast: -0.4 },
137
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.4, scale: 46, cellVariation: 0.6, edgeWidth: 0.14 },
138
+ color: { ...ramp('#151517', '#232326', '#2f2f33', '#3b3b40', '#4a4a4f'), jitterValue: 0.06, cavity: 0.3 },
139
+ surface: { heightScale: 0.25, roughness: 0.9, roughnessContrast: 0.2 },
140
+ }),
141
+ preset('gravel', 'Gravel', 'ground', ['gravel', 'pebble', 'crushed stone', 'driveway'], {
142
+ base: { generator: 'worley', scale: 15, cellJitter: 1, cellVariation: 0.55, contrast: 0.05 },
143
+ color: { ...ramp('#26221f', '#453f39', '#615a51', '#7a7266', '#948b7c'), pos1: 0.15, jitterCells: true, jitterValue: 0.16, cavity: 0.5 },
144
+ surface: { heightScale: 0.5, roughness: 0.9, roughnessContrast: 0.3 },
145
+ }),
146
+
147
+ // ------------------------------------------------------------- wood
148
+ preset('oak-planks', 'Oak planks', 'wood', ['wood', 'plank', 'floor', 'oak', 'board'], {
149
+ base: { generator: 'tiles', columns: 4, rows: 1, gap: 0.035, bevel: 0.05, cellVariation: 0.3 },
150
+ detailA: { enabled: true, generator: 'woodGrain', blend: 'multiply', amount: 0.55, scale: 5, rings: 9, grain: 0.55, rotate90: true },
151
+ color: { ...ramp('#3a2413', '#5c3c1e', '#7b5429', '#956b38', '#ab8149'), jitterCells: true, jitterValue: 0.12, cavity: 0.4, sheen: 0.2 },
152
+ surface: { heightScale: 0.3, roughness: 0.65, roughnessContrast: 0.25 },
153
+ }),
154
+ preset('walnut-floor', 'Dark walnut floor', 'wood', ['walnut', 'dark wood', 'floor', 'mahogany', 'furniture'], {
155
+ base: { generator: 'tiles', columns: 5, rows: 1, gap: 0.03, bevel: 0.04, cellVariation: 0.35 },
156
+ detailA: { enabled: true, generator: 'woodGrain', blend: 'multiply', amount: 0.6, scale: 5, rings: 11, grain: 0.6, rotate90: true },
157
+ color: { ...ramp('#190e08', '#2c1a0e', '#3f2715', '#52351d', '#654327'), jitterCells: true, jitterValue: 0.1, cavity: 0.35, sheen: 0.3 },
158
+ surface: { heightScale: 0.22, roughness: 0.4, roughnessContrast: 0.2 },
159
+ }),
160
+ preset('weathered-planks', 'Weathered planks', 'wood', ['weathered', 'old wood', 'barn', 'driftwood', 'fence', 'pier'], {
161
+ base: { generator: 'tiles', columns: 4, rows: 1, gap: 0.05, bevel: 0.07, cellVariation: 0.45 },
162
+ detailA: { enabled: true, generator: 'woodGrain', blend: 'multiply', amount: 0.65, scale: 6, rings: 8, grain: 0.8, rotate90: true },
163
+ detailB: { enabled: true, generator: 'cracks', blend: 'min', amount: 0.25, scale: 12, edgeWidth: 0.06, stretchY: 4 },
164
+ color: { ...ramp('#2b2620', '#4a443b', '#645d51', '#7b7365', '#8f8778'), jitterCells: true, jitterValue: 0.14, cavity: 0.5 },
165
+ wear: { damage: 0.4, dirt: 0.3 },
166
+ surface: { heightScale: 0.4, roughness: 0.9, roughnessContrast: 0.35 },
167
+ }),
168
+ preset('tree-bark', 'Tree bark', 'wood', ['bark', 'tree', 'trunk', 'forest'], {
169
+ base: { generator: 'ridged', scale: 7, detail: 5, stretchY: 3.4, warp: 0.2 },
170
+ color: { ...ramp('#231710', '#3a281a', '#4f3a24', '#63492e', '#775a3a'), cavity: 0.6, sheen: 0.12, jitterValue: 0.1 },
171
+ surface: { heightScale: 0.6, roughness: 0.95, roughnessContrast: 0.35 },
172
+ }),
173
+ preset('birch-wood', 'Birch wood', 'wood', ['birch', 'pale wood', 'plywood', 'scandinavian'], {
174
+ base: { generator: 'woodGrain', scale: 3, rings: 5, grain: 0.35, stretchY: 1.5 },
175
+ color: { ...ramp('#8d7350', '#b39670', '#cfb388', '#e2cba2', '#f0ddb8'), jitterValue: 0.06, cavity: 0.2, sheen: 0.2 },
176
+ surface: { heightScale: 0.15, roughness: 0.55, roughnessContrast: 0.15 },
177
+ }),
178
+ preset('parquet', 'Parquet floor', 'wood', ['parquet', 'herringbone', 'floor', 'basket weave'], {
179
+ base: { generator: 'basketWeave', columns: 4, rows: 4, gap: 0.05, bevel: 0.07 },
180
+ detailA: { enabled: true, generator: 'woodGrain', blend: 'multiply', amount: 0.4, scale: 7, rings: 10, grain: 0.5 },
181
+ color: { ...ramp('#4a2e15', '#6b4520', '#88592a', '#a06c36', '#b57f44'), jitterCells: true, jitterValue: 0.1, cavity: 0.3, sheen: 0.25 },
182
+ surface: { heightScale: 0.25, roughness: 0.5, roughnessContrast: 0.2 },
183
+ }),
184
+
185
+ // ------------------------------------------------------------- metal
186
+ preset('brushed-steel', 'Brushed steel', 'metal', ['steel', 'brushed', 'stainless', 'appliance', 'chrome'], {
187
+ base: { generator: 'fbm', scale: 20, detail: 3, stretchX: 8, contrast: -0.35 },
188
+ color: { ...ramp('#5c6066', '#767b82', '#8d939a', '#a3a9b0', '#bcc2c8'), cavity: 0.08, sheen: 0.25, jitterValue: 0.03 },
189
+ surface: { heightScale: 0.08, normalStrength: 0.6, roughness: 0.38, roughnessContrast: -0.15, metalness: 1, aoStrength: 0.15 },
190
+ }),
191
+ preset('rusted-iron', 'Rusted iron', 'metal', ['rust', 'iron', 'corroded', 'oxidized', 'scrap', 'old metal'], {
192
+ base: { generator: 'fbm', scale: 7, detail: 5, warp: 0.2 },
193
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.2, scale: 34, cellVariation: 0.5 },
194
+ color: { ...ramp('#2c2b2c', '#413f40', '#565354', '#6b6767', '#807b79'), cavity: 0.35, sheen: 0.15 },
195
+ accentA: {
196
+ enabled: true, generator: 'turbulence', scale: 5, warp: 0.5, coverage: 0.55, softness: 0.25, creviceBias: 0.45,
197
+ color: '#6e3312', colorB: '#b06a2a', blend: 'normal', roughnessShift: 0.45, heightShift: 0.04, metalShift: -0.85,
198
+ },
199
+ accentB: {
200
+ enabled: true, generator: 'fbm', scale: 9, coverage: 0.25, softness: 0.2, creviceBias: 0.6,
201
+ color: '#1d1512', colorB: '#33241c', blend: 'multiply', roughnessShift: 0.3, heightShift: -0.03,
202
+ },
203
+ surface: { heightScale: 0.35, roughness: 0.55, roughnessContrast: 0.3, metalness: 0.9 },
204
+ }),
205
+ preset('hammered-copper', 'Hammered copper', 'metal', ['copper', 'hammered', 'bronze', 'kettle', 'artisan'], {
206
+ base: { generator: 'worley', scale: 8, cellJitter: 0.75, invert: true, contrast: 0.1 },
207
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.2, scale: 20 },
208
+ color: { ...ramp('#3c1f10', '#67351a', '#8f4f26', '#b56d35', '#d68d4a'), cavity: 0.35, sheen: 0.35, sheenTint: '#ffd9a8' },
209
+ surface: { heightScale: 0.35, roughness: 0.4, roughnessContrast: 0.3, metalness: 1 },
210
+ }),
211
+ preset('polished-gold', 'Polished gold', 'metal', ['gold', 'golden', 'treasure', 'trim', 'royal'], {
212
+ base: { generator: 'fbm', scale: 6, detail: 3, contrast: -0.45 },
213
+ color: { ...ramp('#6b4a12', '#96691c', '#c08c28', '#ddab38', '#f4c854'), cavity: 0.15, sheen: 0.3, sheenTint: '#fff2c4' },
214
+ surface: { heightScale: 0.08, normalStrength: 0.6, roughness: 0.18, roughnessContrast: 0.1, metalness: 1, aoStrength: 0.15 },
215
+ }),
216
+ preset('galvanized-metal', 'Galvanized metal', 'metal', ['galvanized', 'zinc', 'sheet metal', 'industrial'], {
217
+ base: { generator: 'cells', scale: 7, cellJitter: 1, cellVariation: 0.4, contrast: -0.2 },
218
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.25, scale: 22, stretchX: 2 },
219
+ color: { ...ramp('#565b60', '#6e747a', '#848b91', '#979ea4', '#abb2b8'), jitterCells: true, jitterValue: 0.08, cavity: 0.1, sheen: 0.2 },
220
+ surface: { heightScale: 0.1, normalStrength: 0.6, roughness: 0.5, roughnessContrast: -0.1, metalness: 0.95, aoStrength: 0.2 },
221
+ }),
222
+ preset('scifi-hull', 'Sci-fi hull panels', 'metal', ['sci-fi', 'hull', 'panel', 'spaceship', 'mech', 'plating'], {
223
+ base: { generator: 'tiles', columns: 5, rows: 3, gap: 0.03, bevel: 0.05, cellVariation: 0.3 },
224
+ detailB: { enabled: true, generator: 'speckle', blend: 'min', amount: 0.15, scale: 30, cellVariation: 0.4 },
225
+ color: { ...ramp('#23272e', '#3a4049', '#4f5661', '#646c78', '#7b8490'), jitterCells: true, jitterValue: 0.1, cavity: 0.4, sheen: 0.25 },
226
+ accentB: {
227
+ enabled: true, generator: 'fbm', scale: 8, stretchY: 5, coverage: 0.3, softness: 0.25, creviceBias: 0.3,
228
+ color: '#15171b', colorB: '#2a2e35', blend: 'multiply', roughnessShift: 0.3, heightShift: 0,
229
+ },
230
+ surface: { heightScale: 0.3, roughness: 0.45, roughnessContrast: 0.25, metalness: 0.9 },
231
+ }),
232
+ preset('copper-patina', 'Copper patina', 'metal', ['patina', 'verdigris', 'copper', 'statue', 'roof', 'aged'], {
233
+ base: { generator: 'fbm', scale: 6, detail: 4, warp: 0.25 },
234
+ color: { ...ramp('#33200f', '#553517', '#754a20', '#92602c', '#ab7639'), cavity: 0.3, sheen: 0.2 },
235
+ accentA: {
236
+ enabled: true, generator: 'turbulence', scale: 5, warp: 0.5, coverage: 0.55, softness: 0.3, creviceBias: 0.55,
237
+ color: '#2f8a70', colorB: '#6fc4a5', blend: 'normal', roughnessShift: 0.4, heightShift: 0.03, metalShift: -0.7,
238
+ },
239
+ surface: { heightScale: 0.25, roughness: 0.45, roughnessContrast: 0.25, metalness: 0.95 },
240
+ }),
241
+
242
+ // ------------------------------------------------------------- fabric
243
+ preset('denim', 'Denim', 'fabric', ['denim', 'jeans', 'jacket', 'blue fabric', 'textile'], {
244
+ base: { generator: 'weave', columns: 34, rows: 34, gap: 0.14 },
245
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.2, scale: 5 },
246
+ color: { ...ramp('#141c30', '#20304e', '#2c4166', '#3b537d', '#4f6892'), jitterValue: 0.06, cavity: 0.3, sheen: 0.15 },
247
+ surface: { heightScale: 0.22, roughness: 0.95, roughnessContrast: 0.1, aoStrength: 0.4 },
248
+ }),
249
+ preset('canvas', 'Canvas', 'fabric', ['canvas', 'linen', 'burlap', 'sack', 'tent'], {
250
+ base: { generator: 'weave', columns: 28, rows: 28, gap: 0.18 },
251
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.22, scale: 4 },
252
+ color: { ...ramp('#6b5c44', '#8a795c', '#a29070', '#b5a480', '#c6b691'), jitterValue: 0.07, cavity: 0.25 },
253
+ surface: { heightScale: 0.2, roughness: 1, roughnessContrast: 0.1, aoStrength: 0.35 },
254
+ }),
255
+ preset('tartan-plaid', 'Tartan plaid', 'fabric', ['plaid', 'tartan', 'flannel', 'scottish', 'checkered fabric'], {
256
+ base: { generator: 'checker', columns: 6, rows: 6, warp: 0.03 },
257
+ detailA: { enabled: true, generator: 'stripes', blend: 'multiply', amount: 0.45, columns: 12 },
258
+ detailB: { enabled: true, generator: 'stripes', blend: 'multiply', amount: 0.45, columns: 12, rotate90: true },
259
+ color: { ...ramp('#4a1420', '#77202c', '#9c3033', '#274224', '#3f6a35'), rampSmooth: 0.55, jitterValue: 0.04, cavity: 0.2 },
260
+ surface: { heightScale: 0.12, roughness: 1, roughnessContrast: 0, aoStrength: 0.25 },
261
+ }),
262
+ preset('knit-wool', 'Knit wool', 'fabric', ['knit', 'wool', 'sweater', 'yarn', 'cozy'], {
263
+ base: { generator: 'chevron', columns: 10, rows: 22, warp: 0.08 },
264
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.25, scale: 26, stretchY: 2 },
265
+ color: { ...ramp('#7a6a55', '#998769', '#b3a07d', '#c7b58f', '#d8c8a2'), jitterValue: 0.07, cavity: 0.4, sheen: 0.1 },
266
+ surface: { heightScale: 0.35, roughness: 1, roughnessContrast: 0.15, aoStrength: 0.45 },
267
+ }),
268
+ preset('leather', 'Leather', 'fabric', ['leather', 'hide', 'saddle', 'belt', 'boot'], {
269
+ base: { generator: 'cracks', scale: 26, edgeWidth: 0.12, cellJitter: 1, cellVariation: 0.15 },
270
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.3, scale: 4, warp: 0.25 },
271
+ color: { ...ramp('#2a150b', '#452411', '#5e3418', '#754521', '#8a552b'), pos1: 0.14, jitterValue: 0.07, cavity: 0.45, sheen: 0.3, sheenTint: '#e8c193' },
272
+ surface: { heightScale: 0.15, roughness: 0.55, roughnessContrast: 0.3 },
273
+ }),
274
+ preset('worn-leather', 'Worn leather', 'fabric', ['old leather', 'worn', 'jacket', 'vintage', 'scuffed', 'antique'], {
275
+ base: { generator: 'cracks', scale: 24, edgeWidth: 0.12, cellJitter: 1, cellVariation: 0.2 },
276
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.35, scale: 4, warp: 0.3 },
277
+ detailB: { enabled: true, generator: 'cracks', blend: 'min', amount: 0.3, scale: 9, edgeWidth: 0.05, stretchX: 2.5, warp: 0.2 },
278
+ color: {
279
+ ...ramp('#1d0f08', '#331c0e', '#4a2b15', '#5f3c1e', '#714b28'),
280
+ pos1: 0.12, jitterValue: 0.12, saturation: 0.85, cavity: 0.5, sheen: 0.45, sheenTint: '#d9b184',
281
+ },
282
+ wear: { damage: 0.45, dirt: 0.3 },
283
+ accentB: {
284
+ enabled: true, generator: 'turbulence', scale: 4, coverage: 0.35, softness: 0.3, creviceBias: -0.4,
285
+ color: '#6d4d2c', colorB: '#8a6a40', blend: 'overlay', roughnessShift: -0.25, heightShift: 0,
286
+ },
287
+ surface: { heightScale: 0.16, roughness: 0.6, roughnessContrast: 0.35 },
288
+ }),
289
+ preset('carbon-fiber', 'Carbon fiber', 'fabric', ['carbon', 'fiber', 'racing', 'composite', 'tech'], {
290
+ base: { generator: 'weave', columns: 22, rows: 22, gap: 0.08 },
291
+ color: { ...ramp('#0a0b0d', '#15171b', '#22252b', '#2f333b', '#3e434d'), cavity: 0.3, sheen: 0.5, sheenTint: '#9fb4d8' },
292
+ surface: { heightScale: 0.15, roughness: 0.3, roughnessContrast: -0.2, metalness: 0.4, aoStrength: 0.3 },
293
+ }),
294
+
295
+ // ------------------------------------------------------------- ceramic
296
+ preset('bathroom-tiles', 'Bathroom tiles', 'ceramic', ['tile', 'bathroom', 'kitchen', 'porcelain', 'clean'], {
297
+ base: { generator: 'tiles', columns: 8, rows: 8, gap: 0.05, bevel: 0.05, cellVariation: 0.1 },
298
+ color: { ...ramp('#5f6a68', '#9fb5b0', '#c9dcd6', '#e2efe9', '#f4faf6'), jitterCells: true, jitterValue: 0.05, cavity: 0.35, sheen: 0.35 },
299
+ surface: { heightScale: 0.18, roughness: 0.15, roughnessContrast: 0.35, aoStrength: 0.4 },
300
+ }),
301
+ preset('mosaic-tiles', 'Mosaic tiles', 'ceramic', ['mosaic', 'colorful', 'byzantine', 'pool', 'art'], {
302
+ base: { generator: 'tiles', columns: 14, rows: 14, gap: 0.09, bevel: 0.08, cellVariation: 0.75 },
303
+ color: {
304
+ ...ramp('#20355c', '#2f6a8e', '#3f9d92', '#7cc4a2', '#e9e3c8'),
305
+ jitterCells: true, jitterHue: 0.22, jitterValue: 0.15, cavity: 0.4, sheen: 0.3,
306
+ },
307
+ surface: { heightScale: 0.25, roughness: 0.25, roughnessContrast: 0.35, aoStrength: 0.45 },
308
+ }),
309
+ preset('hex-floor', 'Hex tiles', 'ceramic', ['hexagon', 'hex tile', 'honeycomb floor', 'cafe'], {
310
+ base: { generator: 'hex', columns: 8, gap: 0.09, bevel: 0.12, cellVariation: 0.25 },
311
+ color: { ...ramp('#1e2126', '#33383f', '#484e57', '#5d646e', '#747c86'), jitterCells: true, jitterValue: 0.1, cavity: 0.4, sheen: 0.2 },
312
+ surface: { heightScale: 0.2, roughness: 0.35, roughnessContrast: 0.3, aoStrength: 0.4 },
313
+ }),
314
+ preset('terracotta', 'Terracotta', 'ceramic', ['terracotta', 'clay', 'pot', 'mediterranean', 'roof tile'], {
315
+ base: { generator: 'fbm', scale: 7, detail: 4, contrast: -0.25 },
316
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.15, scale: 30, cellVariation: 0.45 },
317
+ color: { ...ramp('#6e3018', '#8f4423', '#ab572c', '#c06a38', '#d17e46'), jitterValue: 0.07, cavity: 0.3, sheen: 0.15 },
318
+ surface: { heightScale: 0.2, roughness: 0.85, roughnessContrast: 0.2 },
319
+ }),
320
+ preset('concrete', 'Concrete', 'ceramic', ['concrete', 'cement', 'wall', 'brutalist', 'sidewalk'], {
321
+ base: { generator: 'fbm', scale: 5, detail: 5, contrast: -0.35 },
322
+ detailB: { enabled: true, generator: 'speckle', blend: 'min', amount: 0.2, scale: 36, cellVariation: 0.5 },
323
+ color: { ...ramp('#4d4b48', '#67655f', '#7d7b74', '#8f8d85', '#a19f96'), jitterValue: 0.07, cavity: 0.25 },
324
+ accentB: {
325
+ enabled: true, generator: 'fbm', scale: 4, stretchY: 3, coverage: 0.25, softness: 0.3, creviceBias: 0.3,
326
+ color: '#3a3833', colorB: '#54524b', blend: 'multiply', roughnessShift: 0.15, heightShift: 0,
327
+ },
328
+ surface: { heightScale: 0.2, roughness: 0.9, roughnessContrast: 0.2 },
329
+ }),
330
+ preset('stucco', 'Stucco plaster', 'ceramic', ['stucco', 'plaster', 'wall', 'adobe', 'mediterranean'], {
331
+ base: { generator: 'turbulence', scale: 9, detail: 4, contrast: -0.2 },
332
+ color: { ...ramp('#9c8d76', '#b5a78d', '#cbbfa2', '#dcd1b4', '#eae1c6'), jitterValue: 0.05, cavity: 0.3 },
333
+ surface: { heightScale: 0.3, roughness: 0.95, roughnessContrast: 0.2 },
334
+ }),
335
+ preset('roof-shingles', 'Roof shingles', 'ceramic', ['shingle', 'roof', 'slate roof', 'house'], {
336
+ base: { generator: 'scales', columns: 6, rows: 10, cellVariation: 0.4 },
337
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.25, scale: 16 },
338
+ color: { ...ramp('#1c1e24', '#31343d', '#464a55', '#5a5f6b', '#6f7480'), jitterCells: true, jitterValue: 0.12, cavity: 0.55 },
339
+ surface: { heightScale: 0.45, roughness: 0.75, roughnessContrast: 0.3 },
340
+ }),
341
+ preset('circuit-board', 'Circuit board', 'ceramic', ['circuit', 'pcb', 'electronics', 'tech', 'motherboard'], {
342
+ base: { generator: 'grid', columns: 18, rows: 18, gap: 0.1, bevel: 0.03, invert: true, warp: 0.02 },
343
+ detailB: { enabled: true, generator: 'dots', blend: 'max', amount: 0.5, columns: 9, rows: 9, gap: 0.34, bevel: 0.05, cellJitter: 0.6 },
344
+ color: { ...ramp('#0d2818', '#124024', '#1a5a30', '#7a9c48', '#d8c25a'), pos3: 0.82, rampSmooth: 0.5, cavity: 0.2 },
345
+ surface: { heightScale: 0.15, roughness: 0.4, roughnessContrast: -0.3, metalness: 0.35 },
346
+ emissive: { enabled: true, source: 'peaks', threshold: 0.8, width: 0.15, softness: 0.1, color: '#57ff9a', intensity: 1.6 },
347
+ }),
348
+
349
+ // ------------------------------------------------------------- organic
350
+ preset('dragon-scales', 'Dragon scales', 'organic', ['dragon', 'scale', 'reptile', 'creature', 'fantasy'], {
351
+ base: { generator: 'scales', columns: 7, rows: 11, cellVariation: 0.3 },
352
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.2, scale: 20 },
353
+ color: { ...ramp('#0d1f1a', '#14382c', '#1d5540', '#2e7250', '#4a9464'), jitterCells: true, jitterHue: 0.05, jitterValue: 0.1, cavity: 0.6, sheen: 0.4, sheenTint: '#bfe8c9' },
354
+ surface: { heightScale: 0.55, roughness: 0.45, roughnessContrast: 0.35 },
355
+ }),
356
+ preset('reptile-skin', 'Reptile skin', 'organic', ['lizard', 'snake', 'skin', 'crocodile'], {
357
+ base: { generator: 'hex', columns: 13, gap: 0.14, bevel: 0.2, cellVariation: 0.35 },
358
+ color: { ...ramp('#2c2a12', '#45421c', '#5d5a26', '#767230', '#8f8a3c'), jitterCells: true, jitterValue: 0.12, cavity: 0.55, sheen: 0.25 },
359
+ surface: { heightScale: 0.4, roughness: 0.6, roughnessContrast: 0.3 },
360
+ }),
361
+ preset('coral', 'Coral', 'organic', ['coral', 'reef', 'sea', 'underwater'], {
362
+ base: { generator: 'worleyF2', scale: 9, cellJitter: 1, warp: 0.35 },
363
+ detailB: { enabled: true, generator: 'speckle', blend: 'add', amount: 0.2, scale: 36, cellVariation: 0.5 },
364
+ color: { ...ramp('#6e2038', '#a03050', '#c94a62', '#e2707a', '#f29a94'), jitterHue: 0.05, cavity: 0.5, sheen: 0.2 },
365
+ surface: { heightScale: 0.5, roughness: 0.8, roughnessContrast: 0.3 },
366
+ }),
367
+ preset('bone', 'Bone', 'organic', ['bone', 'ivory', 'skull', 'fossil'], {
368
+ base: { generator: 'fbm', scale: 5, detail: 4, stretchX: 2.2, contrast: -0.3 },
369
+ detailB: { enabled: true, generator: 'speckle', blend: 'min', amount: 0.25, scale: 30, cellVariation: 0.45, edgeWidth: 0.12 },
370
+ color: { ...ramp('#786a52', '#9c8d70', '#bcae8d', '#d4c7a4', '#e7dcba'), jitterValue: 0.06, cavity: 0.35, sheen: 0.2 },
371
+ surface: { heightScale: 0.25, roughness: 0.6, roughnessContrast: 0.25 },
372
+ }),
373
+ preset('alien-flesh', 'Alien flesh', 'organic', ['alien', 'flesh', 'organ', 'monster', 'biomass'], {
374
+ base: { generator: 'billow', scale: 6, detail: 5, warp: 0.5 },
375
+ detailA: { enabled: true, generator: 'worleyF2', blend: 'overlay', amount: 0.35, scale: 10, warp: 0.3 },
376
+ color: { ...ramp('#2a0d22', '#4a1638', '#6d224c', '#8f325c', '#b04a68'), jitterHue: 0.06, cavity: 0.5, sheen: 0.5, sheenTint: '#ffc9d8' },
377
+ surface: { heightScale: 0.5, roughness: 0.3, roughnessContrast: 0.4 },
378
+ emissive: { enabled: true, source: 'crevices', threshold: 0.3, width: 0.25, softness: 0.2, color: '#c135b0', intensity: 1.2 },
379
+ }),
380
+ preset('animal-fur', 'Animal fur', 'organic', ['fur', 'fluffy', 'pelt', 'hair'], {
381
+ base: { generator: 'fbm', scale: 18, detail: 5, detailGain: 0.6, stretchY: 7 },
382
+ color: { ...ramp('#2e1d10', '#4c3018', '#684322', '#82562c', '#9a6b38'), jitterValue: 0.12, jitterHue: 0.03, cavity: 0.45, sheen: 0.25 },
383
+ surface: { heightScale: 0.3, roughness: 0.95, roughnessContrast: 0.15 },
384
+ }),
385
+ preset('leopard-spots', 'Leopard spots', 'organic', ['leopard', 'cheetah', 'animal print', 'spots', 'safari'], {
386
+ base: { generator: 'dots', columns: 8, rows: 8, gap: 0.2, bevel: 0.12, cellJitter: 1, cellVariation: 0.4, warp: 0.25, invert: true },
387
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.15, scale: 24 },
388
+ color: { ...ramp('#241505', '#4d3010', '#a76f28', '#cf9a44', '#e4bc66'), pos1: 0.3, pos2: 0.48, rampSmooth: 0.35, jitterValue: 0.06 },
389
+ surface: { heightScale: 0.12, roughness: 0.9, roughnessContrast: 0.1 },
390
+ }),
391
+ preset('zebra-stripes', 'Zebra stripes', 'organic', ['zebra', 'stripes', 'animal print', 'black and white'], {
392
+ base: { generator: 'stripes', columns: 7, warp: 0.45, warpScale: 5, stretchY: 1.4 },
393
+ color: { ...ramp('#131114', '#1d1a1d', '#8e8a86', '#dedad2', '#f7f4ec'), pos1: 0.42, pos2: 0.5, pos3: 0.58, rampSmooth: 0.25 },
394
+ surface: { heightScale: 0.08, roughness: 0.85, roughnessContrast: 0 },
395
+ }),
396
+
397
+ // ------------------------------------------------------------- liquid
398
+ preset('water-caustics', 'Water caustics', 'liquid', ['water', 'caustics', 'pool', 'ocean floor', 'sea'], {
399
+ base: { generator: 'caustics', scale: 6, edgeWidth: 0.2, warp: 0.25 },
400
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.25, scale: 8, warp: 0.3 },
401
+ color: { ...ramp('#0a2e4a', '#10496b', '#1a6d8e', '#3fa3b8', '#bfeef2'), pos3: 0.82, cavity: 0.15, sheen: 0.3 },
402
+ surface: { heightScale: 0.25, roughness: 0.12, roughnessContrast: 0.2 },
403
+ }),
404
+ preset('lava-flow', 'Lava flow', 'liquid', ['lava', 'magma', 'molten', 'volcano', 'fire'], {
405
+ base: { generator: 'cracks', scale: 5, edgeWidth: 0.14, cellJitter: 1, cellVariation: 0.3, warp: 0.4 },
406
+ detailA: { enabled: true, generator: 'turbulence', blend: 'overlay', amount: 0.3, scale: 12 },
407
+ color: { ...ramp('#1a0f0c', '#241a16', '#33261e', '#453528', '#584434'), cavity: 0.3, sheen: 0.1 },
408
+ surface: { heightScale: 0.6, roughness: 0.9, roughnessContrast: 0.35 },
409
+ emissive: { enabled: true, source: 'crevices', threshold: 0.34, width: 0.3, softness: 0.15, color: '#ff5a00', intensity: 4 },
410
+ }),
411
+ preset('cooled-magma', 'Cooling magma', 'liquid', ['magma', 'ember', 'cooling', 'obsidian', 'scorched'], {
412
+ base: { generator: 'cracks', scale: 7, edgeWidth: 0.08, cellJitter: 1, warp: 0.3 },
413
+ color: { ...ramp('#0b0a0c', '#161417', '#232025', '#302c31', '#403a3e'), cavity: 0.45, sheen: 0.2 },
414
+ surface: { heightScale: 0.5, roughness: 0.75, roughnessContrast: 0.3 },
415
+ emissive: { enabled: true, source: 'crevices', threshold: 0.22, width: 0.18, softness: 0.12, color: '#c9351a', intensity: 2 },
416
+ }),
417
+ preset('cracked-ice', 'Cracked ice', 'liquid', ['ice', 'frozen', 'glacier', 'frost', 'winter'], {
418
+ base: { generator: 'cracks', scale: 5, edgeWidth: 0.05, cellJitter: 1, warp: 0.2, invert: true },
419
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.2, scale: 10 },
420
+ color: { ...ramp('#eef8ff', '#c3e2f2', '#9cc8e4', '#7cb2d6', '#5e9bc4'), pos1: 0.14, cavity: 0.15, sheen: 0.5, sheenTint: '#ffffff' },
421
+ surface: { heightScale: 0.2, roughness: 0.08, roughnessContrast: 0.3, aoStrength: 0.25 },
422
+ }),
423
+ preset('toxic-slime', 'Toxic slime', 'liquid', ['slime', 'toxic', 'goo', 'ooze', 'poison'], {
424
+ base: { generator: 'billow', scale: 6, detail: 5, warp: 0.5 },
425
+ color: { ...ramp('#0d2a10', '#17471a', '#256b22', '#3f9430', '#6fc04a'), cavity: 0.35, sheen: 0.55, sheenTint: '#d8ffc9' },
426
+ surface: { heightScale: 0.45, roughness: 0.12, roughnessContrast: 0.4 },
427
+ emissive: { enabled: true, source: 'peaks', threshold: 0.72, width: 0.3, softness: 0.25, color: '#4dff2e', intensity: 1.4 },
428
+ }),
429
+
430
+ // ------------------------------------------------------------- scifi
431
+ preset('energy-plasma', 'Energy plasma', 'scifi', ['energy', 'plasma', 'magic', 'portal', 'arcane'], {
432
+ base: { generator: 'caustics', scale: 5, edgeWidth: 0.25, warp: 0.6, warpScale: 4 },
433
+ detailA: { enabled: true, generator: 'turbulence', blend: 'screen', amount: 0.35, scale: 9, warp: 0.4 },
434
+ color: { ...ramp('#160a33', '#2c1461', '#4c1d94', '#8438c9', '#e26bf5'), cavity: 0, sheen: 0.3, sheenTint: '#9fd9ff' },
435
+ surface: { heightScale: 0.25, roughness: 0.3, roughnessContrast: 0 },
436
+ emissive: { enabled: true, source: 'peaks', threshold: 0.55, width: 0.4, softness: 0.3, color: '#b44dff', intensity: 3 },
437
+ }),
438
+ preset('hex-shield', 'Hex force shield', 'scifi', ['shield', 'hexagon', 'force field', 'hologram', 'barrier'], {
439
+ base: { generator: 'hex', columns: 10, gap: 0.1, bevel: 0.08, cellVariation: 0.3 },
440
+ color: { ...ramp('#04121f', '#082338', '#0d3653', '#144a6e', '#1d6089'), jitterCells: true, jitterValue: 0.15, cavity: 0.2 },
441
+ surface: { heightScale: 0.15, roughness: 0.25, roughnessContrast: 0, metalness: 0.3 },
442
+ emissive: { enabled: true, source: 'crevices', threshold: 0.3, width: 0.2, softness: 0.12, color: '#2fd6ff', intensity: 4.5 },
443
+ }),
444
+ preset('alien-circuit', 'Alien circuitry', 'scifi', ['alien tech', 'runes', 'glyph', 'ancient machine'], {
445
+ base: { generator: 'grid', columns: 12, rows: 12, gap: 0.16, bevel: 0.04, invert: true, warp: 0.12, warpScale: 6 },
446
+ detailB: { enabled: true, generator: 'cracks', blend: 'max', amount: 0.4, scale: 7, edgeWidth: 0.07, invert: true },
447
+ color: { ...ramp('#0c1214', '#172226', '#233338', '#31454a', '#41585c'), cavity: 0.3, sheen: 0.2 },
448
+ surface: { heightScale: 0.3, roughness: 0.5, roughnessContrast: 0.3, metalness: 0.6 },
449
+ emissive: { enabled: true, source: 'peaks', threshold: 0.78, width: 0.2, softness: 0.12, color: '#38ffd0', intensity: 3 },
450
+ }),
451
+ preset('starfield-nebula', 'Nebula', 'scifi', ['nebula', 'space', 'galaxy', 'cosmos', 'stars'], {
452
+ base: { generator: 'fbm', scale: 4, detail: 6, warp: 0.55, warpScale: 3 },
453
+ detailB: { enabled: true, generator: 'speckle', blend: 'max', amount: 0.6, scale: 52, cellVariation: 0.3, edgeWidth: 0.07 },
454
+ color: { ...ramp('#050514', '#141033', '#2c1a5e', '#63308f', '#e8dcf5'), pos3: 0.86, cavity: 0, sheen: 0 },
455
+ surface: { heightScale: 0.1, roughness: 1, roughnessContrast: 0, aoStrength: 0 },
456
+ emissive: { enabled: true, source: 'peaks', threshold: 0.82, width: 0.2, softness: 0.2, color: '#cfa4ff', intensity: 2 },
457
+ }),
458
+
459
+ // ------------------------------------------------------------- stylized
460
+ preset('toon-clouds', 'Toon clouds', 'stylized', ['cloud', 'sky', 'cartoon', 'anime', 'puffy'], {
461
+ base: { generator: 'billow', scale: 4, detail: 4, warp: 0.2 },
462
+ color: { ...ramp('#7ba6d8', '#9fc0e6', '#c4daf0', '#e4eef8', '#ffffff'), rampSmooth: 0.22, cavity: 0.1, cavityTint: '#6f96c9' },
463
+ surface: { heightScale: 0.3, normalStrength: 0.5, roughness: 1, roughnessContrast: 0, aoStrength: 0.2 },
464
+ }),
465
+ preset('forest-camo', 'Forest camo', 'stylized', ['camo', 'camouflage', 'military', 'army'], {
466
+ base: { generator: 'cells', scale: 4, cellJitter: 1, cellVariation: 0.8, warp: 0.4, warpScale: 3 },
467
+ color: { ...ramp('#2a2a1a', '#3d4a24', '#57652f', '#6f5d33', '#8a8250'), rampSmooth: 0.08, jitterCells: false },
468
+ surface: { heightScale: 0.05, roughness: 1, roughnessContrast: 0, aoStrength: 0.1 },
469
+ }),
470
+ preset('halftone', 'Halftone dots', 'stylized', ['halftone', 'comic', 'pop art', 'print', 'manga'], {
471
+ base: { generator: 'dots', columns: 22, rows: 22, gap: 0.16, bevel: 0.1 },
472
+ color: { ...ramp('#20242c', '#333947', '#8c93a3', '#dfe3ea', '#f7f8fa'), pos1: 0.4, pos2: 0.5, pos3: 0.62, rampSmooth: 0.3 },
473
+ surface: { heightScale: 0.05, roughness: 0.9, roughnessContrast: 0, aoStrength: 0.1 },
474
+ }),
475
+ preset('retro-checker', 'Retro checker', 'stylized', ['checker', 'diner', 'retro', 'race flag'], {
476
+ base: { generator: 'checker', columns: 8, rows: 8 },
477
+ detailA: { enabled: true, generator: 'fbm', blend: 'overlay', amount: 0.12, scale: 20 },
478
+ color: { ...ramp('#1d2126', '#2c3138', '#9aa4ab', '#e8e3d5', '#f6f1e3'), pos1: 0.42, pos2: 0.5, pos3: 0.58, rampSmooth: 0.2, cavity: 0.15 },
479
+ surface: { heightScale: 0.08, roughness: 0.35, roughnessContrast: 0.2 },
480
+ }),
481
+ preset('candy-stripes', 'Candy stripes', 'stylized', ['candy', 'stripes', 'circus', 'sweet', 'pink'], {
482
+ base: { generator: 'stripes', columns: 10, warp: 0.05 },
483
+ color: { ...ramp('#c2385a', '#dc5b78', '#f2f0e8', '#f7dce2', '#fcf3f0'), pos1: 0.44, pos2: 0.5, pos3: 0.56, rampSmooth: 0.25, sheen: 0.25 },
484
+ surface: { heightScale: 0.06, roughness: 0.3, roughnessContrast: 0 },
485
+ }),
486
+ ]);
487
+
488
+ export function findTexturePreset(id) {
489
+ return BUILT_IN_TEXTURE_PRESETS.find((entry) => entry.id === id) ?? null;
490
+ }