@call-me-sensei/toonlab 0.4.19 → 0.4.21

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 (123) hide show
  1. package/NPM-LIBRARY.md +230 -0
  2. package/README.md +78 -36
  3. package/agents/PROMPTS.md +91 -0
  4. package/agents/README.md +9 -14
  5. package/agents/claude/CLAUDE.md +8 -0
  6. package/agents/codex/AGENTS.md +161 -0
  7. package/agents/cursor/toonlab.mdc +37 -0
  8. package/agents/references/mcp-asset-discovery.md +12 -9
  9. package/agents/references/runtime-entry-points.md +5 -4
  10. package/agents/skills/claude/asset-sourcing/SKILL.md +9 -6
  11. package/agents/skills/claude/rock-ground-shaders/SKILL.md +16 -0
  12. package/agents/skills/claude/vegetation-sky/SKILL.md +7 -4
  13. package/agents/skills/codex/asset-sourcing/SKILL.md +9 -6
  14. package/agents/skills/codex/rock-ground-shaders/SKILL.md +16 -0
  15. package/agents/skills/codex/vegetation-sky/SKILL.md +7 -4
  16. package/cli/toonlab.mjs +3 -2
  17. package/database/fal-patina.mjs +131 -0
  18. package/database/generation-service.mjs +108 -7
  19. package/database/migrations/0007_creation_revisions.sql +80 -0
  20. package/database/migrations/0008_creation_revision_hardening.sql +98 -0
  21. package/database/migrations/0009_creation_revision_delete_integrity.sql +11 -0
  22. package/database/migrations/0010_external_catalog_assets.sql +28 -0
  23. package/database/providers.mjs +195 -16
  24. package/database/repository.mjs +518 -70
  25. package/database/seeds/catalog/0003_2026-08-open-assets.sql +159086 -0
  26. package/database/seeds/catalog/0004_2026-08-c7-rocks.sql +39405 -0
  27. package/mcp/public-catalog.mjs +4 -52
  28. package/mcp/server.mjs +175 -12
  29. package/mcp/vite-plugin.mjs +78 -2
  30. package/package.json +32 -12
  31. package/scripts/generate-catalog-seed.mjs +34 -7
  32. package/src/asset-policy/catalogLicenses.js +64 -6
  33. package/src/assetlib/loadImported.js +15 -1
  34. package/src/catalog/officialCatalogAssetRuntime.js +13 -2
  35. package/src/catalog/officialCatalogLod.js +34 -1
  36. package/src/catalog/officialCatalogPlacement.js +29 -14
  37. package/src/character/animationRetarget.js +2 -0
  38. package/src/character/characterRig.js +6 -1
  39. package/src/character/characterRuntime.js +175 -7
  40. package/src/environment/environmentMaterialAdapter.js +30 -0
  41. package/src/environment/environmentPresets.js +90 -0
  42. package/src/environment/environmentSunShadowPass.js +42 -0
  43. package/src/environment/toonLabSurfaceLighting.js +108 -10
  44. package/src/environment/urbanPropMaterial.js +104 -2
  45. package/src/lighting/lightingSystem.js +65 -10
  46. package/src/renderer/index.js +7 -0
  47. package/src/renderer/styleComparison.js +985 -0
  48. package/src/rock-shader/index.js +5 -0
  49. package/src/rock-shader/rockGeometryDetail.js +701 -0
  50. package/src/rock-shader/rockMaterial.js +782 -39
  51. package/src/rock-shader/rockRegionRuntime.js +185 -0
  52. package/src/rock-shader/rockSemanticMaterialRuntime.js +337 -0
  53. package/src/rock-shader/rockShaderRuntime.js +354 -67
  54. package/src/rock-shader/rockShaderSettings.js +246 -16
  55. package/src/rock-shader/rockTangentIntegrity.js +136 -0
  56. package/src/rock-shader/rockTextureIntegrity.js +115 -0
  57. package/src/rockgen/index.js +1 -0
  58. package/src/rockgen/rockDocument.js +27 -3
  59. package/src/rockgen/surface/c7GeologySurface.js +372 -0
  60. package/src/shaders-tsl/water.js +8 -0
  61. package/src/sky/cloudShadow.js +25 -1
  62. package/src/sky/skySystem.js +9 -0
  63. package/src/styles/index.js +23 -0
  64. package/src/styles/neutralStylePresets.js +712 -0
  65. package/src/styles/sceneStyleRuntime.js +51 -4
  66. package/src/styles/styleAdapters.js +13 -2
  67. package/src/styles/styleBundle.js +1 -1
  68. package/src/texgen/evaluateTexture.js +30 -3
  69. package/src/texgen/textureGenerators.js +63 -31
  70. package/src/texgen/textureSettings.js +25 -8
  71. package/src/toon/toonSettings.js +96 -2
  72. package/src/vegetation/branchTree.js +327 -42
  73. package/src/vegetation/index.js +24 -2
  74. package/src/vegetation/scatter.js +372 -1
  75. package/src/vegetation/stylizedTree.js +312 -126
  76. package/src/vegetation/stylizedTreeFoliage.js +229 -7
  77. package/src/vegetation/treeSurfaceTextures.js +328 -0
  78. package/src/version.js +1 -1
  79. package/src/water/waterSettings.js +15 -7
  80. package/types/asset-policy/catalogLicenses.d.ts +2 -0
  81. package/types/asset-policy/index.d.ts +2 -0
  82. package/types/assetlib/loadImported.d.ts +3 -1
  83. package/types/catalog/officialCatalogLod.d.ts +63 -5
  84. package/types/character/characterRig.d.ts +59 -0
  85. package/types/character/characterRuntime.d.ts +1 -0
  86. package/types/environment/environmentMaterialAdapter.d.ts +3 -1
  87. package/types/environment/toonLabSurfaceLighting.d.ts +20 -3
  88. package/types/index.d.ts +89 -7
  89. package/types/lighting/lightingSystem.d.ts +7 -0
  90. package/types/react/index.d.ts +20 -0
  91. package/types/renderer/index.d.ts +1 -0
  92. package/types/renderer/styleComparison.d.ts +409 -0
  93. package/types/rock-shader/index.d.ts +5 -0
  94. package/types/rock-shader/rockGeometryDetail.d.ts +300 -0
  95. package/types/rock-shader/rockMaterial.d.ts +3 -0
  96. package/types/rock-shader/rockRegionRuntime.d.ts +86 -0
  97. package/types/rock-shader/rockSemanticMaterialRuntime.d.ts +29 -0
  98. package/types/rock-shader/rockShaderRuntime.d.ts +2 -0
  99. package/types/rock-shader/rockShaderSettings.d.ts +19 -5
  100. package/types/rock-shader/rockTangentIntegrity.d.ts +51 -0
  101. package/types/rock-shader/rockTextureIntegrity.d.ts +61 -0
  102. package/types/rockgen/index.d.ts +1 -0
  103. package/types/rockgen/rockDocument.d.ts +29 -1
  104. package/types/rockgen/surface/c7GeologySurface.d.ts +8 -0
  105. package/types/sky/cloudShadow.d.ts +1 -0
  106. package/types/styles/index.d.ts +1 -0
  107. package/types/styles/neutralStylePresets.d.ts +944 -0
  108. package/types/styles/sceneStyleRuntime.d.ts +20 -0
  109. package/types/vegetation/branchTree.d.ts +4 -0
  110. package/types/vegetation/index.d.ts +9 -7
  111. package/types/vegetation/scatter.d.ts +1 -0
  112. package/types/vegetation/stylizedTree.d.ts +1 -2
  113. package/types/vegetation/stylizedTreeFoliage.d.ts +1 -0
  114. package/types/version.d.ts +1 -1
  115. package/agents/references/geology-playbook.md +0 -118
  116. package/agents/skills/claude/karst-cliff-construction/SKILL.md +0 -258
  117. package/agents/skills/claude/outdoor-world/SKILL.md +0 -492
  118. package/agents/skills/claude/outdoor-world/references/coastal-landform-formation.md +0 -100
  119. package/agents/skills/codex/karst-cliff-construction/SKILL.md +0 -258
  120. package/agents/skills/codex/outdoor-world/SKILL.md +0 -492
  121. package/agents/skills/codex/outdoor-world/references/coastal-landform-formation.md +0 -100
  122. package/src/vegetation/legacyTreePresets.js +0 -120
  123. package/types/vegetation/legacyTreePresets.d.ts +0 -22
@@ -0,0 +1,944 @@
1
+ /**
2
+ * Registers `neutral` into every domain registry that has one. Idempotent and
3
+ * safe to call from any entry point; returns the per-registrar result.
4
+ */
5
+ export function registerNeutralStylePresets({ force }?: {
6
+ force?: boolean;
7
+ }): {
8
+ alreadyRegistered: boolean;
9
+ registrars: ({
10
+ id: string;
11
+ ok: boolean;
12
+ result: string | {
13
+ description: any;
14
+ id: any;
15
+ label: any;
16
+ };
17
+ error?: undefined;
18
+ } | {
19
+ error: string;
20
+ id: string;
21
+ ok: boolean;
22
+ result?: undefined;
23
+ })[];
24
+ };
25
+ /**
26
+ * Reports neutral coverage per slot against the Call Me Sensei slot list, so a
27
+ * gap is visible instead of implied.
28
+ */
29
+ export function describeNeutralStyleCoverage(): {
30
+ abSafe: any;
31
+ coverage: any;
32
+ inBundle: boolean;
33
+ note: any;
34
+ slot: string;
35
+ }[];
36
+ /**
37
+ * Proves that `neutral` differs from `call_me_sensei` in SHADING ONLY.
38
+ *
39
+ * Two questions, deliberately separated, because they have different answers
40
+ * and only one of them is a defect:
41
+ *
42
+ * - **issues (must be empty).** When a host supplies the same explicit
43
+ * recipe to both presets — which is what a scene always does — do the
44
+ * geometry / mask / tiling / motion keys resolve identically? If not, the
45
+ * neutral preset is overriding something it has no business owning, and the
46
+ * two halves of a wipe would not share geometry.
47
+ * - **warnings (informational).** With NO host recipe, do the bare
48
+ * resolutions differ? Some do, and that is correct: `bladesPerClump` is a
49
+ * property of the field the host authored, not of the style, so `neutral`
50
+ * does not declare it and it falls through to the schema default rather
51
+ * than to the styled preset's value. Each key listed here is one the host
52
+ * must pass identically to both halves. The ground shader takes the other
53
+ * policy — it PINS its mask keys to the styled values so an un-parameterised
54
+ * neutral still paints the same masks — and reports no warnings as a result.
55
+ */
56
+ export function auditNeutralStyleShadingOnly(): {
57
+ domains: any[];
58
+ issues: any[];
59
+ ok: boolean;
60
+ warnings: any[];
61
+ };
62
+ /** The reserved id every domain uses for its un-stylized baseline. */
63
+ export const NEUTRAL_STYLE_PRESET_ID: "neutral";
64
+ /**
65
+ * Character toon shading. Disables every graphic feature (cel bands, outlines,
66
+ * rim, hair/eye highlights, face proxy normals, shadow tinting, skin-tone
67
+ * grading) and lets shadows fall to their physical depth by dropping the anime
68
+ * "minimum light" floors to zero. Material maps, alpha, specular, scene/self
69
+ * shadow and indirect light stay ON — that is the PBR half of the shader.
70
+ */
71
+ export const NEUTRAL_TOON_SETTINGS: Readonly<{
72
+ averageShadow: {
73
+ enabled: boolean;
74
+ };
75
+ celShade: {
76
+ enabled: boolean;
77
+ };
78
+ contactShadow: {
79
+ enabled: boolean;
80
+ };
81
+ eyeHighlight: {
82
+ enabled: boolean;
83
+ };
84
+ faceLighting: {
85
+ enabled: boolean;
86
+ };
87
+ fur: {
88
+ enabled: boolean;
89
+ };
90
+ glitter: {
91
+ enabled: boolean;
92
+ };
93
+ hairHighlight: {
94
+ enabled: boolean;
95
+ };
96
+ outline: {
97
+ enabled: boolean;
98
+ };
99
+ perspectiveRemoval: {
100
+ enabled: boolean;
101
+ };
102
+ rimLight: {
103
+ enabled: boolean;
104
+ };
105
+ sceneShadow: {
106
+ defaultMinLight: number;
107
+ defaultStrength: number;
108
+ enabled: boolean;
109
+ eyeMinLight: number;
110
+ eyeStrength: number;
111
+ faceMinLight: number;
112
+ faceStrength: number;
113
+ shadowAreaStrength: number;
114
+ skinMinLight: number;
115
+ skinStrength: number;
116
+ };
117
+ selfShadow: {
118
+ defaultMinLight: number;
119
+ defaultStrength: number;
120
+ enabled: boolean;
121
+ eyeMinLight: number;
122
+ eyeStrength: number;
123
+ faceMinLight: number;
124
+ faceStrength: number;
125
+ hairMinLight: number;
126
+ hairStrength: number;
127
+ shadowAreaStrength: number;
128
+ skinMinLight: number;
129
+ skinStrength: number;
130
+ };
131
+ shadowColor: {
132
+ enabled: boolean;
133
+ };
134
+ skinTone: {
135
+ enabled: boolean;
136
+ };
137
+ sticker: {
138
+ enabled: boolean;
139
+ };
140
+ }>;
141
+ /**
142
+ * Vegetation shader — one registration serves the `treeShader`, `grassShader`
143
+ * and `flowerShader` scopes, which share a registry. Bands go to their
144
+ * smoothest admissible form (`bandCount` is clamped to `[2, 6]`, so 6 with full
145
+ * softness is the closest the schema gets to continuous), tints and rim fills
146
+ * go to zero, and physical transmission (`thinSurface`) and weather response
147
+ * are left exactly as authored because they are PBR, not stylization.
148
+ */
149
+ export const NEUTRAL_VEGETATION_SHADER_SETTINGS: Readonly<{
150
+ bark: {
151
+ bandCount: number;
152
+ bandSoftness: number;
153
+ emissiveStrength: number;
154
+ normalFlatness: number;
155
+ rimStrength: number;
156
+ roughness: number;
157
+ shadowFloor: number;
158
+ skyFillStrength: number;
159
+ specularStrength: number;
160
+ sunTintStrength: number;
161
+ tintStrength: number;
162
+ verticalShadeStrength: number;
163
+ };
164
+ flower: {
165
+ backlitStrength: number;
166
+ bandSoftness: number;
167
+ emissiveStrength: number;
168
+ tintStrength: number;
169
+ unlitPetalLift: number;
170
+ };
171
+ foliage: {
172
+ backlitStrength: number;
173
+ bandSoftness: number;
174
+ cardVariationStrength: number;
175
+ crestSoftness: number;
176
+ crownOcclusionStrength: number;
177
+ emissiveStrength: number;
178
+ gradientContrast: number;
179
+ gradientOffset: number;
180
+ hueShift: number;
181
+ hueVariation: number;
182
+ spriteLuminanceStrength: number;
183
+ styleColorStrength: number;
184
+ };
185
+ grass: {
186
+ backlitStrength: number;
187
+ bandSoftness: number;
188
+ colorVariationStrength: number;
189
+ emissiveStrength: number;
190
+ gustSheenStrength: number;
191
+ rootOcclusionStrength: number;
192
+ shadowFloor: number;
193
+ styleColorStrength: number;
194
+ tipDesaturation: number;
195
+ tipHueShift: number;
196
+ };
197
+ lighting: {
198
+ rimStrength: number;
199
+ shadowTintStrength: number;
200
+ skyFillStrength: number;
201
+ sunTintStrength: number;
202
+ };
203
+ stem: {
204
+ bandCount: number;
205
+ bandSoftness: number;
206
+ colorStrength: number;
207
+ emissiveStrength: number;
208
+ rimStrength: number;
209
+ shadowFloor: number;
210
+ skyFillStrength: number;
211
+ };
212
+ }>;
213
+ /**
214
+ * Grass field. SHADING KEYS ONLY — `bladesPerClump`, `clumpRadius`,
215
+ * `bladeHeightRange`, `bladeWidthRange`, `leanStrength`, every wind/gust key
216
+ * and `pushRadius` are intentionally absent so the neutral and styled halves
217
+ * grow the identical blades in the identical places with the identical motion.
218
+ */
219
+ export const NEUTRAL_GRASS_SETTINGS: Readonly<{
220
+ backlitStrength: 0;
221
+ baseColor: readonly number[];
222
+ cloudShadowStrength: 0;
223
+ groundAdoptStrength: 0;
224
+ groundAdoptTint: readonly number[];
225
+ shadowStrength: 0.5;
226
+ shadowTint: readonly number[];
227
+ tipColor: readonly number[];
228
+ washLift: 0;
229
+ washOpacity: 1;
230
+ }>;
231
+ /**
232
+ * Ground shader. Projection scales, slope thresholds and shoreline widths are
233
+ * copied from the `call_me_sensei` preset ON PURPOSE: those decide WHICH layer
234
+ * is painted WHERE and at what tiling. Keeping them equal means the neutral
235
+ * half paints the identical mask at the identical scale, and only the treatment
236
+ * differs — layer tints go neutral, macro variation and edge highlight go to
237
+ * zero, shadows lose their tint and lift, and the aerial distance tint is off.
238
+ */
239
+ export const NEUTRAL_GROUND_SHADER_SETTINGS: Readonly<{
240
+ distance: {
241
+ detailFade: number;
242
+ strength: number;
243
+ };
244
+ layers: {
245
+ brightness: number;
246
+ contrast: number;
247
+ dirtTint: number[];
248
+ grassTint: number[];
249
+ rockTint: number[];
250
+ sandTint: number[];
251
+ saturation: number;
252
+ textureStrength: number;
253
+ };
254
+ lighting: {
255
+ backShadowStrength: number;
256
+ shadowLift: number;
257
+ shadowTint: number[];
258
+ shadowTintStrength: number;
259
+ skyFillStrength: number;
260
+ sunIntensity: number;
261
+ };
262
+ macro: {
263
+ amount: number;
264
+ secondaryAmount: number;
265
+ tintStrength: number;
266
+ };
267
+ material: {
268
+ emissiveStrength: number;
269
+ metalness: number;
270
+ roughness: number;
271
+ };
272
+ projection: {
273
+ dirtScale: number;
274
+ grassScale: number;
275
+ rockScale: number;
276
+ sandScale: number;
277
+ triplanarSharpness: number;
278
+ triplanarStrength: number;
279
+ };
280
+ printResponse: {
281
+ rimLightening: number;
282
+ };
283
+ shoreline: {
284
+ autoSandStrength: number;
285
+ bandWidth: number;
286
+ softness: number;
287
+ wetBandWidth: number;
288
+ };
289
+ slope: {
290
+ autoRockStrength: number;
291
+ edgeHighlight: number;
292
+ fade: number;
293
+ noiseScale: number;
294
+ noiseStrength: number;
295
+ start: number;
296
+ };
297
+ }>;
298
+ /**
299
+ * Environment. Keeps every map-consuming and light-consuming feature on and
300
+ * turns off the five graphic ones (AO overlay, the authored left-side shade,
301
+ * sky tinting, sun boost and the untextured gradient), then flattens the
302
+ * grading parameters to unity.
303
+ */
304
+ export const NEUTRAL_ENVIRONMENT_PRESET: Readonly<{
305
+ features: Readonly<{
306
+ aoOverlay: false;
307
+ leftSideShadow: false;
308
+ skyTint: false;
309
+ sunBoost: false;
310
+ untexturedGradient: false;
311
+ }>;
312
+ parameters: Readonly<{
313
+ aoWarmth: 0;
314
+ cloudShadowStrength: 0;
315
+ directLightStrength: 1;
316
+ exposure: 1;
317
+ lightingInfluence: 1;
318
+ saturation: 1;
319
+ shadowLift: 0;
320
+ shadowTintColor: number[];
321
+ skyTintStrength: 0;
322
+ triplanarDetail: 0;
323
+ triplanarEdgeHighlight: 0;
324
+ untexturedGradientStrength: 0;
325
+ }>;
326
+ }>;
327
+ /**
328
+ * Manufactured surface. Every `*Enabled` control that adds a graphic layer goes
329
+ * to 0; source authority, normal detail, reflection probes, decals and graphics
330
+ * stay at 1 so the surface still reads as the material it actually is.
331
+ */
332
+ export const NEUTRAL_MANUFACTURED_SURFACE_SETTINGS: Readonly<{
333
+ celLightingEnabled: 0;
334
+ colorLiftEnabled: 0;
335
+ colorLiftStrength: 0;
336
+ coolShadowsEnabled: 0;
337
+ coolShadowStrength: 0;
338
+ decalStrength: 1;
339
+ edgeInkEnabled: 0;
340
+ fresnelEnabled: 0;
341
+ fresnelStrength: 0;
342
+ graphicsEnabled: 1;
343
+ highlightBandEnabled: 0;
344
+ highlightBandStrength: 0;
345
+ materialResponseEnabled: 0;
346
+ materialResponseStrength: 0;
347
+ normalDetailEnabled: 1;
348
+ paintBandsEnabled: 0;
349
+ paintExtractionEnabled: 1;
350
+ paintExtractionStrength: 1;
351
+ pastelPaletteEnabled: 0;
352
+ pastelStrength: 0;
353
+ planarSheenEnabled: 0;
354
+ planarSheenStrength: 0;
355
+ reflectionNormalEnabled: 1;
356
+ reflectionProbeLayerEnabled: 1;
357
+ reflectionSelectivityEnabled: 0;
358
+ rimEnabled: 0;
359
+ roughnessBreakupEnabled: 0;
360
+ shadowPastelEnabled: 0;
361
+ shadowPastelStrength: 0;
362
+ silhouetteInkEnabled: 0;
363
+ sourceAuthorityEnabled: 1;
364
+ sourceAuthorityStrength: 1;
365
+ viewReflectionEnabled: 1;
366
+ wearEnabled: 0;
367
+ }>;
368
+ /**
369
+ * Water. `colorTone: 'classic'` is the schema's own "palette untouched" tone —
370
+ * it hands colour back to the preset instead of force-applying the `anime`
371
+ * palette over it (see D19-005). Motion identity stays owned by the preset, so
372
+ * both halves run the same waves.
373
+ */
374
+ export const NEUTRAL_WATER_STYLE: Readonly<{
375
+ settings: Readonly<{
376
+ colorTone: "classic";
377
+ sceneShadowStrength: 1;
378
+ }>;
379
+ }>;
380
+ /**
381
+ * Sky. A restrained physical-looking gradient with the signature glow and
382
+ * saturation pulled back. Cloud coverage, scale, speed, direction and seed are
383
+ * NOT set — cloud shape is geometry, and both halves must see the same clouds.
384
+ */
385
+ export const NEUTRAL_SKY_SETTINGS: Readonly<{
386
+ cloudSeed: 7;
387
+ horizonColor: number[];
388
+ horizonScattering: 0.5;
389
+ sunGlowStrength: 0.6;
390
+ zenithColor: number[];
391
+ }>;
392
+ /** Post. Pipeline stays enabled at zero strength — same cost, no grade. */
393
+ export const NEUTRAL_POST_SETTINGS: Readonly<{
394
+ features: Readonly<{
395
+ bloom: false;
396
+ colorGrade: false;
397
+ enabled: true;
398
+ verticalGrade: false;
399
+ vignette: false;
400
+ }>;
401
+ parameters: Readonly<{
402
+ bloomStrength: 0;
403
+ bottomDark: 0;
404
+ contrast: 1;
405
+ exposure: 1;
406
+ saturation: 1;
407
+ strength: 0;
408
+ topLight: 0;
409
+ vignetteStrength: 0;
410
+ warmth: 0;
411
+ }>;
412
+ }>;
413
+ /** Portable manufactured-surface document, for the bundle's `{ document }` payload. */
414
+ export const NEUTRAL_MANUFACTURED_SURFACE_DOCUMENT: Readonly<{
415
+ description: string;
416
+ id: string;
417
+ label: string;
418
+ settings: {};
419
+ type: string;
420
+ version: number;
421
+ }>;
422
+ /**
423
+ * Per-slot coverage. `authored` slots gained a neutral counterpart here;
424
+ * `shipped` already had one; `inherited` resolves to schema defaults because
425
+ * the domain has no style registry; `excluded` has no usable neutral and says
426
+ * why. Nothing is silently missing.
427
+ */
428
+ export const NEUTRAL_STYLE_SLOT_COVERAGE: Readonly<{
429
+ cloud: Readonly<{
430
+ abSafe: true;
431
+ coverage: "inherited";
432
+ note: "There is no cloud style registry — the slot resolves to SkyParams schema defaults for every style, neutral included (see D19-006). Schema defaults ARE the un-stylized cloud.";
433
+ payload: Readonly<{
434
+ style: "neutral";
435
+ }>;
436
+ }>;
437
+ environment: Readonly<{
438
+ abSafe: true;
439
+ coverage: "authored";
440
+ registrar: "environment";
441
+ payload: Readonly<{
442
+ style: "neutral";
443
+ }>;
444
+ }>;
445
+ flowerShader: Readonly<{
446
+ abSafe: true;
447
+ coverage: "authored";
448
+ registrar: "vegetationShader";
449
+ payload: Readonly<{
450
+ style: "neutral";
451
+ }>;
452
+ }>;
453
+ grass: Readonly<{
454
+ abSafe: true;
455
+ coverage: "authored";
456
+ registrar: "grass";
457
+ payload: Readonly<{
458
+ style: "neutral";
459
+ }>;
460
+ }>;
461
+ grassShader: Readonly<{
462
+ abSafe: true;
463
+ coverage: "authored";
464
+ registrar: "vegetationShader";
465
+ payload: Readonly<{
466
+ style: "neutral";
467
+ }>;
468
+ }>;
469
+ groundShader: Readonly<{
470
+ abSafe: true;
471
+ coverage: "authored";
472
+ registrar: "groundShader";
473
+ payload: Readonly<{
474
+ style: "neutral";
475
+ }>;
476
+ }>;
477
+ lighting: Readonly<{
478
+ abSafe: false;
479
+ coverage: "excluded";
480
+ note: "Deliberately unpaired. A lighting style owns sun intensity, sun path and the day cycle, so a neutral lighting style changes LIGHT TRANSFORMS — which §11 requires both halves of a comparison to share. Neutral lighting would be unusable in the only construction it exists for.";
481
+ }>;
482
+ manufacturedSurface: Readonly<{
483
+ abSafe: true;
484
+ coverage: "authored";
485
+ note: "Carried as an inline document: the manufactured-surface slot has no style registry, so a { style } payload resolves to defaults regardless of the id.";
486
+ payload: Readonly<{
487
+ document: Readonly<{
488
+ description: string;
489
+ id: string;
490
+ label: string;
491
+ settings: {};
492
+ type: string;
493
+ version: number;
494
+ }>;
495
+ }>;
496
+ registrar: any;
497
+ }>;
498
+ post: Readonly<{
499
+ abSafe: false;
500
+ coverage: "authored";
501
+ note: "Registered and usable, but not part of an A/B: post runs over the composited frame, after both scissored renders, so it cannot differ per half. Both halves must share it — which §11 also requires (\"stable exposure\").";
502
+ payload: Readonly<{
503
+ style: "neutral";
504
+ }>;
505
+ registrar: "post";
506
+ }>;
507
+ rock: Readonly<{
508
+ abSafe: true;
509
+ coverage: "shipped";
510
+ note: "Pre-existing — registered by src/rock-shader/rockShaderSettings.js. The only domain that already had a neutral preset.";
511
+ payload: Readonly<{
512
+ style: "neutral";
513
+ }>;
514
+ }>;
515
+ sky: Readonly<{
516
+ abSafe: true;
517
+ coverage: "authored";
518
+ registrar: "sky";
519
+ payload: Readonly<{
520
+ style: "neutral";
521
+ }>;
522
+ }>;
523
+ toon: Readonly<{
524
+ abSafe: true;
525
+ coverage: "authored";
526
+ registrar: "toon";
527
+ payload: Readonly<{
528
+ style: "neutral";
529
+ }>;
530
+ }>;
531
+ treeShader: Readonly<{
532
+ abSafe: true;
533
+ coverage: "authored";
534
+ registrar: "vegetationShader";
535
+ payload: Readonly<{
536
+ style: "neutral";
537
+ }>;
538
+ }>;
539
+ water: Readonly<{
540
+ abSafe: true;
541
+ coverage: "authored";
542
+ registrar: "water";
543
+ payload: Readonly<{
544
+ style: "neutral";
545
+ }>;
546
+ }>;
547
+ }>;
548
+ /**
549
+ * The neutral counterpart of `CALL_ME_SENSEI_STYLE_BUNDLE`. Same slot ids,
550
+ * minus the two that cannot honestly carry a neutral half — so applying this
551
+ * bundle and then the Call Me Sensei bundle to the same scene produces a
552
+ * symmetric A/B in which only material treatment changed.
553
+ */
554
+ export const NEUTRAL_STYLE_BUNDLE: any;
555
+ /** The slot ids `NEUTRAL_STYLE_BUNDLE` actually carries. */
556
+ export const NEUTRAL_STYLE_SLOT_IDS: readonly string[];
557
+ /**
558
+ * Keys per domain that control geometry, density, placement, tiling, masking or
559
+ * motion. A neutral preset that touched one of these would make the two halves
560
+ * structurally different, which is the failure this whole pass exists to
561
+ * prevent. Used by {@link auditNeutralStyleShadingOnly}.
562
+ */
563
+ export const NEUTRAL_STYLE_NON_SHADING_KEYS: Readonly<{
564
+ grass: readonly string[];
565
+ groundShader: readonly string[];
566
+ sky: readonly string[];
567
+ }>;
568
+ /**
569
+ * Resolved neutral toon settings — handy for `applyToonShader(root, { settings })`
570
+ * when a host wants the neutral half without going through a bundle.
571
+ */
572
+ export const NEUTRAL_TOON_RESOLVED_SETTINGS: Readonly<{
573
+ alpha: {
574
+ blendCutoff: any;
575
+ costumeCutout: boolean;
576
+ cutoutCutoff: any;
577
+ ditherOpacity: any;
578
+ enabled: boolean;
579
+ expressionTokenCutout: boolean;
580
+ eyeHighlightOrder: any;
581
+ eyeOrder: any;
582
+ faceCutout: boolean;
583
+ hairCutout: boolean;
584
+ mapTransparentCutout: boolean;
585
+ overlayDepthWrite: boolean;
586
+ overlayOrder: any;
587
+ preserveSourceAlphaTest: boolean;
588
+ scleraOrder: any;
589
+ skinCutout: boolean;
590
+ sortOverlays: boolean;
591
+ sourceAlphaMapCutout: boolean;
592
+ sourceTransparentCutout: boolean;
593
+ transparentOverlayBlend: boolean;
594
+ transparentOpacityThreshold: any;
595
+ };
596
+ averageShadow: {
597
+ defaultMinLight: any;
598
+ defaultStrength: any;
599
+ enabled: boolean;
600
+ measuredBlend: any;
601
+ eyeMinLight: any;
602
+ eyeStrength: any;
603
+ faceMinLight: any;
604
+ faceStrength: any;
605
+ hairMinLight: any;
606
+ hairStrength: any;
607
+ skinMinLight: any;
608
+ skinStrength: any;
609
+ softness: any;
610
+ };
611
+ baseTexture: Readonly<{
612
+ customSaturation: 1;
613
+ materialColorMode: "legacy";
614
+ saturationMode: "legacy";
615
+ }> | {
616
+ customSaturation: any;
617
+ materialColorMode: any;
618
+ saturationMode: any;
619
+ };
620
+ celShade: {
621
+ bodyCelMidPoint: any;
622
+ bodyCelSoftness: any;
623
+ bodyMainLightIgnoreCelShade: any;
624
+ edgeAntiAliasStrength: any;
625
+ enabled: boolean;
626
+ };
627
+ contactShadow: {
628
+ enabled: boolean;
629
+ faceHeadUpBlend: any;
630
+ faceStrength: any;
631
+ fadeRange: any;
632
+ strength: any;
633
+ thresholdOffset: any;
634
+ width: any;
635
+ };
636
+ eyeHighlight: {
637
+ color: any;
638
+ enabled: boolean;
639
+ intensity: any;
640
+ maskChannel: any;
641
+ maskMap: any;
642
+ maskStrength: any;
643
+ power: any;
644
+ showInShadowArea: any;
645
+ sourceMaskMode: "off" | "source";
646
+ };
647
+ faceLighting: {
648
+ enabled: boolean;
649
+ faceCelMidPoint: any;
650
+ faceCelSoftness: any;
651
+ faceLocalLightLift: any;
652
+ faceMainLightIgnoreCelShade: any;
653
+ faceNormalProxyBlend: any;
654
+ faceProxyNormal: any[];
655
+ faceSceneShadowStrength: any;
656
+ faceSphereBlend: any;
657
+ headSpaceMode: any;
658
+ };
659
+ fur: {
660
+ density: any;
661
+ enabled: boolean;
662
+ gravity: any;
663
+ length: any;
664
+ materials: any[];
665
+ roles: string[];
666
+ rootOffset: any;
667
+ rootShade: any;
668
+ shellCount: number;
669
+ };
670
+ glitter: {
671
+ enabled: boolean;
672
+ intensity: any;
673
+ density: any;
674
+ size: any;
675
+ randomNormalStrength: any;
676
+ showInShadowArea: any;
677
+ uvChannel: number;
678
+ defaultIntensity: any;
679
+ eyeIntensity: any;
680
+ faceIntensity: any;
681
+ hairIntensity: any;
682
+ skinIntensity: any;
683
+ };
684
+ hairHighlight: {
685
+ materialPresets: {
686
+ byName: any;
687
+ byUuid: any;
688
+ patterns: any;
689
+ };
690
+ direction: any[];
691
+ enabled: boolean;
692
+ maskChannel: any;
693
+ maskMap: any;
694
+ maskStrength: any;
695
+ mode: "legacy" | "anisotropic";
696
+ intensity: any;
697
+ shadowFloor: any;
698
+ sideBandPower: any;
699
+ sourceMaskMode: "off" | "source";
700
+ strandPower: any;
701
+ uvBandAxis: number;
702
+ uvBandCenter: any;
703
+ uvBandHalfWidth: any;
704
+ uvPreset: string;
705
+ };
706
+ perspectiveRemoval: {
707
+ amount: any;
708
+ enabled: boolean;
709
+ endHeight: any;
710
+ radius: any;
711
+ startHeight: any;
712
+ };
713
+ sticker: {
714
+ blendMode: any;
715
+ enabled: boolean;
716
+ map: any;
717
+ offset: any[];
718
+ repeat: any[];
719
+ strength: any;
720
+ uvChannel: number;
721
+ };
722
+ indirectLight: {
723
+ ambientTint: any;
724
+ defaultIntensity: any;
725
+ defaultMinimumIndirectLight: any;
726
+ enabled: boolean;
727
+ environmentIndirectLight: any;
728
+ eyeIntensity: any;
729
+ eyeMinimumIndirectLight: any;
730
+ faceIntensity: any;
731
+ faceMinimumIndirectLight: any;
732
+ hairIntensity: any;
733
+ hairMinimumIndirectLight: any;
734
+ hemisphereLightIntensity: any;
735
+ skinIntensity: any;
736
+ skinMinimumIndirectLight: any;
737
+ };
738
+ localLights: {
739
+ defaultIntensity: any;
740
+ defaultMaxContribution: any;
741
+ defaultShadowLift: any;
742
+ enabled: boolean;
743
+ eyeIntensity: any;
744
+ eyeMaxContribution: any;
745
+ eyeShadowLift: any;
746
+ faceIntensity: any;
747
+ faceMaxContribution: any;
748
+ faceShadowLift: any;
749
+ hairIntensity: any;
750
+ hairMaxContribution: any;
751
+ hairShadowLift: any;
752
+ skinIntensity: any;
753
+ skinMaxContribution: any;
754
+ skinShadowLift: any;
755
+ };
756
+ materialMaps: {
757
+ aoMap: any;
758
+ aoStrength: any;
759
+ detailMap: any;
760
+ detailRepeat: any;
761
+ detailStrength: any;
762
+ emissiveColor: any;
763
+ emissiveMap: any;
764
+ emissiveStrength: any;
765
+ enabled: boolean;
766
+ matcapMap: any;
767
+ matcapStrength: any;
768
+ metalnessMap: any;
769
+ metalnessStrength: any;
770
+ normalMap: any;
771
+ normalScale: any;
772
+ normalStrength: any;
773
+ rampMap: any;
774
+ rampStrength: any;
775
+ roughnessMap: any;
776
+ roughnessStrength: any;
777
+ sourceMode: "off" | "source";
778
+ specularColorMap: any;
779
+ specularColorStrength: any;
780
+ };
781
+ materialRoles: any;
782
+ outline: {
783
+ defaultLightingMix: any;
784
+ defaultMaxBrightness: any;
785
+ defaultMinBrightness: any;
786
+ defaultTintColor: any;
787
+ defaultWidth: any;
788
+ depthOffset: any;
789
+ depthTest: boolean;
790
+ depthWrite: boolean;
791
+ enabled: boolean;
792
+ eyeLightingMix: any;
793
+ eyeMaxBrightness: any;
794
+ eyeMinBrightness: any;
795
+ eyeTintColor: any;
796
+ eyeWidth: any;
797
+ faceLightingMix: any;
798
+ faceMaxBrightness: any;
799
+ faceMinBrightness: any;
800
+ faceTintColor: any;
801
+ faceWidth: any;
802
+ hairCutoutWidth: any;
803
+ hairLightingMix: any;
804
+ hairMaxBrightness: any;
805
+ hairMinBrightness: any;
806
+ hairTintColor: any;
807
+ hairWidth: any;
808
+ maxWidth: any;
809
+ metalLightingMix: any;
810
+ metalMaxBrightness: any;
811
+ metalMinBrightness: any;
812
+ metalTintColor: any;
813
+ metalWidth: any;
814
+ polygonOffset: boolean;
815
+ polygonOffsetFactor: any;
816
+ polygonOffsetUnits: any;
817
+ referenceDistance: any;
818
+ referenceFov: any;
819
+ screenSpaceWidth: any;
820
+ smoothNormals: boolean;
821
+ widthFadeDistance: any;
822
+ skinLightingMix: any;
823
+ skinMaxBrightness: any;
824
+ skinMinBrightness: any;
825
+ skinTintColor: any;
826
+ skinWidth: any;
827
+ transparentOverlayWidth: any;
828
+ widthScale: any;
829
+ };
830
+ preset: any;
831
+ presetDescription: string;
832
+ presetLabel: any;
833
+ rimLight: {
834
+ blockByShadow: any;
835
+ defaultIntensity: any;
836
+ defaultTintColor: any;
837
+ depthCloseWidthReduce: any;
838
+ depthDottedLineFix: boolean;
839
+ depthFadeEndDistance: any;
840
+ depthFadeRange: any;
841
+ depthFadeStartDistance: any;
842
+ depthMask3D: boolean;
843
+ depthSafeDistance: any;
844
+ depthThresholdOffset: any;
845
+ depthWidth: any;
846
+ enabled: boolean;
847
+ eyeIntensity: any;
848
+ faceIntensity: any;
849
+ hairIntensity: any;
850
+ midPoint: any;
851
+ mixWithBaseMapColor: any;
852
+ mode: any;
853
+ skinIntensity: any;
854
+ softness: any;
855
+ };
856
+ sceneShadow: {
857
+ defaultMinLight: any;
858
+ defaultStrength: any;
859
+ enabled: boolean;
860
+ eyeMinLight: any;
861
+ eyeStrength: any;
862
+ faceMinLight: any;
863
+ faceStrength: any;
864
+ shadowAreaStrength: any;
865
+ skinMinLight: any;
866
+ skinStrength: any;
867
+ };
868
+ selfShadow: {
869
+ defaultMinLight: any;
870
+ defaultStrength: any;
871
+ enabled: boolean;
872
+ eyeMinLight: any;
873
+ eyeStrength: any;
874
+ faceMinLight: any;
875
+ faceStrength: any;
876
+ hairMinLight: any;
877
+ hairStrength: any;
878
+ shadowAreaStrength: any;
879
+ skinMinLight: any;
880
+ skinStrength: any;
881
+ sourceMode: 0 | 1 | 2;
882
+ };
883
+ shadowColor: {
884
+ enabled: boolean;
885
+ lowSaturationFallbackColor: any;
886
+ selfShadowAlbedoMulStrength: any;
887
+ selfShadowAreaHSVStrength: any;
888
+ selfShadowAreaHueOffset: any;
889
+ selfShadowAreaSaturationBoost: any;
890
+ selfShadowAreaValueMul: any;
891
+ selfShadowTintColor: any;
892
+ transitionAreaHueOffset: any;
893
+ transitionAreaIntensity: any;
894
+ transitionAreaSaturationBoost: any;
895
+ transitionAreaTintColor: any;
896
+ transitionAreaValueMul: any;
897
+ };
898
+ skinTone: {
899
+ enabled: boolean;
900
+ faceMaxDirectLight: any;
901
+ faceMinimumIndirectLight: any;
902
+ faceShadowBrightness: any;
903
+ faceShadowSaturation: any;
904
+ faceShadowTint: any;
905
+ faceShadowTintStrength: any;
906
+ skinMaxDirectLight: any;
907
+ skinMinimumIndirectLight: any;
908
+ skinShadowBrightness: any;
909
+ skinShadowSaturation: any;
910
+ skinShadowTint: any;
911
+ skinShadowTintStrength: any;
912
+ };
913
+ specular: {
914
+ defaultColor: any;
915
+ defaultIntensity: any;
916
+ defaultMidPoint: any;
917
+ defaultPower: any;
918
+ defaultRange: any;
919
+ defaultShowInShadowArea: any;
920
+ directionMode: "light" | "view";
921
+ enabled: boolean;
922
+ eyeIntensity: any;
923
+ eyeMidPoint: any;
924
+ eyePower: any;
925
+ eyeRange: any;
926
+ eyeShowInShadowArea: any;
927
+ faceIntensity: any;
928
+ hairIntensity: any;
929
+ hairPower: any;
930
+ maskChannel: any;
931
+ maskMap: any;
932
+ maskStrength: any;
933
+ metalIntensity: any;
934
+ skinIntensity: any;
935
+ sourceMaskMode: "off" | "source";
936
+ };
937
+ }>;
938
+ /** Resolved neutral environment settings, for direct `applyEnvironmentShader` use. */
939
+ export const NEUTRAL_ENVIRONMENT_RESOLVED_SETTINGS: Readonly<{
940
+ features: any;
941
+ parameters: any;
942
+ }>;
943
+ /** Resolved neutral manufactured-surface settings. */
944
+ export const NEUTRAL_MANUFACTURED_SURFACE_RESOLVED_SETTINGS: Readonly<{}>;