@call-me-sensei/toonlab 0.2.0 → 0.3.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 (205) hide show
  1. package/AGENTS.md +127 -4
  2. package/ATTRIBUTION.md +41 -3
  3. package/README.md +234 -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 +739 -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,154 @@
1
+ // Opaque stylized material for trunks, branches, roots, and other woody
2
+ // surfaces. Bark is intentionally not routed through thin-surface lighting:
3
+ // it shares the IP lighting/weather treatment, but owns its toon ramp and
4
+ // woody accents independently from leaves, petals, and grass blades.
5
+
6
+ import * as THREE from 'three';
7
+ import {
8
+ abs,
9
+ cameraPosition,
10
+ clamp,
11
+ dot,
12
+ floor,
13
+ Fn,
14
+ max,
15
+ mix,
16
+ normalize,
17
+ normalWorld,
18
+ positionLocal,
19
+ positionWorld,
20
+ pow,
21
+ smoothstep,
22
+ texture,
23
+ uniform,
24
+ uv,
25
+ vec3,
26
+ vec4,
27
+ } from 'three/tsl';
28
+ import { NodeMaterial } from 'three/webgpu';
29
+
30
+ import { sampleEnvironmentSunShadow } from './chunks/environment-sun-shadow.js';
31
+ import {
32
+ createVegetationStyleUniforms,
33
+ tagVegetationRole,
34
+ } from './chunks/vegetation-style.js';
35
+
36
+ export function createWoodySurfaceNodeMaterial({
37
+ color = 0xc9ab8a,
38
+ height = 1,
39
+ map = null,
40
+ vegetationShader = null,
41
+ } = {}) {
42
+ const u = {
43
+ uBaseColor: uniform(new THREE.Color(color)),
44
+ uHeight: uniform(Math.max(Number(height) || 1, 1e-3)),
45
+ uSkyColor: uniform(new THREE.Color().setRGB(0.72, 0.87, 1, THREE.SRGBColorSpace)),
46
+ uSunColor: uniform(new THREE.Color().setRGB(1, 0.96, 0.86, THREE.SRGBColorSpace)),
47
+ uSunDirection: uniform(new THREE.Vector3(0.45, 0.75, 0.5).normalize()),
48
+ ...createVegetationStyleUniforms(vegetationShader, 'woodySurface'),
49
+ };
50
+ const albedo = map ? texture(map).rgb.mul(u.uBaseColor) : u.uBaseColor;
51
+
52
+ const material = new NodeMaterial();
53
+ material.name = 'StylizedWoodySurface';
54
+ material.fog = true;
55
+ material.map = map;
56
+ material.fragmentNode = Fn(() => {
57
+ const normal = normalize(normalWorld);
58
+ const sunDirection = normalize(u.uSunDirection);
59
+ const light = clamp(dot(normal, sunDirection).mul(0.5).add(0.5), 0, 1).toVar();
60
+ const steps = max(floor(u.uStyleBarkBandCount), 2);
61
+ const intervals = max(steps.sub(1), 1);
62
+ const hardBand = floor(light.mul(intervals).add(1e-4)).div(intervals);
63
+ const band = mix(hardBand, light, u.uStyleBarkBandSoftness).toVar();
64
+ const visibility = sampleEnvironmentSunShadow(positionWorld).toVar();
65
+ const lit = band.mul(visibility).toVar();
66
+
67
+ const localHeight = clamp(positionLocal.y.div(u.uHeight), 0, 1);
68
+ const verticalShade = mix(
69
+ u.uStyleBarkVerticalShadeStrength.oneMinus(),
70
+ 1,
71
+ localHeight,
72
+ );
73
+ const colorNode = albedo.mul(mix(u.uStyleBarkShadowFloor, 1, lit))
74
+ .mul(verticalShade).toVar();
75
+
76
+ const shadowAmount = visibility.oneMinus()
77
+ .mul(u.uStyleLightingShadowTintStrength);
78
+ colorNode.mulAssign(mix(
79
+ vec3(1),
80
+ u.uStyleLightingShadowTint,
81
+ clamp(shadowAmount, 0, 1),
82
+ ));
83
+ colorNode.mulAssign(mix(
84
+ vec3(1),
85
+ u.uSunColor,
86
+ lit.mul(u.uStyleLightingSunTintStrength.add(u.uStyleBarkSunTintStrength)),
87
+ ));
88
+ colorNode.addAssign(
89
+ u.uSkyColor.mul(lit.oneMinus())
90
+ .mul(u.uStyleLightingSkyFillStrength.add(u.uStyleBarkSkyFillStrength)),
91
+ );
92
+
93
+ const viewDirection = normalize(cameraPosition.sub(positionWorld));
94
+ const rim = pow(
95
+ clamp(abs(dot(normal, viewDirection)).oneMinus(), 0, 1),
96
+ u.uStyleLightingRimPower,
97
+ );
98
+ colorNode.addAssign(
99
+ u.uSkyColor.mul(rim)
100
+ .mul(u.uStyleLightingRimStrength.add(u.uStyleBarkRimStrength)),
101
+ );
102
+
103
+ const halfVector = normalize(sunDirection.add(viewDirection));
104
+ const specular = pow(clamp(dot(normal, halfVector), 0, 1), 24)
105
+ .mul(visibility).mul(u.uStyleBarkSpecularStrength);
106
+
107
+ const wet = clamp(u.uWetness.mul(u.uWetnessResponse), 0, 1).toVar();
108
+ colorNode.mulAssign(wet.mul(u.uStyleWeatherResponseWetDarkening).oneMinus());
109
+ const luminance = dot(colorNode, vec3(0.299, 0.587, 0.114));
110
+ colorNode.assign(mix(
111
+ colorNode,
112
+ vec3(luminance),
113
+ wet.mul(u.uStyleWeatherResponseWetDesaturation),
114
+ ));
115
+ colorNode.addAssign(
116
+ u.uSunColor.mul(specular.add(
117
+ wet.mul(u.uStyleWeatherResponseWetHighlightStrength)
118
+ .mul(rim.mul(0.5).add(0.08)),
119
+ )),
120
+ );
121
+
122
+ const snowSoftness = u.uStyleWeatherResponseSnowEdgeSoftness.max(0.001);
123
+ const snowFacing = smoothstep(
124
+ snowSoftness.mul(-0.25),
125
+ snowSoftness.mul(0.75),
126
+ normal.y,
127
+ );
128
+ const snow = clamp(u.uSnowCover.mul(u.uSnowRetention).mul(snowFacing), 0, 1);
129
+ const snowTint = u.uStyleWeatherResponseSnowTint.mul(mix(
130
+ u.uStyleWeatherResponseSnowShadowStrength,
131
+ 1,
132
+ visibility,
133
+ ));
134
+ colorNode.assign(mix(colorNode, snowTint, snow));
135
+
136
+ return vec4(colorNode, 1);
137
+ })();
138
+
139
+ material.uniforms = u;
140
+ return tagVegetationRole(material, 'woodySurface', 'mesh');
141
+ }
142
+
143
+ export function setWoodySurfaceSun(material, {
144
+ color = [1, 0.96, 0.86],
145
+ direction = [0.45, 0.75, 0.5],
146
+ sky = [0.72, 0.87, 1],
147
+ } = {}) {
148
+ const uniforms = material?.uniforms;
149
+ if (!uniforms) return material;
150
+ uniforms.uSunDirection?.value.set(...direction).normalize();
151
+ uniforms.uSunColor?.value.setRGB(...color, THREE.SRGBColorSpace);
152
+ uniforms.uSkyColor?.value.setRGB(...sky, THREE.SRGBColorSpace);
153
+ return material;
154
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Ordered transient layers for the active sky. Lower priorities establish a
3
+ * base that higher priorities can derive from or replace. These values are
4
+ * runtime policy, never part of a portable sky-look document.
5
+ */
6
+ export const SKY_SCENE_OVERRIDE_PRIORITIES = Object.freeze({
7
+ lighting: 100,
8
+ weather: 200,
9
+ scene: 300,
10
+ });
@@ -0,0 +1,26 @@
1
+ const TIERS = Object.freeze({
2
+ low: Object.freeze({ cloudOctaves: 2, id: 'low' }),
3
+ medium: Object.freeze({ cloudOctaves: 3, id: 'medium' }),
4
+ high: Object.freeze({ cloudOctaves: 4, id: 'high' }),
5
+ });
6
+
7
+ /** Compile-time Sky deployment tiers. They never enter portable art presets. */
8
+ export const SKY_QUALITY_TIERS = TIERS;
9
+ export const SKY_QUALITY_OPTIONS = Object.freeze(Object.keys(TIERS));
10
+
11
+ /**
12
+ * Resolves a named tier or a custom `{ cloudOctaves }` build policy. Cloud
13
+ * FBM loops are unrolled, so changing quality requires a material rebuild.
14
+ */
15
+ export function resolveSkyQuality(value = 'high') {
16
+ if (value && typeof value === 'object') {
17
+ const fallback = TIERS[String(value.id ?? value.quality ?? '').toLowerCase()] ?? TIERS.high;
18
+ const requested = Number(value.cloudOctaves);
19
+ const cloudOctaves = Number.isFinite(requested)
20
+ ? Math.min(5, Math.max(1, Math.round(requested)))
21
+ : fallback.cloudOctaves;
22
+ const named = Object.values(TIERS).find((tier) => tier.cloudOctaves === cloudOctaves);
23
+ return Object.freeze({ cloudOctaves, id: named?.id ?? 'custom' });
24
+ }
25
+ return TIERS[String(value ?? '').toLowerCase()] ?? TIERS.high;
26
+ }