@babylonjs/lite 1.11.0 → 1.13.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 (105) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/index.js +444 -368
  3. package/dist/index.js.map +1 -1
  4. package/index.d.ts +208 -6
  5. package/lib/asset-container.js.map +1 -1
  6. package/lib/audio/index.js +1 -0
  7. package/lib/audio/index.js.map +1 -1
  8. package/lib/audio/media-stream-output.js +44 -0
  9. package/lib/audio/media-stream-output.js.map +1 -0
  10. package/lib/engine/engine.js +1 -1
  11. package/lib/frame-graph/render-task.js +1 -1
  12. package/lib/frame-graph/render-task.js.map +1 -1
  13. package/lib/frame-graph/shadow-inputs.js +10 -1
  14. package/lib/frame-graph/shadow-inputs.js.map +1 -1
  15. package/lib/frame-graph/transmission.js +1 -16
  16. package/lib/frame-graph/transmission.js.map +1 -1
  17. package/lib/index.js +6 -3
  18. package/lib/index.js.map +1 -1
  19. package/lib/loader-gltf/gltf-json-asset.js +1 -1
  20. package/lib/loader-gltf/gltf-json-asset.js.map +1 -1
  21. package/lib/loader-gltf/gltf-multi-buffer.js +2 -10
  22. package/lib/loader-gltf/gltf-multi-buffer.js.map +1 -1
  23. package/lib/loader-gltf/gltf-pbr-builder-ext.js +4 -18
  24. package/lib/loader-gltf/gltf-pbr-builder-ext.js.map +1 -1
  25. package/lib/loader-gltf/gltf-pbr-builder.js +17 -14
  26. package/lib/loader-gltf/gltf-pbr-builder.js.map +1 -1
  27. package/lib/loader-gltf/gltf-sampler-desc.js +3 -16
  28. package/lib/loader-gltf/gltf-sampler-desc.js.map +1 -1
  29. package/lib/material/node/blocks/ambient-occlusion-block.js +1 -4
  30. package/lib/material/node/blocks/ambient-occlusion-block.js.map +1 -1
  31. package/lib/material/node/blocks/biplanar-block.js +3 -6
  32. package/lib/material/node/blocks/biplanar-block.js.map +1 -1
  33. package/lib/material/node/blocks/image-source.js +2 -5
  34. package/lib/material/node/blocks/image-source.js.map +1 -1
  35. package/lib/material/node/blocks/input-block.js +5 -26
  36. package/lib/material/node/blocks/input-block.js.map +1 -1
  37. package/lib/material/node/blocks/pbr-mr-helper-full.js +5 -8
  38. package/lib/material/node/blocks/pbr-mr-helper-full.js.map +1 -1
  39. package/lib/material/node/blocks/reflection-texture-block.js +1 -4
  40. package/lib/material/node/blocks/reflection-texture-block.js.map +1 -1
  41. package/lib/material/node/blocks/texture-block.js +2 -5
  42. package/lib/material/node/blocks/texture-block.js.map +1 -1
  43. package/lib/material/node/blocks/triplanar-block.js +3 -6
  44. package/lib/material/node/blocks/triplanar-block.js.map +1 -1
  45. package/lib/material/node/node-emitter.js +24 -1
  46. package/lib/material/node/node-emitter.js.map +1 -1
  47. package/lib/material/node/node-geometry-renderable.js +2 -2
  48. package/lib/material/node/node-material.js +1 -22
  49. package/lib/material/node/node-material.js.map +1 -1
  50. package/lib/material/node/node-types.js.map +1 -1
  51. package/lib/material/pbr/fragments/shadow-only-fragment.js +68 -0
  52. package/lib/material/pbr/fragments/shadow-only-fragment.js.map +1 -0
  53. package/lib/material/pbr/pbr-flag-bits.js.map +1 -1
  54. package/lib/material/pbr/pbr-material.js.map +1 -1
  55. package/lib/material/pbr/pbr-primitive-resolver.js +2 -2
  56. package/lib/material/pbr/pbr-primitive-resolver.js.map +1 -1
  57. package/lib/material/pbr/pbr-renderable.js +3 -0
  58. package/lib/material/pbr/pbr-renderable.js.map +1 -1
  59. package/lib/material/pbr/pbr-template.js +1 -0
  60. package/lib/material/pbr/pbr-template.js.map +1 -1
  61. package/lib/mesh/GaussianSplatting/gaussian-splatting-mesh.js +2 -8
  62. package/lib/mesh/GaussianSplatting/gaussian-splatting-mesh.js.map +1 -1
  63. package/lib/mesh/get-mesh-geometry.js +24 -0
  64. package/lib/mesh/get-mesh-geometry.js.map +1 -0
  65. package/lib/mesh/mesh-dispose.js +2 -0
  66. package/lib/mesh/mesh-dispose.js.map +1 -1
  67. package/lib/mesh/mesh.js +2 -8
  68. package/lib/mesh/mesh.js.map +1 -1
  69. package/lib/mesh/thin-instance-cull-binding.js +54 -3
  70. package/lib/mesh/thin-instance-cull-binding.js.map +1 -1
  71. package/lib/mesh/thin-instance-gpu-culling.js +241 -24
  72. package/lib/mesh/thin-instance-gpu-culling.js.map +1 -1
  73. package/lib/mesh/thin-instance.js +112 -1
  74. package/lib/mesh/thin-instance.js.map +1 -1
  75. package/lib/picking/gpu-picker.js +4 -2
  76. package/lib/picking/gpu-picker.js.map +1 -1
  77. package/lib/picking/picking-pipeline.js +1 -1
  78. package/lib/picking/picking-pipeline.js.map +1 -1
  79. package/lib/picking/picking-shader.js +38 -16
  80. package/lib/picking/picking-shader.js.map +1 -1
  81. package/lib/scene/scene-core.js +7 -2
  82. package/lib/scene/scene-core.js.map +1 -1
  83. package/lib/scene/scene-node.js +2 -6
  84. package/lib/scene/scene-node.js.map +1 -1
  85. package/lib/scene/scene-remove.js +70 -1
  86. package/lib/scene/scene-remove.js.map +1 -1
  87. package/lib/scene/transform-node.js +3 -0
  88. package/lib/scene/transform-node.js.map +1 -1
  89. package/lib/scene/world-matrix-state.js +7 -1
  90. package/lib/scene/world-matrix-state.js.map +1 -1
  91. package/lib/shadow/csm-directional-shadow-generator.js +22 -1
  92. package/lib/shadow/csm-directional-shadow-generator.js.map +1 -1
  93. package/lib/shadow/csm-shadow-task-hooks.js +19 -11
  94. package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
  95. package/lib/shadow/esm-directional-shadow-generator.js +2 -51
  96. package/lib/shadow/esm-directional-shadow-generator.js.map +1 -1
  97. package/lib/shadow/pcf-directional-shadow-generator.js +2 -48
  98. package/lib/shadow/pcf-directional-shadow-generator.js.map +1 -1
  99. package/lib/shadow/shadow-base.js +48 -1
  100. package/lib/shadow/shadow-base.js.map +1 -1
  101. package/lib/text/text-renderable.js +2 -10
  102. package/lib/text/text-renderable.js.map +1 -1
  103. package/lib/texture/texture-array.js +96 -0
  104. package/lib/texture/texture-array.js.map +1 -0
  105. package/package.json +3 -3
package/index.d.ts CHANGED
@@ -594,6 +594,14 @@ export declare interface ArcRotateInterpolationOptions {
594
594
  interpolationFactor?: number;
595
595
  }
596
596
 
597
+ /** Per-layer upload options for `uploadImageToArrayLayer()` / `loadImageToArrayLayer()`. */
598
+ export declare interface ArrayLayerUploadOptions {
599
+ /** Flip Y during upload. Default true (matches Babylon.js convention). */
600
+ invertY?: boolean;
601
+ /** Treat the destination as premultiplied-alpha. Default false (straight RGBA). */
602
+ premultiplyAlpha?: boolean;
603
+ }
604
+
597
605
  /**
598
606
  * Result returned by loadGltf / loadBabylon.
599
607
  * Pass directly to addToScene() — it handles all fields automatically.
@@ -853,6 +861,11 @@ export declare interface AudioEngine {
853
861
  /** Fires on every qualifying user gesture (click), not just the first. */
854
862
  readonly onUserGesture: AudioSignal<void>;
855
863
 
864
+ /** Pure-state handle for a MediaStream carrying the audio engine's final master mix. */
865
+ export declare interface AudioEngineMediaStream {
866
+ /** One live audio track containing the post-master engine output. */
867
+ readonly stream: MediaStream;
868
+
856
869
  /** Options for {@link createAudioEngineAsync}. */
857
870
  export declare interface AudioEngineOptions {
858
871
  /**
@@ -1552,6 +1565,11 @@ export declare function clearSprite2DLayer(layer: Sprite2DLayer): void;
1552
1565
  */
1553
1566
  export declare function clearSpriteAnimations(manager: SpriteAnimationManager): void;
1554
1567
 
1568
+ /** Dissolve a `setThinInstanceLodPartner` pairing: `fullMesh` culling reverts to its single-bucket output and
1569
+ * the former partner returns to independent rendering (drawing its own instance count again after the next
1570
+ * renderable rebuild; GPU culling auto-enabled by the pairing is switched back off). */
1571
+ export declare function clearThinInstanceLodPartner(fullMesh: Mesh): void;
1572
+
1555
1573
  /** A clipping plane expressed as the coefficients `[a, b, c, d]` of `a·x + b·y + c·z + d`. */
1556
1574
  export declare type ClipPlane = readonly [number, number, number, number];
1557
1575
 
@@ -1830,6 +1848,14 @@ export declare function createAudioBusAsync(engine: AudioEngine, name: string, o
1830
1848
  */
1831
1849
  export declare function createAudioEngineAsync(options?: AudioEngineOptions): Promise<AudioEngine>;
1832
1850
 
1851
+ /**
1852
+ * Mirrors an engine's final master output into a MediaStream.
1853
+ *
1854
+ * Real-time Web Audio is required because OfflineAudioContext has no
1855
+ * MediaStream destination. The engine's audible destination remains connected.
1856
+ */
1857
+ export declare function createAudioEngineMediaStream(engine: AudioEngine): AudioEngineMediaStream;
1858
+
1833
1859
  /**
1834
1860
  * Creates a real-time visualizer that taps the host's analyzer and draws to the
1835
1861
  * given canvas. Enables the analyzer on the host if it is not already enabled.
@@ -2844,6 +2870,36 @@ export declare function createTextRenderable(data: TextData, options?: TextRende
2844
2870
  * @returns A rendering context that can be registered with the engine. */
2845
2871
  export declare function createTextRenderer(surface: SurfaceContext, opts: TextRendererOptions): TextRenderer;
2846
2872
 
2873
+ /**
2874
+ * Create an empty 2D texture array of `layers` same-size RGBA8 layers, ready to
2875
+ * be filled with `uploadImageToArrayLayer()` / `loadImageToArrayLayer()`.
2876
+ *
2877
+ * The texture is created with `TEXTURE_BINDING | COPY_DST | RENDER_ATTACHMENT`
2878
+ * usage — `copyExternalImageToTexture` (used by the upload helpers) requires
2879
+ * both `COPY_DST` and `RENDER_ATTACHMENT` on the destination, and the render
2880
+ * attachment is also what the mipmap-blit pass writes into.
2881
+ *
2882
+ * @param engine - Engine context.
2883
+ * @param width - Layer width in texels (\>= 1).
2884
+ * @param height - Layer height in texels (\>= 1).
2885
+ * @param layers - Number of array layers (\>= 1).
2886
+ * @param options - Sampler / format overrides.
2887
+ */
2888
+ export declare function createTexture2DArray(engine: EngineContext, width: number, height: number, layers: number, options?: TextureArrayOptions): Texture2DArray;
2889
+
2890
+ /**
2891
+ * Create a 2D texture array and populate every layer from a list of image URLs
2892
+ * — one URL per layer, in order. All images must decode to the same dimensions
2893
+ * (the array's `width`/`height` are taken from the first). This is the
2894
+ * highest-level, most ergonomic entry point.
2895
+ *
2896
+ * @param engine - Engine context.
2897
+ * @param urls - One image URL per layer (`urls.length` \>= 1).
2898
+ * @param options - Sampler / format overrides.
2899
+ * @returns A promise resolving to the populated `Texture2DArray`.
2900
+ */
2901
+ export declare function createTexture2DArrayFromUrls(engine: EngineContext, urls: readonly [string, ...string[]], options?: TextureArrayOptions): Promise<Texture2DArray>;
2902
+
2847
2903
  /**
2848
2904
  * Create a `Texture2D` from a tightly-packed RGBA8 byte buffer.
2849
2905
  *
@@ -3228,6 +3284,12 @@ export declare function disposeAudioBus(bus: AudioBus): void;
3228
3284
  */
3229
3285
  export declare function disposeAudioEngine(engine: AudioEngine): void;
3230
3286
 
3287
+ /**
3288
+ * Disconnects a media-stream tap and stops every track owned by its stream.
3289
+ * Safe to call more than once.
3290
+ */
3291
+ export declare function disposeAudioEngineMediaStream(output: AudioEngineMediaStream): void;
3292
+
3231
3293
  /**
3232
3294
  * Stops the render loop and releases the visualizer. The underlying analyzer tap
3233
3295
  * stays on the host (dispose the host to release it).
@@ -4279,6 +4341,18 @@ export declare function getClosestPoint(plugin: NavigationPlugin, position: Vec3
4279
4341
  */
4280
4342
  export declare function getContainerMeshes(container: AssetContainer): Mesh[];
4281
4343
 
4344
+ /**
4345
+ * Returns the borrowed depth-array texture wrapper used by a custom CSM receiver.
4346
+ *
4347
+ * The wrapper shares the generator's texture and comparison sampler, is cached per
4348
+ * generator, and remains valid for the generator's lifetime. Callers must not dispose
4349
+ * or release it independently.
4350
+ *
4351
+ * @param sg - A cascaded-shadow generator from {@link createCsmDirectionalShadowGenerator}.
4352
+ * @returns A stable `Texture2D` with a 2d-array depth view.
4353
+ */
4354
+ export declare function getCsmReceiverTexture(sg: ShadowGenerator): Texture2D;
4355
+
4282
4356
  /** Returns the render-target aspect ratio adjusted for the camera's normalized viewport, or the raw ratio if none. */
4283
4357
  export declare function getEffectiveAspectRatio(camera: Camera | null | undefined, targetWidth: number, targetHeight: number): number;
4284
4358
 
@@ -4354,6 +4428,18 @@ export declare function getMasterVolume(engine: AudioEngine): number;
4354
4428
  * values above as the documented set to match against. */
4355
4429
  export declare function getMaterialFamily(material: Material): string | undefined;
4356
4430
 
4431
+ /** Return caller-owned copies of the CPU geometry retained by a mesh.
4432
+ * Returns `null` when positions, normals, or indices are unavailable. */
4433
+ export declare function getMeshGeometry(mesh: Mesh): {
4434
+ positions: Float32Array;
4435
+ normals: Float32Array;
4436
+ indices: Uint32Array;
4437
+ uvs?: Float32Array;
4438
+ uvs2?: Float32Array;
4439
+ tangents?: Float32Array;
4440
+ colors?: Float32Array;
4441
+ } | null;
4442
+
4357
4443
  /** Get the current seed used by Recast's randomized queries. */
4358
4444
  export declare function getNavigationRandomSeed(plugin: NavigationPlugin): number;
4359
4445
 
@@ -5088,6 +5174,20 @@ export declare function loadGltf(engine: EngineContext, source: string | ArrayBu
5088
5174
  */
5089
5175
  export declare function loadHdrEnvironment(scene: SceneContext, url: string, options?: HdrLoadOptions): Promise<EnvironmentTextures>;
5090
5176
 
5177
+ /**
5178
+ * Fetch an image from `url`, decode it to an `ImageBitmap`, and upload it into
5179
+ * `layer` of a texture array. This is the optional URL-loading counterpart to
5180
+ * `uploadImageToArrayLayer()`; keeping it a separate function means apps that
5181
+ * already hold a decoded source never pull in the fetch/decode path.
5182
+ *
5183
+ * @param engine - Engine context.
5184
+ * @param tex - Target texture array (from `createTexture2DArray`).
5185
+ * @param layer - Destination layer index in `[0, tex.layers)`.
5186
+ * @param url - Image URL to fetch and decode.
5187
+ * @param opts - Flip-Y / premultiply overrides.
5188
+ */
5189
+ export declare function loadImageToArrayLayer(engine: EngineContext, tex: Texture2DArray, layer: number, url: string, opts?: ArrayLayerUploadOptions): Promise<void>;
5190
+
5091
5191
  /** Fetch and decode a standalone KTX2 (Basis Universal) texture from a URL into a Texture2D, transcoded to the
5092
5192
  * device's best GPU-compressed format (BC7/ETC2/ASTC) so it STAYS compressed in VRAM (a few times less than the
5093
5193
  * uncompressed RGBA8 `loadTexture2D` always uploads). Mirrors `loadKtxTexture2D` (KTX1) for app textures that
@@ -5571,6 +5671,10 @@ declare interface NodeEmitContext {
5571
5671
  readonly temp: (state: NodeBuildState, prefix?: string) => string;
5572
5672
  /** Cast a typed expression to a target WGSL type when the shapes differ. */
5573
5673
  readonly cast: (value: NodeExpr, target: NodeValueType) => NodeExpr;
5674
+ /** Sanitize a block/input name for use as a WGSL identifier. */
5675
+ readonly sanitize: (name: string) => string;
5676
+ /** Map Babylon.js connection-point flags to Lite's node value types. */
5677
+ readonly bjsTypeToNodeType: (type: number, source?: string) => NodeValueType;
5574
5678
  /** Access the surrounding graph (so emitters can find upstream blocks). */
5575
5679
  readonly graph: NodeGraph;
5576
5680
 
@@ -6080,7 +6184,27 @@ export declare interface PbrMaterialProps extends Material {
6080
6184
  /** Linear-RGB tint applied to baseColor when `unlit` is true (i.e. glTF
6081
6185
  * `baseColorFactor`). When omitted or [1,1,1], no tint is applied.
6082
6186
  * Only bundled/bound when the unlit extension is active. */
6083
- unlitColor?: [number, number, number];
6084
6187
  /** Optional stencil-test state baked into the main-pass pipeline. Lets this material write the stencil buffer
6188
+ unlitColor?: [number, number, number];
6189
+ /** When true, the material is a shadow-only receiver: the surface is invisible
6190
+ * except where a shadow is cast on it, where it appears in `shadowOnlyColor` (or
6191
+ * black when omitted). Mirrors BJS `BackgroundMaterial.shadowOnly`. Requires
6192
+ * `receiveShadows` on the mesh and at least one shadow-casting light in the scene.
6193
+ * Implies alpha-blended rendering. Only bundled/bound when at least one mesh in
6194
+ * the scene uses it. */
6195
+ shadowOnly?: boolean;
6196
+ /** Linear-RGB color shown where the shadow falls when `shadowOnly` is true.
6197
+ * Defaults to black (`[0, 0, 0]`). */
6198
+ shadowOnlyColor?: [number, number, number];
6199
+ /** Maximum opacity at the darkest part of the shadow (when `shadowOnly` is true).
6200
+ * Range [0, 1]. Default 1.0 (fully opaque at full shadow). Lower values produce
6201
+ * a lighter, more transparent shadow. Mirrors the `shadowLevel` parameter on BJS
6202
+ * `BackgroundMaterial.shadowOnly`. */
6203
+ shadowOnlyOpacity?: number;
6204
+ /** Falloff sharpness for the shadow's soft edges (when `shadowOnly` is true).
6205
+ * Default 1.0 (the natural ESM/PCF falloff from the shadow generator). Higher
6206
+ * values steepen the falloff (saturating closer to the model silhouette), giving
6207
+ * crisper visible edges. Mathematically: `alpha = saturate((1 - shadowFactor) * falloff) * opacity`. */
6208
+ shadowOnlyFalloff?: number;
6085
6209
  /** Optional stencil-test state baked into the main-pass pipeline. Lets this material write the stencil buffer
6086
6210
  * where it draws (mask) or discard where another material wrote it. Default none. See `StencilState`. */
6087
6211
  stencil?: StencilState;
6088
6212
  }
@@ -6548,9 +6672,11 @@ export declare interface PickOptions {
6548
6672
  *
6549
6673
  * `fn shouldDiscardPick(input: PickDiscardInput) -> bool`
6550
6674
  *
6551
- * The input exposes only generic picker data: `worldPos`, `pickId`, `thinInstanceIndex`,
6552
- * `hasThinInstance`, and `instanceExtras` (the original thin-instance matrix w lanes, zero for
6553
- * non-instanced meshes). Storage entries are uploaded and bound by Lite for the current pick only. */
6675
+ * The input exposes only generic picker data: `worldPos`, `fragmentCoord` (the selected pixel
6676
+ * centre in the original backing framebuffer), `pickId`, `thinInstanceIndex`,
6677
+ * `hasThinInstance`, and `instanceExtras` (the
6678
+ * original thin-instance matrix w lanes, zero for non-instanced meshes). Storage entries are
6679
+ * uploaded and bound by Lite for the current pick only. */
6554
6680
  discard?: PickDiscardRule;
6555
6681
  /** Dev-only diagnostics: logs the pick ray, pixel, pick id/depth and resolved mesh. */
6556
6682
  debugLabel?: string;
@@ -7220,9 +7346,12 @@ export declare function removeBillboardSprite(handle: BillboardSpriteHandle): vo
7220
7346
  */
7221
7347
  export declare function removeBillboardSpriteIndex(system: BillboardSpriteSystem, index: number): void;
7222
7348
 
7223
- /** Remove a mesh from the scene and destroy its GPU resources.
7349
+ /** Remove an entity from the scene, undoing what `addToScene` did. Accepts the same
7350
+ * union as {@link addToScene}: a Mesh, light, camera, shadow generator, transform node,
7351
+ * or a whole AssetContainer. Safe to call more than once (idempotent).
7352
+ *
7224
7353
  * Standalone function for tree-shaking — only included when actually used. */
7225
- export declare function removeFromScene(scene: SceneContext, mesh: Mesh): void;
7354
+ export declare function removeFromScene(scene: SceneContext, entity: Mesh | LightBase | Camera | ShadowGenerator | TransformNode | AssetContainer): void;
7226
7355
 
7227
7356
  /**
7228
7357
  * Remove one logical hierarchy instance with O(1) swap-remove semantics.
@@ -8164,6 +8293,18 @@ export declare function setShaderUniform(material: ShaderMaterial, name: string,
8164
8293
  /** Set a declared `vec3<f32>` uniform. Convenience wrapper over `setShaderUniform()`. */
8165
8294
  export declare function setShaderVector3(material: ShaderMaterial, name: string, value: readonly [number, number, number]): void;
8166
8295
 
8296
+ /**
8297
+ * Cap the cascades a caster mesh renders into: the mesh casts only into cascade layers `0..maxCascade`
8298
+ * (0 = the nearest). Lets a scene keep small casters out of the far cascades, where their shadows are
8299
+ * sub-texel anyway — each excluded layer saves that caster's draw + pipeline switch per frame.
8300
+ *
8301
+ * Unset (the default) casts into every cascade. Pass `Infinity` to restore that.
8302
+ * The cap is read when a generator's caster set is (re)supplied through
8303
+ * {@link setShadowTaskCasterMeshes}; to change it for an already-registered caster, re-supply the
8304
+ * caster list (a new array) afterwards. Non-cascaded (single-map) generators ignore the cap.
8305
+ */
8306
+ export declare function setShadowCasterMaxCascade(mesh: Mesh, maxCascade: number): void;
8307
+
8167
8308
  /** Register scene-owned shadow caster inputs for a generator. */
8168
8309
  export declare function setShadowTaskCasterMeshes(shadowGenerator: ShadowGenerator, casterMeshes: readonly Mesh[]): void;
8169
8310
 
@@ -8366,6 +8507,17 @@ export declare function setThinInstanceCullBoundsPad(mesh: Mesh, pad: number): v
8366
8507
  * must have completed an initial full-capacity GPU synchronization. */
8367
8508
  export declare function setThinInstanceDrawCount(mesh: Mesh, count: number): void;
8368
8509
 
8510
+ /** Pair a GPU-culled thin-instanced mesh with a lower-detail partner: when `fullMesh`'s compute cull runs,
8511
+ * in-frustum instances closer than `options.distance` keep drawing through `fullMesh` while farther ones are
8512
+ * compacted into a second bucket drawn by `lodMesh` instead. `lodMesh` must be a normal scene mesh sharing the
8513
+ * same thin-instance matrix layout (it may reference the same matrices array); while paired it draws ONLY the
8514
+ * far bucket — never its own instance count — so when culling is disabled, unavailable, or the instance count
8515
+ * is 0, `fullMesh` falls back to drawing ALL instances and `lodMesh` draws nothing. `options.band` dithers the
8516
+ * threshold per instance by ±band/2 via a deterministic hash of the instance index. Like
8517
+ * `enableThinInstanceGpuCulling`, call after `setThinInstances()` and before `registerScene()`;
8518
+ * `distance`/`band` may be re-set live by calling again with the same pair. */
8519
+ export declare function setThinInstanceLodPartner(fullMesh: Mesh, lodMesh: Mesh, options: ThinInstanceLodPartnerOptions): void;
8520
+
8369
8521
  /** Update one instance's matrix. */
8370
8522
  export declare function setThinInstanceMatrix(mesh: Mesh, index: number, matrix: Mat4): void;
8371
8523
 
@@ -9793,6 +9945,15 @@ export declare interface Texture2D {
9793
9945
  * in-place row flipping is impractical) remain correct. */
9794
9946
  invertY?: boolean;
9795
9947
 
9948
+ /** A 2D texture array handle. It is a `Texture2D` (so it drops straight into
9949
+ * `setEffectTexture` / material sampler bindings) whose `view` is created with
9950
+ * `dimension:"2d-array"`, plus a `layers` count. Bind it to a shader sampler
9951
+ * declared `viewDimension:"2d-array"` and sample it in WGSL as
9952
+ * `texture_2d_array<f32>`. */
9953
+ export declare interface Texture2DArray extends Texture2D {
9954
+ layers: number;
9955
+ }
9956
+
9796
9957
  /** Sampler, format, and decode options for `loadTexture2D()`. */
9797
9958
  export declare interface Texture2DOptions {
9798
9959
  /** Generate mipmaps. Default true. */
@@ -9823,6 +9984,23 @@ export declare type Texture3D = Texture2D & {
9823
9984
  depth: number;
9824
9985
  };
9825
9986
 
9987
+ /** Sampler and format options for `createTexture2DArray()`. */
9988
+ export declare interface TextureArrayOptions {
9989
+ /** Generate a full mip chain for each layer on upload. Default true. */
9990
+ mipMaps?: boolean;
9991
+ /** Use sRGB format (rgba8unorm-srgb) so the hardware converts to linear on
9992
+ * sample. Use for color/albedo layers in PBR workflows. Default false. */
9993
+ srgb?: boolean;
9994
+ /** Address mode U. Default 'repeat'. */
9995
+ addressModeU?: GPUAddressMode;
9996
+ /** Address mode V. Default 'repeat'. */
9997
+ addressModeV?: GPUAddressMode;
9998
+ /** Min filter. Default 'linear'. */
9999
+ minFilter?: GPUFilterMode;
10000
+ /** Mag filter. Default 'linear'. */
10001
+ magFilter?: GPUFilterMode;
10002
+ }
10003
+
9826
10004
  /** Thickness sub-feature. Controls how thick the material is at each point. */
9827
10005
  export declare interface ThicknessProps {
9828
10006
  /** Thickness map texture. R channel is sampled by default (matches
@@ -9849,6 +10027,14 @@ export declare interface ThinInstanceData {
9849
10027
  count: number;
9850
10028
  /** Optional per-instance RGBA colors (4 floats per instance). */
9851
10029
  colors?: Float32Array | null;
9852
10030
 
10031
+ /** Options for `setThinInstanceLodPartner`. */
10032
+ export declare interface ThinInstanceLodPartnerOptions {
10033
+ /** Camera distance (world units) at which an in-frustum instance switches from `fullMesh` to the LOD partner. */
10034
+ distance: number;
10035
+ /** Width (world units) of a per-instance threshold dither window centered on `distance` (default 0 — hard cut). */
10036
+ band?: number;
10037
+ }
10038
+
9853
10039
  /** Tint sub-feature. Controls absorption tint color for transmittance. */
9854
10040
  export declare interface TintProps {
9855
10041
  /** Tint color (linear RGB). Default [1,1,1]. */
@@ -10201,6 +10387,22 @@ export declare function updateTextData(data: TextData, update: TextDataUpdate):
10201
10387
  */
10202
10388
  export declare function updateTexture2DFromPixels(engine: EngineContext, tex: Texture2D, data: Uint8Array, x?: number, y?: number, width?: number, height?: number): void;
10203
10389
 
10390
+ /**
10391
+ * Fill one layer of a texture array from an already-decoded external image
10392
+ * source — an `ImageBitmap`, `ImageData`, canvas (`HTMLCanvasElement` /
10393
+ * `OffscreenCanvas`), `HTMLImageElement`, `HTMLVideoElement`, or `VideoFrame`.
10394
+ * All of these are accepted directly by WebGPU's `copyExternalImageToTexture`,
10395
+ * so this is a single GPU copy with no per-source-type branching. If the array
10396
+ * was created with mipmaps, the layer's mip chain is regenerated after upload.
10397
+ *
10398
+ * @param engine - Engine context.
10399
+ * @param tex - Target texture array (from `createTexture2DArray`).
10400
+ * @param layer - Destination layer index in `[0, tex.layers)`.
10401
+ * @param source - Any WebGPU external-image source sized `tex.width`×`tex.height`.
10402
+ * @param opts - Flip-Y / premultiply overrides.
10403
+ */
10404
+ export declare function uploadImageToArrayLayer(engine: EngineContext, tex: Texture2DArray, layer: number, source: GPUCopyExternalImageSource, opts?: ArrayLayerUploadOptions): void;
10405
+
10204
10406
  /** UtilityLayer handle. The `scene` field is a regular `SceneContext` — pass it
10205
10407
  * to gizmo factories so their meshes are added there instead of the main
10206
10408
  * scene. */
@@ -1 +1 @@
1
- {"version":3,"file":"asset-container.js","sources":["../../src/asset-container.ts"],"sourcesContent":["import type { SceneNode } from \"./scene/scene-node.js\";\nimport type { LightBase } from \"./light/types.js\";\nimport type { AnimationGroup } from \"./animation/animation-group.js\";\nimport type { MaterialVariantData } from \"./loader-gltf/material-variants.js\";\nimport type { Mesh } from \"./mesh/mesh.js\";\nimport type { Skeleton } from \"./skeleton/bone-control.js\";\nimport type { SceneContext } from \"./scene/scene-core.js\";\n\n/**\n * Result returned by loadGltf / loadBabylon.\n * Pass directly to addToScene() — it handles all fields automatically.\n *\n * - glTF: entities = [root TransformNode], animationGroups = loaded clips\n * - .babylon: entities = root SceneNodes (Mesh/TransformNode) + LightBase, clearColor from file\n */\nexport interface AssetContainer {\n /** Scene entities. glTF: [root TransformNode]. .babylon: root nodes + lights. */\n entities: Array<SceneNode | LightBase>;\n /** Animation groups from the file. addToScene() registers them with the scene-owned AnimationManager by default. */\n animationGroups?: AnimationGroup[];\n /** Scene background color declared in the file. addToScene() applies it to scene.clearColor. */\n clearColor?: GPUColorDict;\n /** Camera parsed from the file. addToScene() sets it as scene.camera when present. */\n camera?: import(\"./camera/camera.js\").Camera;\n /** KHR_materials_variants data. Use selectVariant() / getVariantNames() to interact. */\n materialVariants?: MaterialVariantData;\n /** KHR_xmp_json_ld metadata. `packets` are the JSON-LD packets declared at the\n * document level; `assetPacket` is the packet referenced by `asset` (if any). */\n xmpMetadata?: { packets: unknown[]; assetPacket?: unknown };\n /** Bone-control handles, one per glTF skin. Present only when\n * `enableBoneControl()` was called before loading; otherwise `undefined`.\n * Drive bones via `getBoneByName()` + the `setBone*` functions. */\n skeletons?: Skeleton[];\n /** Deferred scene-wiring hook contributed by a loader feature that needs the\n * target `SceneContext` (which the loader itself never sees). `addToScene()`\n * invokes it once, synchronously, while processing the container. Used by\n * `EXT_lights_image_based` to install its image-based-light environment\n * (spherical harmonics + specular cubemap) onto the scene. Lazy features own\n * the closure so the core loader/scene stay feature-agnostic.\n * @internal */\n _sceneSetup?: (scene: SceneContext) => void;\n}\n\n/**\n * Flatten a loaded asset container's entity tree to its renderable `Mesh` nodes\n * (those carrying GPU geometry), matching the flat `meshes` array Babylon.js\n * loaders return. Useful for camera-framing and per-mesh inspection after a load.\n *\n * Tree-shakeable: only callers that import this pull it into their bundle.\n */\nexport function getContainerMeshes(container: AssetContainer): Mesh[] {\n const meshes: Mesh[] = [];\n const seen = new Set<unknown>();\n const visit = (node: SceneNode): void => {\n if (seen.has(node)) {\n return;\n }\n seen.add(node);\n if ((node as unknown as { _gpu?: unknown })._gpu) {\n meshes.push(node as unknown as Mesh);\n }\n const children = (node as unknown as { children?: SceneNode[] }).children;\n if (children) {\n for (const child of children) {\n visit(child);\n }\n }\n };\n for (const entity of container.entities) {\n // Lights have no scene-graph children to walk; skip them.\n if (\"lightType\" in (entity as object)) {\n continue;\n }\n visit(entity as SceneNode);\n }\n return meshes;\n}\n"],"names":[],"mappings":"AAkDO,SAAS,mBAAmB,SAAA,EAAmC;AAClE,EAAA,MAAM,SAAiB,EAAC;AACxB,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAa;AAC9B,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAA0B;AACrC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAChB,MAAA;AAAA,IACJ;AACA,IAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AACb,IAAA,IAAK,KAAuC,IAAA,EAAM;AAC9C,MAAA,MAAA,CAAO,KAAK,IAAuB,CAAA;AAAA,IACvC;AACA,IAAA,MAAM,WAAY,IAAA,CAA+C,QAAA;AACjE,IAAA,IAAI,QAAA,EAAU;AACV,MAAA,KAAA,MAAW,SAAS,QAAA,EAAU;AAC1B,QAAA,KAAA,CAAM,KAAK,CAAA;AAAA,MACf;AAAA,IACJ;AAAA,EACJ,CAAA;AACA,EAAA,KAAA,MAAW,MAAA,IAAU,UAAU,QAAA,EAAU;AAErC,IAAA,IAAI,eAAgB,MAAA,EAAmB;AACnC,MAAA;AAAA,IACJ;AACA,IAAA,KAAA,CAAM,MAAmB,CAAA;AAAA,EAC7B;AACA,EAAA,OAAO,MAAA;AACX;;;;"}
1
+ {"version":3,"file":"asset-container.js","sources":["../../src/asset-container.ts"],"sourcesContent":["import type { SceneNode } from \"./scene/scene-node.js\";\nimport type { LightBase } from \"./light/types.js\";\nimport type { AnimationGroup } from \"./animation/animation-group.js\";\nimport type { MaterialVariantData } from \"./loader-gltf/material-variants.js\";\nimport type { Mesh } from \"./mesh/mesh.js\";\nimport type { Skeleton } from \"./skeleton/bone-control.js\";\nimport type { SceneContext } from \"./scene/scene-core.js\";\n\n/**\n * Result returned by loadGltf / loadBabylon.\n * Pass directly to addToScene() — it handles all fields automatically.\n *\n * - glTF: entities = [root TransformNode], animationGroups = loaded clips\n * - .babylon: entities = root SceneNodes (Mesh/TransformNode) + LightBase, clearColor from file\n */\nexport interface AssetContainer {\n /** Scene entities. glTF: [root TransformNode]. .babylon: root nodes + lights. */\n entities: Array<SceneNode | LightBase>;\n /** Animation groups from the file. addToScene() registers them with the scene-owned AnimationManager by default. */\n animationGroups?: AnimationGroup[];\n /** Scene background color declared in the file. addToScene() applies it to scene.clearColor. */\n clearColor?: GPUColorDict;\n /** Camera parsed from the file. addToScene() sets it as scene.camera when present. */\n camera?: import(\"./camera/camera.js\").Camera;\n /** KHR_materials_variants data. Use selectVariant() / getVariantNames() to interact. */\n materialVariants?: MaterialVariantData;\n /** KHR_xmp_json_ld metadata. `packets` are the JSON-LD packets declared at the\n * document level; `assetPacket` is the packet referenced by `asset` (if any). */\n xmpMetadata?: { packets: unknown[]; assetPacket?: unknown };\n /** Bone-control handles, one per glTF skin. Present only when\n * `enableBoneControl()` was called before loading; otherwise `undefined`.\n * Drive bones via `getBoneByName()` + the `setBone*` functions. */\n skeletons?: Skeleton[];\n /** @internal Per-frame animation tick closure pushed onto `scene._beforeRender` by\n * `addToScene(scene, container)`. Stored so `removeFromScene(scene, container)` can\n * splice it back out, keeping the two calls symmetric. */\n _beforeRenderHook?: (deltaMs: number) => void;\n /** Deferred scene-wiring hook contributed by a loader feature that needs the\n * target `SceneContext` (which the loader itself never sees). `addToScene()`\n * invokes it once, synchronously, while processing the container. Used by\n * `EXT_lights_image_based` to install its image-based-light environment\n * (spherical harmonics + specular cubemap) onto the scene. Lazy features own\n * the closure so the core loader/scene stay feature-agnostic.\n * @internal */\n _sceneSetup?: (scene: SceneContext) => void;\n}\n\n/**\n * Flatten a loaded asset container's entity tree to its renderable `Mesh` nodes\n * (those carrying GPU geometry), matching the flat `meshes` array Babylon.js\n * loaders return. Useful for camera-framing and per-mesh inspection after a load.\n *\n * Tree-shakeable: only callers that import this pull it into their bundle.\n */\nexport function getContainerMeshes(container: AssetContainer): Mesh[] {\n const meshes: Mesh[] = [];\n const seen = new Set<unknown>();\n const visit = (node: SceneNode): void => {\n if (seen.has(node)) {\n return;\n }\n seen.add(node);\n if ((node as unknown as { _gpu?: unknown })._gpu) {\n meshes.push(node as unknown as Mesh);\n }\n const children = (node as unknown as { children?: SceneNode[] }).children;\n if (children) {\n for (const child of children) {\n visit(child);\n }\n }\n };\n for (const entity of container.entities) {\n // Lights have no scene-graph children to walk; skip them.\n if (\"lightType\" in (entity as object)) {\n continue;\n }\n visit(entity as SceneNode);\n }\n return meshes;\n}\n"],"names":[],"mappings":"AAsDO,SAAS,mBAAmB,SAAA,EAAmC;AAClE,EAAA,MAAM,SAAiB,EAAC;AACxB,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAa;AAC9B,EAAA,MAAM,KAAA,GAAQ,CAAC,IAAA,KAA0B;AACrC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG;AAChB,MAAA;AAAA,IACJ;AACA,IAAA,IAAA,CAAK,IAAI,IAAI,CAAA;AACb,IAAA,IAAK,KAAuC,IAAA,EAAM;AAC9C,MAAA,MAAA,CAAO,KAAK,IAAuB,CAAA;AAAA,IACvC;AACA,IAAA,MAAM,WAAY,IAAA,CAA+C,QAAA;AACjE,IAAA,IAAI,QAAA,EAAU;AACV,MAAA,KAAA,MAAW,SAAS,QAAA,EAAU;AAC1B,QAAA,KAAA,CAAM,KAAK,CAAA;AAAA,MACf;AAAA,IACJ;AAAA,EACJ,CAAA;AACA,EAAA,KAAA,MAAW,MAAA,IAAU,UAAU,QAAA,EAAU;AAErC,IAAA,IAAI,eAAgB,MAAA,EAAmB;AACnC,MAAA;AAAA,IACJ;AACA,IAAA,KAAA,CAAM,MAAmB,CAAA;AAAA,EAC7B;AACA,EAAA,OAAO,MAAA;AACX;;;;"}
@@ -1,4 +1,5 @@
1
1
  export { createAudioEngineAsync, disposeAudioEngine, getMasterVolume, setMasterVolume, unlockAudioEngineAsync } from './audio-engine.js';
2
+ export { createAudioEngineMediaStream, disposeAudioEngineMediaStream } from './media-stream-output.js';
2
3
  export { SoundState, createSoundAsync, disposeSound, pauseSound, playSound, resumeSound, setSoundVolume, stopSound } from './static-sound.js';
3
4
  export { createStreamingSoundAsync, disposeStreamingSound, pauseStreamingSound, playStreamingSound, preloadStreamingInstanceAsync, preloadStreamingInstancesAsync, resumeStreamingSound, setStreamingSoundVolume, stopStreamingSound } from './streaming-sound.js';
4
5
  export { createAudioBusAsync, disposeAudioBus, setBusVolume } from './audio-bus.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
@@ -0,0 +1,44 @@
1
+ function createAudioEngineMediaStream(engine) {
2
+ const context = engine._ctx;
3
+ if (engine._isOffline || typeof context.createMediaStreamDestination !== "function") {
4
+ throw new Error("Audio engine media streams require a real-time AudioContext.");
5
+ }
6
+ const source = engine._mainOut._gain;
7
+ const destination = context.createMediaStreamDestination();
8
+ source.connect(destination);
9
+ const output = {
10
+ stream: destination.stream,
11
+ _engine: engine,
12
+ _source: source,
13
+ _destination: destination,
14
+ _engineDisposer: () => {
15
+ output._registered = false;
16
+ disposeAudioEngineMediaStream(output);
17
+ },
18
+ _registered: true,
19
+ _disposed: false,
20
+ _dispose: () => disposeAudioEngineMediaStream(output)
21
+ };
22
+ engine._disposers.push(output._engineDisposer);
23
+ return output;
24
+ }
25
+ function disposeAudioEngineMediaStream(output) {
26
+ if (output._disposed) {
27
+ return;
28
+ }
29
+ output._disposed = true;
30
+ if (output._registered) {
31
+ output._registered = false;
32
+ const disposerIndex = output._engine._disposers.indexOf(output._engineDisposer);
33
+ if (disposerIndex !== -1) {
34
+ output._engine._disposers.splice(disposerIndex, 1);
35
+ }
36
+ }
37
+ output._source.disconnect(output._destination);
38
+ for (const track of output.stream.getTracks()) {
39
+ track.stop();
40
+ }
41
+ }
42
+
43
+ export { createAudioEngineMediaStream, disposeAudioEngineMediaStream };
44
+ //# sourceMappingURL=media-stream-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-stream-output.js","sources":["../../../src/audio/media-stream-output.ts"],"sourcesContent":["/**\n * Media-stream output — opt-in tap of the audio engine's final master mix.\n *\n * The tap mirrors the post-master signal into a MediaStream without changing\n * the normal speaker output. Consumers can use that stream for recording,\n * WebRTC, or other browser media pipelines, then dispose the tap independently.\n */\n\nimport type { AudioEngine } from \"./audio-engine.js\";\n\n/** Pure-state handle for a MediaStream carrying the audio engine's final master mix. */\nexport interface AudioEngineMediaStream {\n /** One live audio track containing the post-master engine output. */\n readonly stream: MediaStream;\n /** @internal */ readonly _engine: AudioEngine;\n /** @internal */ readonly _source: GainNode;\n /** @internal */ readonly _destination: MediaStreamAudioDestinationNode;\n /** @internal */ readonly _engineDisposer: () => void;\n /** @internal */ _registered: boolean;\n /** @internal */ _disposed: boolean;\n /** @internal */ _dispose(): void;\n}\n\n/**\n * Mirrors an engine's final master output into a MediaStream.\n *\n * Real-time Web Audio is required because OfflineAudioContext has no\n * MediaStream destination. The engine's audible destination remains connected.\n */\nexport function createAudioEngineMediaStream(engine: AudioEngine): AudioEngineMediaStream {\n const context = engine._ctx;\n if (engine._isOffline || typeof (context as AudioContext).createMediaStreamDestination !== \"function\") {\n throw new Error(\"Audio engine media streams require a real-time AudioContext.\");\n }\n\n const source = engine._mainOut._gain;\n const destination = (context as AudioContext).createMediaStreamDestination();\n source.connect(destination);\n\n const output: AudioEngineMediaStream = {\n stream: destination.stream,\n _engine: engine,\n _source: source,\n _destination: destination,\n _engineDisposer: () => {\n output._registered = false;\n disposeAudioEngineMediaStream(output);\n },\n _registered: true,\n _disposed: false,\n _dispose: () => disposeAudioEngineMediaStream(output),\n };\n\n engine._disposers.push(output._engineDisposer);\n return output;\n}\n\n/**\n * Disconnects a media-stream tap and stops every track owned by its stream.\n * Safe to call more than once.\n */\nexport function disposeAudioEngineMediaStream(output: AudioEngineMediaStream): void {\n if (output._disposed) {\n return;\n }\n\n output._disposed = true;\n if (output._registered) {\n output._registered = false;\n const disposerIndex = output._engine._disposers.indexOf(output._engineDisposer);\n if (disposerIndex !== -1) {\n output._engine._disposers.splice(disposerIndex, 1);\n }\n }\n output._source.disconnect(output._destination);\n for (const track of output.stream.getTracks()) {\n track.stop();\n }\n}\n"],"names":[],"mappings":"AA6BO,SAAS,6BAA6B,MAAA,EAA6C;AACtF,EAAA,MAAM,UAAU,MAAA,CAAO,IAAA;AACvB,EAAA,IAAI,MAAA,CAAO,UAAA,IAAc,OAAQ,OAAA,CAAyB,iCAAiC,UAAA,EAAY;AACnG,IAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,EAClF;AAEA,EAAA,MAAM,MAAA,GAAS,OAAO,QAAA,CAAS,KAAA;AAC/B,EAAA,MAAM,WAAA,GAAe,QAAyB,4BAAA,EAA6B;AAC3E,EAAA,MAAA,CAAO,QAAQ,WAAW,CAAA;AAE1B,EAAA,MAAM,MAAA,GAAiC;AAAA,IACnC,QAAQ,WAAA,CAAY,MAAA;AAAA,IACpB,OAAA,EAAS,MAAA;AAAA,IACT,OAAA,EAAS,MAAA;AAAA,IACT,YAAA,EAAc,WAAA;AAAA,IACd,iBAAiB,MAAM;AACnB,MAAA,MAAA,CAAO,WAAA,GAAc,KAAA;AACrB,MAAA,6BAAA,CAA8B,MAAM,CAAA;AAAA,IACxC,CAAA;AAAA,IACA,WAAA,EAAa,IAAA;AAAA,IACb,SAAA,EAAW,KAAA;AAAA,IACX,QAAA,EAAU,MAAM,6BAAA,CAA8B,MAAM;AAAA,GACxD;AAEA,EAAA,MAAA,CAAO,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,eAAe,CAAA;AAC7C,EAAA,OAAO,MAAA;AACX;AAMO,SAAS,8BAA8B,MAAA,EAAsC;AAChF,EAAA,IAAI,OAAO,SAAA,EAAW;AAClB,IAAA;AAAA,EACJ;AAEA,EAAA,MAAA,CAAO,SAAA,GAAY,IAAA;AACnB,EAAA,IAAI,OAAO,WAAA,EAAa;AACpB,IAAA,MAAA,CAAO,WAAA,GAAc,KAAA;AACrB,IAAA,MAAM,gBAAgB,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,OAAA,CAAQ,OAAO,eAAe,CAAA;AAC9E,IAAA,IAAI,kBAAkB,EAAA,EAAI;AACtB,MAAA,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,MAAA,CAAO,aAAA,EAAe,CAAC,CAAA;AAAA,IACrD;AAAA,EACJ;AACA,EAAA,MAAA,CAAO,OAAA,CAAQ,UAAA,CAAW,MAAA,CAAO,YAAY,CAAA;AAC7C,EAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,SAAA,EAAU,EAAG;AAC3C,IAAA,KAAA,CAAM,IAAA,EAAK;AAAA,EACf;AACJ;;;;"}
@@ -2,7 +2,7 @@ import { _setHpmAllocator } from '../math/_matrix-allocator.js';
2
2
  import { isDomCanvas, _buildSurface, resizeSurface, _refreshScRT, setSurfaceSize } from './surface.js';
3
3
  import { disposeGpuResourceRetirements } from './gpu-resource-retirement.js';
4
4
 
5
- const VERSION = /* @__PURE__ */ (() => "1.11.0" )();
5
+ const VERSION = /* @__PURE__ */ (() => "1.13.0" )();
6
6
  let _vis = 0;
7
7
  function bumpVisibilityEpoch() {
8
8
  _vis = _vis + 1 | 0;
@@ -392,5 +392,5 @@ function drawList(enc, list, engine) {
392
392
  return draws;
393
393
  }
394
394
 
395
- export { _writePassSceneUBO, createRenderTask, removeMeshFromTask };
395
+ export { _writePassSceneUBO, createRenderTask, drawList, removeMeshFromTask };
396
396
  //# sourceMappingURL=render-task.js.map