reze-engine 0.64.0 → 0.66.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 (173) hide show
  1. package/dist/engine.d.ts +300 -94
  2. package/dist/engine.d.ts.map +1 -1
  3. package/dist/engine.js +1628 -787
  4. package/dist/graph/compile.d.ts.map +1 -1
  5. package/dist/graph/compile.js +5 -0
  6. package/dist/graph/presets/body.d.ts.map +1 -1
  7. package/dist/graph/presets/body.js +26 -24
  8. package/dist/graph/presets/cloth_rough.js +8 -8
  9. package/dist/graph/presets/cloth_smooth.js +8 -8
  10. package/dist/graph/presets/default.js +4 -4
  11. package/dist/graph/presets/eye.js +10 -10
  12. package/dist/graph/presets/face.d.ts.map +1 -1
  13. package/dist/graph/presets/face.js +28 -26
  14. package/dist/graph/presets/hair.js +6 -6
  15. package/dist/graph/presets/metal.js +8 -8
  16. package/dist/graph/presets/stockings.d.ts.map +1 -1
  17. package/dist/graph/presets/stockings.js +4 -11
  18. package/dist/graph/presets/unlit.d.ts.map +1 -1
  19. package/dist/graph/presets/unlit.js +9 -13
  20. package/dist/graph/registry.d.ts.map +1 -1
  21. package/dist/graph/registry.js +128 -157
  22. package/dist/graph/render-class.d.ts +5 -2
  23. package/dist/graph/render-class.d.ts.map +1 -1
  24. package/dist/graph/slots.d.ts.map +1 -1
  25. package/dist/graph/slots.js +12 -2
  26. package/dist/index.d.ts +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/model.d.ts +23 -1
  29. package/dist/model.d.ts.map +1 -1
  30. package/dist/model.js +41 -1
  31. package/dist/outline-normals.d.ts +12 -0
  32. package/dist/outline-normals.d.ts.map +1 -0
  33. package/dist/outline-normals.js +100 -0
  34. package/dist/pmx-loader.d.ts +7 -0
  35. package/dist/pmx-loader.d.ts.map +1 -1
  36. package/dist/pmx-loader.js +17 -3
  37. package/dist/shaders/anchor-table.d.ts +11 -0
  38. package/dist/shaders/anchor-table.d.ts.map +1 -1
  39. package/dist/shaders/anchor-table.js +9 -3
  40. package/dist/shaders/directives.d.ts +42 -5
  41. package/dist/shaders/directives.d.ts.map +1 -1
  42. package/dist/shaders/directives.js +51 -4
  43. package/dist/shaders/lights.d.ts +11 -7
  44. package/dist/shaders/lights.d.ts.map +1 -1
  45. package/dist/shaders/lights.js +315 -271
  46. package/dist/shaders/materials/common.d.ts.map +1 -1
  47. package/dist/shaders/materials/common.js +30 -5
  48. package/dist/shaders/materials/nodes.d.ts +1 -1
  49. package/dist/shaders/materials/nodes.d.ts.map +1 -1
  50. package/dist/shaders/materials/nodes.js +191 -271
  51. package/dist/shaders/passes/bloom.d.ts +4 -3
  52. package/dist/shaders/passes/bloom.d.ts.map +1 -1
  53. package/dist/shaders/passes/bloom.js +58 -87
  54. package/dist/shaders/passes/composite.d.ts +1 -1
  55. package/dist/shaders/passes/composite.d.ts.map +1 -1
  56. package/dist/shaders/passes/composite.js +121 -77
  57. package/dist/shaders/passes/ground.js +1 -1
  58. package/dist/shaders/passes/mirror.d.ts +18 -12
  59. package/dist/shaders/passes/mirror.d.ts.map +1 -1
  60. package/dist/shaders/passes/mirror.js +59 -13
  61. package/dist/shaders/passes/outline.d.ts.map +1 -1
  62. package/dist/shaders/passes/outline.js +71 -14
  63. package/dist/shaders/passes/particles.d.ts.map +1 -1
  64. package/dist/shaders/passes/particles.js +9 -3
  65. package/dist/shaders/passes/probe.d.ts +45 -0
  66. package/dist/shaders/passes/probe.d.ts.map +1 -0
  67. package/dist/shaders/passes/probe.js +230 -0
  68. package/dist/shaders/passes/scene-contract.d.ts +13 -0
  69. package/dist/shaders/passes/scene-contract.d.ts.map +1 -1
  70. package/dist/shaders/passes/scene-contract.js +4 -0
  71. package/dist/shaders/scene-light-api.d.ts.map +1 -1
  72. package/dist/shaders/scene-light-api.js +1 -0
  73. package/dist/unity/globals.d.ts +7 -0
  74. package/dist/unity/globals.d.ts.map +1 -1
  75. package/dist/unity/globals.js +4 -3
  76. package/dist/unity/host.d.ts +18 -0
  77. package/dist/unity/host.d.ts.map +1 -1
  78. package/dist/unity/host.js +144 -70
  79. package/dist/unity/looks.d.ts +47 -0
  80. package/dist/unity/looks.d.ts.map +1 -1
  81. package/dist/unity/looks.js +150 -6
  82. package/dist/unity/skin.d.ts.map +1 -1
  83. package/dist/unity/skin.js +5 -2
  84. package/dist/unity/stage.d.ts +24 -0
  85. package/dist/unity/stage.d.ts.map +1 -1
  86. package/dist/unity/stage.js +59 -7
  87. package/package.json +1 -1
  88. package/src/engine.ts +2010 -1033
  89. package/src/graph/compile.ts +4 -0
  90. package/src/graph/presets/body.ts +26 -24
  91. package/src/graph/presets/cloth_rough.ts +8 -8
  92. package/src/graph/presets/cloth_smooth.ts +8 -8
  93. package/src/graph/presets/default.ts +4 -4
  94. package/src/graph/presets/eye.ts +10 -10
  95. package/src/graph/presets/face.ts +28 -26
  96. package/src/graph/presets/hair.ts +6 -6
  97. package/src/graph/presets/metal.ts +8 -8
  98. package/src/graph/presets/stockings.ts +4 -11
  99. package/src/graph/presets/unlit.ts +9 -13
  100. package/src/graph/registry.ts +133 -158
  101. package/src/graph/render-class.ts +5 -2
  102. package/src/graph/slots.ts +12 -2
  103. package/src/index.ts +1 -0
  104. package/src/model.ts +50 -1
  105. package/src/outline-normals.ts +110 -0
  106. package/src/pmx-loader.ts +18 -3
  107. package/src/shaders/anchor-table.ts +15 -3
  108. package/src/shaders/directives.ts +88 -6
  109. package/src/shaders/lights.ts +464 -415
  110. package/src/shaders/materials/common.ts +30 -5
  111. package/src/shaders/materials/nodes.ts +191 -271
  112. package/src/shaders/passes/bloom.ts +59 -87
  113. package/src/shaders/passes/composite.ts +121 -77
  114. package/src/shaders/passes/ground.ts +1 -1
  115. package/src/shaders/passes/mirror.ts +60 -13
  116. package/src/shaders/passes/outline.ts +71 -14
  117. package/src/shaders/passes/particles.ts +9 -3
  118. package/src/shaders/passes/probe.ts +240 -0
  119. package/src/shaders/passes/scene-contract.ts +17 -0
  120. package/src/shaders/scene-light-api.ts +1 -0
  121. package/src/unity/globals.ts +7 -3
  122. package/src/unity/host.ts +93 -20
  123. package/src/unity/looks.ts +182 -9
  124. package/src/unity/skin.ts +5 -2
  125. package/src/unity/stage.ts +66 -7
  126. package/dist/physics-debug.d.ts +0 -30
  127. package/dist/physics-debug.d.ts.map +0 -1
  128. package/dist/physics-debug.js +0 -526
  129. package/dist/shaders/agx-lut.d.ts +0 -11
  130. package/dist/shaders/agx-lut.d.ts.map +0 -1
  131. package/dist/shaders/agx-lut.js +0 -29
  132. package/dist/shaders/dfg_lut.d.ts +0 -3
  133. package/dist/shaders/dfg_lut.d.ts.map +0 -1
  134. package/dist/shaders/dfg_lut.js +0 -129
  135. package/dist/shaders/ltc_mag_lut.d.ts +0 -3
  136. package/dist/shaders/ltc_mag_lut.d.ts.map +0 -1
  137. package/dist/shaders/ltc_mag_lut.js +0 -1033
  138. package/dist/shaders/materials/body.d.ts +0 -2
  139. package/dist/shaders/materials/body.d.ts.map +0 -1
  140. package/dist/shaders/materials/body.js +0 -95
  141. package/dist/shaders/materials/cloth_rough.d.ts +0 -2
  142. package/dist/shaders/materials/cloth_rough.d.ts.map +0 -1
  143. package/dist/shaders/materials/cloth_rough.js +0 -69
  144. package/dist/shaders/materials/cloth_smooth.d.ts +0 -2
  145. package/dist/shaders/materials/cloth_smooth.d.ts.map +0 -1
  146. package/dist/shaders/materials/cloth_smooth.js +0 -61
  147. package/dist/shaders/materials/default.d.ts +0 -2
  148. package/dist/shaders/materials/default.d.ts.map +0 -1
  149. package/dist/shaders/materials/default.js +0 -43
  150. package/dist/shaders/materials/eye.d.ts +0 -2
  151. package/dist/shaders/materials/eye.d.ts.map +0 -1
  152. package/dist/shaders/materials/eye.js +0 -60
  153. package/dist/shaders/materials/face.d.ts +0 -2
  154. package/dist/shaders/materials/face.d.ts.map +0 -1
  155. package/dist/shaders/materials/face.js +0 -95
  156. package/dist/shaders/materials/hair.d.ts +0 -2
  157. package/dist/shaders/materials/hair.d.ts.map +0 -1
  158. package/dist/shaders/materials/hair.js +0 -90
  159. package/dist/shaders/materials/metal.d.ts +0 -2
  160. package/dist/shaders/materials/metal.d.ts.map +0 -1
  161. package/dist/shaders/materials/metal.js +0 -77
  162. package/dist/shaders/materials/mmd_classic.d.ts +0 -2
  163. package/dist/shaders/materials/mmd_classic.d.ts.map +0 -1
  164. package/dist/shaders/materials/mmd_classic.js +0 -66
  165. package/dist/shaders/materials/stockings.d.ts +0 -2
  166. package/dist/shaders/materials/stockings.d.ts.map +0 -1
  167. package/dist/shaders/materials/stockings.js +0 -122
  168. package/dist/shaders/passes/physics-debug.d.ts +0 -2
  169. package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
  170. package/dist/shaders/passes/physics-debug.js +0 -69
  171. package/src/shaders/agx-lut.ts +0 -30
  172. package/src/shaders/dfg_lut.ts +0 -131
  173. package/src/shaders/ltc_mag_lut.ts +0 -1035
package/dist/engine.d.ts CHANGED
@@ -51,9 +51,9 @@ export type LoadModelFromFilesOptions = {
51
51
  pmxFile?: File;
52
52
  };
53
53
  type WorldOptions = {
54
- /** Linear scene-referred color of the World Background (Blender: World > Surface > Color). */
54
+ /** Linear colour of the ambient when the World is a flat colour (Unity: Environment Lighting > Source Color). */
55
55
  color?: Vec3;
56
- /** Multiplier on world color (Blender: World > Surface > Strength). */
56
+ /** Multiplier on the ambient and the sky's reflection (Unity: the Environment Lighting intensity multiplier). */
57
57
  strength?: number;
58
58
  /**
59
59
  * A sky that changes with the direction you look: one colour overhead, one at
@@ -128,14 +128,14 @@ type ParentTrack = {
128
128
  seat: [number, number, number];
129
129
  };
130
130
  type SunOptions = {
131
- /** Linear color of the sun lamp (Blender: Light > Color). */
131
+ /** Linear colour of the main light (Unity: Light > Color). */
132
132
  color?: Vec3;
133
133
  /** The rendering layers it keys, as bits; every layer by default. A
134
134
  * directional light from setLights takes the layers the sun leaves. */
135
135
  layers?: number;
136
- /** Lamp power in Blender units (Blender: Light > Strength). */
136
+ /** Unity's light intensity: a white sun of 1 lights albedo 1:1 at N·L = 1. */
137
137
  strength?: number;
138
- /** Direction sunlight travels (points FROM sun TO scene, Blender: -light.rotation.Z). */
138
+ /** Direction sunlight travels (points FROM the sun TO the scene, Unity: the light's forward). */
139
139
  direction?: Vec3;
140
140
  /**
141
141
  * How much shadow the sun casts: 1 full, 0 none, and anything between.
@@ -222,15 +222,22 @@ type CameraOptions = {
222
222
  /** Vertical field of view in radians. */
223
223
  fov?: number;
224
224
  };
225
- /** EEVEE Bloom panel (3D Viewport > Render > Bloom). Fields map 1:1 to Blender's UI. */
225
+ /** Bloom — Aether Gazer's own (shaders/passes/bloom.ts): a soft-knee prefilter,
226
+ * a Gaussian chain down to a few pixels, and a scatter blend back up, added to
227
+ * the scene before the view transform. The defaults ARE the game. */
226
228
  export type BloomOptions = {
227
229
  enabled: boolean;
230
+ /** Brightest-channel level where the glow starts (the game's per-scene
231
+ * threshold). The soft knee is always half of it. */
228
232
  threshold: number;
229
- knee: number;
230
- radius: number;
233
+ /** 0..1, URP's Scatter: how far each level leans toward the wider one on the
234
+ * way up, as lerp(0.05, 0.95, scatter) — low is a tight halo, high a wide
235
+ * haze, and the top still keeps the finest level. 0.8 is the game's 0.77. */
236
+ scatter: number;
237
+ /** Tint on the glow; white is the game. */
231
238
  color: Vec3;
239
+ /** Multiplier on the glow added in the composite; 1 is the game. */
232
240
  intensity: number;
233
- clamp: number;
234
241
  };
235
242
  export declare const DEFAULT_BLOOM_OPTIONS: BloomOptions;
236
243
  /** Camera depth of field — a bokeh gather in the composite pass. Costs nothing
@@ -258,27 +265,27 @@ export type DepthOfFieldOptions = {
258
265
  quality: "performance" | "balanced" | "cinematic";
259
266
  };
260
267
  export declare const DEFAULT_DEPTH_OF_FIELD_OPTIONS: DepthOfFieldOptions;
261
- /** Blender Color Management / View (rendering.txt: Filmic, exposure, gamma). `look` is reserved for future curve tweaks. */
268
+ /** How the scene-linear frame becomes a display image: exposure, then a tone
269
+ * transform, then display gamma. */
262
270
  export type ViewTransformOptions = {
263
- /** Stops applied before Filmic: `linear *= 2^exposure`. */
271
+ /** Stops applied before the transform: `linear *= 2^exposure`. */
264
272
  exposure: number;
265
- /** After Filmic, display gamma (`pow(rgb, 1/gamma)`). */
273
+ /** After the transform, display gamma (`pow(rgb, 1/gamma)`). */
266
274
  gamma: number;
267
275
  /**
268
- * Which display transform the frame is formed with.
276
+ * Which display transform the frame is formed with (composite.ts, viewTransform).
269
277
  *
270
- * "standard" is Blender's Standard: the sRGB encoding and nothing else, which
271
- * is what NPR and anime work uses — the colours the graph computes are the
272
- * colours that land, with no film curve reinterpreting them. Both of the
273
- * reference Wuthering Waves projects render this way.
278
+ * "soft" — Aether Gazer's own final curve, (1 - e^(-2.5x))^1.4. The default.
279
+ * "neutral" — Unity URP's Neutral, the Khronos PBR Neutral operator: colour
280
+ * passes through until the top fifth, which rolls off.
281
+ * "aces" — Unity URP's ACES (RRT + ODT approximation from the Core RP).
282
+ * "none" — the sRGB encoding and nothing else.
274
283
  *
275
- * "filmic" is Blender 3.6's Filmic, Medium High Contrast, baked as a LUT.
276
- *
277
- * "aether-gazer" is that game's own final curve, (1 - e^(-2.5x))^1.4 — what
278
- * its scenes are graded through (composite.ts, agTransform).
284
+ * All four end in the sRGB encoding.
279
285
  */
280
- transform: "agx" | "filmic" | "standard" | "aether-gazer";
286
+ transform: ViewTransformName;
281
287
  };
288
+ export type ViewTransformName = "soft" | "neutral" | "aces" | "none";
282
289
  export declare const DEFAULT_VIEW_TRANSFORM: ViewTransformOptions;
283
290
  /** Color grading applied to the tonemapped scene (ASC CDL — see grade() in
284
291
  * composite.ts). The three tonal controls are expressed as COLORS with
@@ -371,9 +378,9 @@ export type EngineOptions = {
371
378
  /** Canvas background (display-space sRGB 0–1), composited under the scene after
372
379
  * tonemapping. Omit/null = transparent canvas (see setBackgroundColor). */
373
380
  background?: Vec3 | null;
374
- /** Initial EEVEE-style bloom; tune at runtime with `setBloomOptions`. */
381
+ /** Initial bloom; tune at runtime with `setBloomOptions`. */
375
382
  bloom?: Partial<BloomOptions>;
376
- /** View transform (exposure/gamma) applied in composite before/after Filmic. */
383
+ /** View transform (exposure, tone transform, gamma) applied in the composite. */
377
384
  view?: Partial<ViewTransformOptions>;
378
385
  onRaycast?: RaycastCallback;
379
386
  /** See {@link GizmoDragCallback}. */
@@ -545,12 +552,19 @@ interface ModelInstance {
545
552
  indexBuffer: GPUBuffer;
546
553
  jointsBuffer: GPUBuffer;
547
554
  weightsBuffer: GPUBuffer;
555
+ /** Vertex colour and second UV, per vertex — the material pipelines' slot 4.
556
+ * See createAttributeBuffer. */
557
+ attributeBuffer: GPUBuffer;
558
+ /** The outline hull's own stream — smoothed normal + PMX edge scale per
559
+ * vertex (outline-normals.ts). Made with the first edge-flagged material,
560
+ * so a model with no outline never pays for it. */
561
+ outlineVertexBuffer?: GPUBuffer;
548
562
  skinMatrixBuffer: GPUBuffer;
549
563
  drawCalls: DrawCall[];
550
564
  shadowDrawCalls: DrawCall[];
551
565
  shadowBindGroups: GPUBindGroup[];
552
566
  mainPerInstanceBindGroup: GPUBindGroup;
553
- /** Its ObjectLight — rendering layers, its own ambient — and the CPU copy it
567
+ /** Its ObjectLight — rendering layers, its own ambient, its fill — and the CPU copy it
554
568
  * is written from. Every model has one: its layers decide its lights. */
555
569
  lightBuffer: GPUBuffer;
556
570
  objectLight: Float32Array<ArrayBuffer>;
@@ -703,6 +717,17 @@ export type SceneLight = {
703
717
  * cast's key on RENDERING_LAYER_CHARACTER is how a game lights the two apart.
704
718
  */
705
719
  layers?: number;
720
+ /**
721
+ * The bulb's radius in engine units: inside it the lamp stops getting
722
+ * brighter (intensity / max(d², near²)). Omitted keeps the default small
723
+ * bulb; a large soft lamp (a game rig light's shape radius) is wider.
724
+ */
725
+ near?: number;
726
+ /**
727
+ * A spot's cookie: the key of a picture given to loadLightCookie, projected
728
+ * along the cone the way a stage light throws a gobo. Ignored on a point.
729
+ */
730
+ cookie?: string;
706
731
  };
707
732
  /**
708
733
  * Rendering layers, as the game's pipeline (URP's rendering layers) uses them:
@@ -749,11 +774,19 @@ export declare class Engine {
749
774
  private mainPipelineLayout;
750
775
  private sceneTargets;
751
776
  private sceneTargetsAdditive;
777
+ /** A group blending "premultiplied" — see scene-contract's
778
+ * material-premultiplied. */
779
+ private sceneTargetsPremultiplied;
752
780
  /** The scene pass's attachment formats, settled at init once the device has
753
781
  * said which HDR format it will blend. Every scene-pass pipeline asks
754
782
  * scene-contract for its targets against these. */
755
783
  private get sceneFormats();
756
784
  private fullVertexBufferLayouts;
785
+ /** What a MATERIAL pipeline reads: the full set, then (slot 4, past the
786
+ * outline hull's slot 3) the model's attribute stream — vertex colour and a
787
+ * second UV (see createAttributeBuffer). Only the material shaders declare
788
+ * those inputs; every other pass keeps fullVertexBufferLayouts. */
789
+ private materialVertexBufferLayouts;
757
790
  private defaultToonRampTexture;
758
791
  private groundShadowPipeline;
759
792
  /** The soft-edge variant, built the first time a scene asks for one. Null while
@@ -865,6 +898,8 @@ export declare class Engine {
865
898
  private multisampleTexture;
866
899
  private hdrResolveTexture;
867
900
  private static readonly MULTISAMPLE_COUNT;
901
+ /** Floats per vertex in a model's attribute stream: colour RGBA, then UV2. */
902
+ private static readonly ATTRIBUTE_FLOATS;
868
903
  /**
869
904
  * Shadow map depth format — 16-bit, deliberately.
870
905
  *
@@ -1194,6 +1229,9 @@ export declare class Engine {
1194
1229
  /** Where addGround put the floor. The mirror reflects across it, so a raised
1195
1230
  * floor that kept y = 0 would reflect the scene into the wrong plane. */
1196
1231
  private groundY;
1232
+ /** The built-in floor's half size on x and z — what it covers, for the
1233
+ * shadow's reach (updateShadowSceneBounds). */
1234
+ private groundHalf;
1197
1235
  private mirrorPlane;
1198
1236
  private mirrorCameraData;
1199
1237
  private mirrorCameraBuffer;
@@ -1219,6 +1257,7 @@ export declare class Engine {
1219
1257
  * premultiplied quantity and a blur has to move them together. */
1220
1258
  private mirrorMaskMipViews;
1221
1259
  private mirrorMaskBlurBindGroups;
1260
+ private mirrorDownsamplePipeline;
1222
1261
  private mirrorMaskDownsamplePipeline;
1223
1262
  /** Two blocks the ground reads its clip from: the camera's is inert, the
1224
1263
  * mirror's carries the live plane. Which one a draw sees is decided by which
@@ -1312,6 +1351,38 @@ export declare class Engine {
1312
1351
  private worldAmbientSH;
1313
1352
  private fallbackEquirectTexture;
1314
1353
  private fallbackEquirectView;
1354
+ /** The cube the materials read: 64² GGX-prefiltered down seven levels. */
1355
+ private probeTexture;
1356
+ private probeView;
1357
+ /** 1×1 black cube, bound while a probe is being captured so no material
1358
+ * reads the cube it is drawing into. */
1359
+ private probeFallbackView;
1360
+ /** The spot lamps' cookies: one picture a layer of a 512² array, made on the
1361
+ * first cookie (a 1×1 white stand-in until then), and the layer each key holds. */
1362
+ private cookieTexture;
1363
+ private cookieView;
1364
+ private cookieLayers;
1365
+ /** What setLights was last given, rewritten when a cookie it names arrives. */
1366
+ private sceneLights;
1367
+ private static readonly COOKIE_SIZE;
1368
+ private static readonly COOKIE_LAYERS;
1369
+ /** ProbeUniforms for the scene (centre + strength, box min + on-flag, box
1370
+ * max), and a zeroed copy — the off flag — for the capture's own draws. */
1371
+ private probeUniformBuffer;
1372
+ private probeOffBuffer;
1373
+ private probeData;
1374
+ /** The capture camera: CameraUniforms for one cube face at a time. */
1375
+ private probeCameraBuffer;
1376
+ private probeCameraData;
1377
+ private probeCaptureBindGroup;
1378
+ /** Set when the stage or what it wears changes; the capture runs once the
1379
+ * scene has stayed put for PROBE_SETTLE_FRAMES (see maybeCaptureProbe). */
1380
+ private probeDirty;
1381
+ private probeDirtyFrame;
1382
+ private probeFrame;
1383
+ private probeCapture;
1384
+ private static readonly PROBE_SETTLE_FRAMES;
1385
+ private skyPrefilterPipeline;
1315
1386
  /**
1316
1387
  * The scene's effects, in document order — the order they layer in.
1317
1388
  *
@@ -1394,8 +1465,6 @@ export declare class Engine {
1394
1465
  /** Trail samples owed this frame, computed once so every trail on every
1395
1466
  * character samples in lockstep and their paths stay comparable. */
1396
1467
  private trailDue;
1397
- private agxLutTexture;
1398
- private agxFallbackTexture;
1399
1468
  /** The scene's own grade (setStageGrade): the cube as handed over, kept so a
1400
1469
  * call before init() still lands, and its texture once uploaded. */
1401
1470
  private stageGradeCube;
@@ -1420,29 +1489,44 @@ export declare class Engine {
1420
1489
  private readonly pipelineDescs;
1421
1490
  private readonly singleSided;
1422
1491
  private readonly singleSidedMirror;
1492
+ /** Twins whose async build is in flight, so a draw asks for each once. */
1493
+ private readonly sidedPending;
1494
+ private readonly sidedPendingMirror;
1495
+ private readonly shaderModuleCache;
1496
+ private readonly pipelineCache;
1497
+ private readonly bindGroupLayoutCache;
1498
+ private readonly pipelineLayoutCache;
1499
+ private readonly gpuObjectIds;
1500
+ private gpuObjectNext;
1501
+ /** Init's pipelines, built async and in parallel; init awaits them. Null
1502
+ * outside init, where a pipeline job builds the way it always did. */
1503
+ private initPipelineJobs;
1423
1504
  private readonly steppedHeld;
1424
1505
  private readonly steppedTick;
1425
1506
  private steppedLastClock;
1426
- private bloomBlitUniformBuffer;
1427
- private bloomUpsampleUniformBuffer;
1428
- private readonly bloomBlitUniformData;
1429
- private readonly bloomUpsampleUniformData;
1430
- private bloomBlitPipeline;
1431
- private bloomDownsamplePipeline;
1507
+ private bloomPrefilterBindGroupLayout;
1508
+ private bloomBlurBindGroupLayout;
1509
+ /** Single-attachment pass; colorAttachments[0].view set per bloom step. */
1510
+ private bloomPassDescriptor;
1511
+ private bloomPrefilterPipeline;
1512
+ private bloomBlurHPipeline;
1513
+ private bloomBlurVPipeline;
1432
1514
  private bloomUpsamplePipeline;
1433
- private bloomBlitBindGroupLayout;
1434
- private bloomDownsampleBindGroupLayout;
1435
1515
  private bloomUpsampleBindGroupLayout;
1516
+ private bloomUniformBuffer;
1517
+ private readonly bloomUniformData;
1436
1518
  private bloomDownTexture;
1437
1519
  private bloomUpTexture;
1438
- private bloomMipCount;
1439
- private bloomDownMipViews;
1440
- private bloomUpMipViews;
1441
- private bloomBlitBindGroup;
1442
- private bloomDownsampleBindGroups;
1520
+ private bloomLevels;
1521
+ private bloomDownViews;
1522
+ private bloomUpViews;
1523
+ private bloomPrefilterBindGroup;
1524
+ private bloomBlurHBindGroups;
1525
+ private bloomBlurVBindGroups;
1443
1526
  private bloomUpsampleBindGroups;
1444
- /** Single-attachment pass; colorAttachments[0].view set per bloom step. */
1445
- private bloomPassDescriptor;
1527
+ /** The game's prefilter clamps at 6550.4 — a tenth of the half-float ceiling
1528
+ * (its BloomPass _Params.y of 100 never reaches the shader). */
1529
+ private static readonly BLOOM_CLAMP;
1446
1530
  private static readonly BLOOM_MAX_LEVELS;
1447
1531
  private groundVertexBuffer?;
1448
1532
  private groundIndexBuffer?;
@@ -1453,11 +1537,6 @@ export declare class Engine {
1453
1537
  /** The sun's shadow atlas: every cascade in its own tile (shadow-cascades.ts). */
1454
1538
  private shadowAtlasTexture;
1455
1539
  private shadowAtlasView;
1456
- private brdfLutTexture;
1457
- private brdfLutView;
1458
- private filmicLutTexture;
1459
- private filmicLutView;
1460
- private static readonly FILMIC_LUT_WIDTH;
1461
1540
  private shadowDepthPipeline;
1462
1541
  private shadowLightVPBuffer;
1463
1542
  private shadowCascadeVPBuffers;
@@ -1521,10 +1600,10 @@ export declare class Engine {
1521
1600
  private bloomSettings;
1522
1601
  private viewTransform;
1523
1602
  constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
1524
- /** Merge partial bloom with EEVEE defaults (same as constructor). */
1603
+ /** Merge partial bloom with the defaults (same as constructor). */
1525
1604
  static mergeBloomDefaults(partial?: Partial<BloomOptions>): BloomOptions;
1526
1605
  static mergeViewTransformDefaults(partial?: Partial<ViewTransformOptions>): ViewTransformOptions;
1527
- /** Current bloom settings (Blender names; tint is a copied `Vec3`). */
1606
+ /** Current bloom settings (tint is a copied `Vec3`). */
1528
1607
  getBloomOptions(): BloomOptions;
1529
1608
  getViewTransformOptions(): ViewTransformOptions;
1530
1609
  private colorGrading;
@@ -1550,7 +1629,7 @@ export declare class Engine {
1550
1629
  private uploadStageGrade;
1551
1630
  /** Current grade (for serialization into a scene descriptor). */
1552
1631
  getColorGrading(): ColorGradingOptions;
1553
- /** Sensor grain: how much, and whether it moves. */
1632
+ /** Sensor grain: how much. */
1554
1633
  private grain;
1555
1634
  /**
1556
1635
  * Film grain over the rendered scene, 0–1.
@@ -1560,17 +1639,12 @@ export declare class Engine {
1560
1639
  * a background image or a backdrop video, which arrived with grain of their
1561
1640
  * own and would be graded rather than matched by a second helping.
1562
1641
  *
1563
- * `animated` false freezes it. A still photograph's grain does not move, and
1564
- * noise crawling over a frozen picture makes the rendering look more alive
1565
- * than the thing it is standing in.
1566
- *
1567
1642
  * Costs one hash per pixel in a pass that already runs, and nothing at all at
1568
1643
  * zero — the branch is on a uniform.
1569
1644
  */
1570
- setFilmGrain(amount: number, animated?: boolean): void;
1645
+ setFilmGrain(amount: number): void;
1571
1646
  getFilmGrain(): Readonly<{
1572
1647
  amount: number;
1573
- animated: boolean;
1574
1648
  }>;
1575
1649
  setViewTransformOptions(patch: Partial<ViewTransformOptions>): void;
1576
1650
  /**
@@ -1590,6 +1664,8 @@ export declare class Engine {
1590
1664
  * it was written, expensive where it was reported.
1591
1665
  */
1592
1666
  private bloomContributes;
1667
+ /** viewU[6].y per transform — see viewTransform in composite.ts. */
1668
+ private static readonly VIEW_TRANSFORM_ID;
1593
1669
  private writeCompositeViewUniforms;
1594
1670
  /**
1595
1671
  * Set the canvas background color (display-space sRGB, 0–1 per channel — the
@@ -1767,7 +1843,7 @@ export declare class Engine {
1767
1843
  */
1768
1844
  private renderMirrorPass;
1769
1845
  /**
1770
- * Fill the mirror's mip levels — the bloom pyramid's own 13-tap downsample,
1846
+ * Fill the mirror's mip levels — a 13-tap downsample (MIRROR_DOWNSAMPLE_WGSL),
1771
1847
  * one pass per level. Only when the blur dial is up: at zero the ground
1772
1848
  * samples level 0 exactly and the chain would be work nobody reads.
1773
1849
  */
@@ -1958,7 +2034,7 @@ export declare class Engine {
1958
2034
  * whether or not it is the thing you see — and it IS the thing you see until
1959
2035
  * a backdrop is set, which is what an HDRI on its own has always done.
1960
2036
  *
1961
- * `strength` is Blender's world-strength dial and is folded into the
2037
+ * `strength` is the World's intensity and is folded into the
1962
2038
  * coefficients, so what lights her is what you see.
1963
2039
  */
1964
2040
  setWorldEquirect(source: HdrImage | null): void;
@@ -1975,7 +2051,13 @@ export declare class Engine {
1975
2051
  * lighting. Cleared, the world's own sky comes back.
1976
2052
  */
1977
2053
  setBackdropEquirect(source: ImageBitmap | HTMLImageElement | HTMLCanvasElement | null): void;
1978
- private makeCompositePipeline;
2054
+ /**
2055
+ * The scene composite's pair (gamma = 1, gamma ≠ 1), async and from the
2056
+ * shader cache. Its source depends only on which field mounts the scene
2057
+ * samples, so there are four at most, and an effect install that keeps the
2058
+ * mounts it had gets the pair already built.
2059
+ */
2060
+ private compositePipelines;
1979
2061
  /**
1980
2062
  * Install the scene's WGSL effect (shadertoy-style), rendered per-pixel in the
1981
2063
  * composite pass. ONE effect per scene, and the code says where it mounts by
@@ -2285,7 +2367,13 @@ export declare class Engine {
2285
2367
  private getModelBodyFocus;
2286
2368
  private writeDepthOfFieldUniforms;
2287
2369
  setBloomOptions(patch: Partial<BloomOptions>): void;
2370
+ private ensureBloomPipelines;
2371
+ /** The game's chain at the current canvas size (AGSimPostFX.Bloom): half
2372
+ * size, then floor(log2(longest side)) - 1 levels, each half the last. */
2373
+ private buildBloomTargets;
2288
2374
  private writeBloomUniforms;
2375
+ /** The game's chain, pass for pass (AGSimPostFX.Bloom). */
2376
+ private renderBloom;
2289
2377
  init(): Promise<void>;
2290
2378
  /** The frost tile the ground samples instead of evaluating fbm per pixel. */
2291
2379
  private groundNoiseTexture;
@@ -2300,18 +2388,8 @@ export declare class Engine {
2300
2388
  * per-pixel cost becomes a single level-0 texture read.
2301
2389
  */
2302
2390
  private bakeGroundNoise;
2303
- private bakeBrdfLut;
2304
- /**
2305
- * Decompress and upload Blender's AgX cube.
2306
- *
2307
- * Deliberately off the critical path: it is 723 KB once inflated, and a frame
2308
- * rendered before it lands should show the scene under whatever transform is
2309
- * already there rather than wait. Until then binding 10 holds a 1×1×1 stand-in,
2310
- * which is only ever sampled if someone selects AgX in that window.
2311
- */
2312
- private loadAgxLut;
2313
- private bakeFilmicLut;
2314
2391
  private createRenderPipeline;
2392
+ private renderPipelineDesc;
2315
2393
  private createPipelines;
2316
2394
  private setupResize;
2317
2395
  /** When set, render resolution is pinned to this size instead of tracking the
@@ -2573,6 +2651,41 @@ export declare class Engine {
2573
2651
  * resources are half-built, which is exactly the moment a host swaps a sky.
2574
2652
  * Retried at the top of a frame until one of them takes. */
2575
2653
  private worldBindingsDirty;
2654
+ /** Drop the capture's resources, so the next capture rebinds the sky. */
2655
+ private dropProbeCapture;
2656
+ /** Ask for a fresh capture of the stage's reflection probe. It runs at the
2657
+ * start of a frame once the scene has held still for a moment — asked for
2658
+ * by the engine itself whenever the stage or its looks change; a host may
2659
+ * call it after changing something the engine cannot see. */
2660
+ captureReflectionProbe(): void;
2661
+ /** The stage's world-space bounds: every stage model's material boxes
2662
+ * through its placement. Null without a stage. */
2663
+ private stageBounds;
2664
+ /** Run a pending capture once the scene has settled — see captureReflectionProbe. */
2665
+ private maybeCaptureProbe;
2666
+ private ensureProbeCapture;
2667
+ /**
2668
+ * Capture the probe: the stage drawn six times from one point into a 128²
2669
+ * cube, the sky laid in behind it, a mip chain, and the GGX convolution
2670
+ * into the 64² cube the materials read.
2671
+ *
2672
+ * WHERE: the middle of the stage's bounds across the floor, at about a
2673
+ * character's chest height above the floor (y = 0 where the bounds span it,
2674
+ * the MMD convention, else their bottom) — where a game puts the probe of a
2675
+ * room the player stands in. The box it projects onto is the bounds.
2676
+ *
2677
+ * WHAT: the stage alone, in its own looks, lit by the scene's sun, lamps
2678
+ * and sky as they stand. The cast is not in it (a baked probe never holds
2679
+ * the characters), nor are effects.
2680
+ */
2681
+ private renderProbe;
2682
+ /**
2683
+ * The sky's mips, convolved with the GGX lobe each stands for — the box
2684
+ * average the upload built is only the source. Level 0 is copied as it is
2685
+ * (it is also what the backdrop draws); every level below it becomes the
2686
+ * sky as a surface of that roughness reflects it (skyLevelRoughness).
2687
+ */
2688
+ private prefilterSky;
2576
2689
  /** Returns whether it actually rebuilt — see rebuildCompositeBindGroup. */
2577
2690
  private rebuildPerFrameBindGroups;
2578
2691
  /**
@@ -2583,7 +2696,6 @@ export declare class Engine {
2583
2696
  private writeWorld;
2584
2697
  /** Write sun lamp into light slot `index` (0..3). Layout mirrors the WGSL struct. */
2585
2698
  private writeSun;
2586
- /** Update the world environment (Blender: World Background). Ambient recomputes immediately. */
2587
2699
  /**
2588
2700
  * Distance fog on every lit surface, as a game on SimPipeline lays it: per
2589
2701
  * layer, t = saturate(f − (1 − f)·h) with f = saturate(depth·distance[0] +
@@ -2628,7 +2740,7 @@ export declare class Engine {
2628
2740
  */
2629
2741
  setWorldAmbient(sh: ArrayLike<number> | null): void;
2630
2742
  setWorld(options: WorldOptions): void;
2631
- /** Update the sun lamp (Blender: Light > Sun). Direction change marks shadow VP dirty. */
2743
+ /** Update the main light (Unity's directional Sun). Direction change marks shadow VP dirty. */
2632
2744
  setSun(options: SunOptions): void;
2633
2745
  getWorld(): Readonly<{
2634
2746
  color: Vec3;
@@ -2703,6 +2815,16 @@ export declare class Engine {
2703
2815
  * params make: a scene document's JSON passes straight in, and so does a
2704
2816
  * literal typed into a console. Vec3 satisfies it either way. */
2705
2817
  lights: SceneLight[] | null): void;
2818
+ /**
2819
+ * A cookie, under `key`, for every spot lamp that names it (SceneLight.cookie):
2820
+ * the picture a stage light throws through its gobo, projected along the
2821
+ * cone — its RGB is the light let through, so black blocks, white passes and
2822
+ * a colour tints. Square, stretched to 512². Up to 16 at once; loading a key
2823
+ * again replaces its picture. False when every layer is taken.
2824
+ */
2825
+ loadLightCookie(key: string, source: Blob | ImageBitmap): Promise<boolean>;
2826
+ /** Forget a cookie: lamps naming it light plainly again. */
2827
+ removeLightCookie(key: string): void;
2706
2828
  /** How many positional lights the scene is carrying. */
2707
2829
  getLightCount(): number;
2708
2830
  /** Guarded, unlike most private writers here, because its callers are not:
@@ -2875,6 +2997,26 @@ export declare class Engine {
2875
2997
  * in here. Linear radiance, strength included.
2876
2998
  */
2877
2999
  setModelAmbient(name: string, sh: ArrayLike<number> | null): boolean;
3000
+ /**
3001
+ * Light one model with more than the world gives it: a FILL, linear RGB times
3002
+ * its surface colour, added after its material graph. Null takes it away again.
3003
+ *
3004
+ * After the graph, not in its ambient: an NPR ramp reads an ambient fill as
3005
+ * light, so sliding it moved her shadows and flipped whole regions across a
3006
+ * hard step. Added after, it brightens her evenly and every shadow stays put.
3007
+ *
3008
+ * A game lights its stage and its characters apart. Aether Gazer's rooms are
3009
+ * lit by their lamps and a near-black ambient, while its characters take a
3010
+ * flat base light of their own — so a stage whose World is right for the room
3011
+ * leaves a face turned from the lamps in the dark. This is that second light,
3012
+ * for the models the host counts as cast. A model drawn by the game's own
3013
+ * shaders (src/unity) lights itself and takes none of it.
3014
+ */
3015
+ setModelFill(name: string, fill: {
3016
+ x: number;
3017
+ y: number;
3018
+ z: number;
3019
+ } | null): boolean;
2878
3020
  /** The per-model group: its skinning matrices and its ObjectLight. */
2879
3021
  private perInstanceBindGroup;
2880
3022
  removeModel(name: string): void;
@@ -3399,6 +3541,8 @@ export declare class Engine {
3399
3541
  * geometry that vanishes. One of those is a bug report.
3400
3542
  */
3401
3543
  private noteSceneExtent;
3544
+ /** Raise the scene's reach (never lower it) and hand it to the camera. */
3545
+ private raiseSceneExtent;
3402
3546
  /**
3403
3547
  * One record per model: the rigid transform its per-material boxes live under,
3404
3548
  * or the world sphere that bounds it in any pose. Written every frame, because
@@ -3618,12 +3762,26 @@ export declare class Engine {
3618
3762
  * diff them against the reference. */
3619
3763
  private readCullArgs;
3620
3764
  private setupModelInstance;
3765
+ /**
3766
+ * A model's attribute stream: vertex colour (RGBA) and a second UV set, six
3767
+ * floats a vertex, read by the material pipelines at slot 4.
3768
+ *
3769
+ * PMX has no vertex colour and one UV, but it has four ADDITIONAL UV
3770
+ * channels of four floats each, and that is where a model that needs more
3771
+ * keeps it: the first additional UV is the vertex colour, the second's xy
3772
+ * the second UV — the convention a converted game stage is written in (a
3773
+ * plant's occlusion rides in its vertex alpha, a light card's mask in its
3774
+ * second UV). A model without them reads white and its own UV, which is
3775
+ * what every graph that reads neither already assumed.
3776
+ */
3777
+ private createAttributeBuffer;
3621
3778
  private createGpuMorph;
3622
3779
  private createGroundGeometry;
3623
3780
  /** Everything about the ground's pipeline except which shadow variant it
3624
3781
  * compiles, so the two are built from one description and cannot drift. */
3625
3782
  private groundShadowPipelineDesc;
3626
3783
  private buildGroundPipeline;
3784
+ private groundPipelineConfig;
3627
3785
  private groundMirrorPipeline;
3628
3786
  private groundMirrorSoftPipeline;
3629
3787
  /** The ground's pipeline for the mirror pass, built on the first frame a
@@ -3738,25 +3896,6 @@ export declare class Engine {
3738
3896
  private renderGizmoPass;
3739
3897
  private rotateVec3ByQuat;
3740
3898
  private unproject;
3741
- /**
3742
- * Where a point on the canvas lands on a horizontal plane.
3743
- *
3744
- * `px,py` are canvas-relative pixels, top-left origin — what a pointer event
3745
- * gives you after subtracting the element's rect. Returns null when the ray
3746
- * cannot reach the plane: parallel to it, or pointing the other way, which is
3747
- * what a click on the sky above the horizon is.
3748
- *
3749
- * The one primitive a placement UI needs. Dragging a thing across the floor is
3750
- * otherwise three sliders in world units, which asks someone to guess numbers
3751
- * that have no visible relation to the picture they are looking at — and it
3752
- * throws away the property that makes pointing work at all: under perspective,
3753
- * moving something further away makes it smaller by exactly the right amount,
3754
- * so position and size stop being two controls to tune against each other.
3755
- */
3756
- groundPointAt(px: number, py: number, planeY?: number): Vec3 | null;
3757
- /** Hand the pointer to something else — a placement drag, a gizmo, a host's own
3758
- * overlay — so the orbit does not also act on it. */
3759
- setCameraInputLocked(locked: boolean): void;
3760
3899
  private buildMouseRay;
3761
3900
  private hitTestGizmo;
3762
3901
  private distSegmentRay;
@@ -3799,6 +3938,14 @@ export declare class Engine {
3799
3938
  * compile fails is not installed and its materials stay ungrouped (fallback-on-error).
3800
3939
  */
3801
3940
  applyStyleGroups(modelName: string, groups: StyleGroup[]): Promise<ApplyStyleGroupsResult>;
3941
+ /**
3942
+ * Compile style groups' pipelines before any model needs them — a scene's
3943
+ * groups while its bundle is still downloading. Installs nothing: the
3944
+ * pipelines land in the shader cache, and applyStyleGroups later finds them
3945
+ * there (or still in flight). A group that does not compile is skipped
3946
+ * silently; its real install reports it.
3947
+ */
3948
+ prewarmStyleGroups(groups: readonly StyleGroup[]): Promise<void>;
3802
3949
  /** Add or replace a single style group by id. `opts` may carry a `previewNode` for the
3803
3950
  * editor's node-output preview workflow. */
3804
3951
  upsertStyleGroup(modelName: string, group: StyleGroup, opts?: CompileOptions): Promise<ApplyStyleGroupResult>;
@@ -3918,6 +4065,39 @@ export declare class Engine {
3918
4065
  /** A pipeline whose descriptor is kept, so a single-sided twin can be built
3919
4066
  * from it on demand (see sidedPipeline). */
3920
4067
  private createModelPipeline;
4068
+ private static readonly SHADER_CACHE_MAX;
4069
+ private static readonly PIPELINE_CACHE_MAX;
4070
+ private static trimCache;
4071
+ /** A small stable id per GPU object, for cache keys. */
4072
+ private gpuObjectId;
4073
+ /** One module per WGSL source. */
4074
+ private cachedShaderModule;
4075
+ /** Drop a source whose module did not validate, so a retry reports afresh. */
4076
+ private forgetShaderModule;
4077
+ /** One bind group layout per entry list. */
4078
+ private cachedBindGroupLayout;
4079
+ /** One pipeline layout per bind group layout list. */
4080
+ private cachedPipelineLayout;
4081
+ private pipelineKey;
4082
+ private cachedPipeline;
4083
+ /** createRenderPipelineAsync, once per module + state. */
4084
+ private cachedRenderPipeline;
4085
+ /** createComputePipelineAsync, once per module + state. */
4086
+ private cachedComputePipeline;
4087
+ /**
4088
+ * A pipeline init builds: async, in parallel with the rest, and in place by
4089
+ * the time init returns (it awaits every job). Outside init — a pass built
4090
+ * on first use — it is the synchronous build it always was.
4091
+ */
4092
+ private initRenderPipeline;
4093
+ /** The compute twin of initRenderPipeline. */
4094
+ private initComputePipeline;
4095
+ /**
4096
+ * Build a model pipeline's single-sided twin off the draw path (see
4097
+ * sidedPipeline). Resolves once it is in place; never rejects — a twin that
4098
+ * fails leaves the draw on its double-sided pipeline, as before it existed.
4099
+ */
4100
+ private buildSidedTwin;
3921
4101
  /**
3922
4102
  * The pipeline a draw should use once its double-sided flag is honoured.
3923
4103
  *
@@ -3940,6 +4120,17 @@ export declare class Engine {
3940
4120
  * makes outlines compose like MMD: every material drawn later in the author's
3941
4121
  * order covers earlier hulls, and each hull sits over everything drawn before it.
3942
4122
  */
4123
+ /**
4124
+ * A stage's draws, far to near from the eye: its transparent queue, in the
4125
+ * order a game sorts one. Each draw's distance is its material box's centre,
4126
+ * placed, against the camera — a pane or a water surface is one material,
4127
+ * which is the unit a game sorts too. The array is kept per instance and
4128
+ * re-sorted in place, so an unchanged order costs a comparison per draw.
4129
+ */
4130
+ private backToFront;
4131
+ private sortedDraws;
4132
+ private sortScratch;
4133
+ private sortDistance;
3943
4134
  /** Is this draw's compiled class "hair"? Ungrouped draws never are — the
3944
4135
  * neutral pipeline is the auto class. */
3945
4136
  private isHairDraw;
@@ -3947,9 +4138,9 @@ export declare class Engine {
3947
4138
  /**
3948
4139
  * Main-pass render sequence for one model instance — babylon-mmd parity:
3949
4140
  * opaque bucket, the hair-over-eyes stencil pass, then alpha-blend materials
3950
- * in PMX author order with depth write ON (forceDepthWrite). Outlines are not
3951
- * a separate phase: drawMaterials draws each edge-flagged material's hull
3952
- * right after the material itself, like MMD's per-mesh outline stage.
4141
+ * in PMX author order with depth write ON (forceDepthWrite). Outlines close
4142
+ * each drawMaterials call: the edge-flagged materials' hulls after all of its
4143
+ * surfaces, as MMD draws a model's edges.
3953
4144
  */
3954
4145
  private setModelDrawState;
3955
4146
  /**
@@ -4115,6 +4306,21 @@ export declare class Engine {
4115
4306
  * every one still casts its shadow through the engine's pass.
4116
4307
  */
4117
4308
  setModelNativeLook(name: string, look: NativeLook | null): boolean;
4309
+ /** Resolves once a model's native look can draw: every pass's pipeline is
4310
+ * compiled (async, at setModelNativeLook). Until then its dressed materials
4311
+ * sit out — a host reveals the model after this to avoid that gap. */
4312
+ nativeLookReady(name: string): Promise<void>;
4313
+ /**
4314
+ * Set some of the values of one material a model's native look dresses —
4315
+ * its Unity material properties by name, colours linear, as the look's
4316
+ * `values` hold them — over the look's own, until set again. What a game
4317
+ * animates on a material over a take (its timeline's material curves)
4318
+ * reaches the shaders this way, one frame at a time: the caller samples its
4319
+ * keys on its own clock and sets what it got. Only the names the material's
4320
+ * look carries are taken, and a value equal to the one in place writes
4321
+ * nothing. False when the model wears no look dressing that material.
4322
+ */
4323
+ setModelNativeUniforms(name: string, material: string, values: Record<string, number | ArrayLike<number>>): boolean;
4118
4324
  /** The hosts for the game's shaders: the scene pass's and the shadow atlas's,
4119
4325
  * with the stand-ins an empty slot reads. Built on first use. */
4120
4326
  private ensureNativeHosts;