@babylonjs/lite 1.14.0 → 1.15.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 (46) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/index.js +326 -326
  3. package/dist/index.js.map +1 -1
  4. package/index.d.ts +72 -6
  5. package/lib/camera/arc-rotate.js +2 -20
  6. package/lib/camera/arc-rotate.js.map +1 -1
  7. package/lib/camera/camera.js +21 -4
  8. package/lib/camera/camera.js.map +1 -1
  9. package/lib/camera/free-camera.js +2 -19
  10. package/lib/camera/free-camera.js.map +1 -1
  11. package/lib/camera/geospatial-camera.js +2 -19
  12. package/lib/camera/geospatial-camera.js.map +1 -1
  13. package/lib/camera/orthographic.js +70 -0
  14. package/lib/camera/orthographic.js.map +1 -0
  15. package/lib/engine/engine.js +1 -1
  16. package/lib/frame-graph/render-task.js +2 -2
  17. package/lib/frame-graph/render-task.js.map +1 -1
  18. package/lib/index.js +4 -1
  19. package/lib/index.js.map +1 -1
  20. package/lib/light/clustered.js +19 -6
  21. package/lib/light/clustered.js.map +1 -1
  22. package/lib/material/shader/shader-renderable.js +2 -2
  23. package/lib/material/shader/shader-renderable.js.map +1 -1
  24. package/lib/material/standard/enable-standard-mesh-features.js.map +1 -1
  25. package/lib/math/index.js +1 -0
  26. package/lib/math/index.js.map +1 -1
  27. package/lib/math/mat4-look-at-world-lh.js +55 -0
  28. package/lib/math/mat4-look-at-world-lh.js.map +1 -0
  29. package/lib/math/mat4-ortho-lh-to-ref.js +22 -0
  30. package/lib/math/mat4-ortho-lh-to-ref.js.map +1 -0
  31. package/lib/math/mat4.js +1 -0
  32. package/lib/math/mat4.js.map +1 -1
  33. package/lib/navigation/index.js +1 -1
  34. package/lib/navigation/navigation.js +12 -1
  35. package/lib/navigation/navigation.js.map +1 -1
  36. package/lib/post-process/taa.js +2 -1
  37. package/lib/post-process/taa.js.map +1 -1
  38. package/lib/shadow/csm-shadow-task-hooks.js +13 -6
  39. package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
  40. package/lib/shadow/shadow-base.js +3 -2
  41. package/lib/shadow/shadow-base.js.map +1 -1
  42. package/lib/text/text-renderable.js +2 -2
  43. package/lib/text/text-renderable.js.map +1 -1
  44. package/package.json +3 -11
  45. package/material/standard/enable-standard-mesh-features.d.ts +0 -4
  46. package/material/standard/enable-standard-vertex-colors.d.ts +0 -2
@@ -0,0 +1,70 @@
1
+ import { _installOrthographicProjector } from './camera.js';
2
+ import { mat4OrthoOffCenterLHToRef } from '../math/mat4-ortho-lh-to-ref.js';
3
+
4
+ const PLANE_KEYS = ["left", "right", "bottom", "top"];
5
+ function invalidateProjection(camera) {
6
+ camera._projRev = (camera._projRev ?? 0) + 1;
7
+ }
8
+ function createOrthographicBounds(camera, options) {
9
+ let halfHeight = options.halfHeight ?? 1;
10
+ const planes = {
11
+ left: options.left ?? null,
12
+ right: options.right ?? null,
13
+ bottom: options.bottom ?? null,
14
+ top: options.top ?? null
15
+ };
16
+ const bounds = {};
17
+ Object.defineProperty(bounds, "halfHeight", {
18
+ get() {
19
+ return halfHeight;
20
+ },
21
+ set(v) {
22
+ if (halfHeight !== v) {
23
+ halfHeight = v;
24
+ invalidateProjection(camera);
25
+ }
26
+ },
27
+ enumerable: true,
28
+ configurable: true
29
+ });
30
+ for (const key of PLANE_KEYS) {
31
+ Object.defineProperty(bounds, key, {
32
+ get() {
33
+ return planes[key];
34
+ },
35
+ set(v) {
36
+ if (planes[key] !== v) {
37
+ planes[key] = v;
38
+ invalidateProjection(camera);
39
+ }
40
+ },
41
+ enumerable: true,
42
+ configurable: true
43
+ });
44
+ }
45
+ return bounds;
46
+ }
47
+ function writeOrthoProjection(camera, aspectRatio, out) {
48
+ const b = camera.ortho;
49
+ const halfHeight = b.halfHeight;
50
+ const halfWidth = halfHeight * aspectRatio;
51
+ mat4OrthoOffCenterLHToRef(out, b.left ?? -halfWidth, b.right ?? halfWidth, b.bottom ?? -halfHeight, b.top ?? halfHeight, camera.nearPlane, camera.farPlane);
52
+ }
53
+ function enableOrthographicCamera(camera, bounds) {
54
+ _installOrthographicProjector(writeOrthoProjection);
55
+ const ortho = createOrthographicBounds(camera, bounds ?? {});
56
+ camera.ortho = ortho;
57
+ invalidateProjection(camera);
58
+ return ortho;
59
+ }
60
+ function disableOrthographicCamera(camera) {
61
+ camera.ortho = null;
62
+ const p = camera._projCache;
63
+ p[12] = 0;
64
+ p[13] = 0;
65
+ p[15] = 0;
66
+ invalidateProjection(camera);
67
+ }
68
+
69
+ export { disableOrthographicCamera, enableOrthographicCamera };
70
+ //# sourceMappingURL=orthographic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orthographic.js","sources":["../../../src/camera/orthographic.ts"],"sourcesContent":["/**\n * Opt-in entry point for orthographic camera projection.\n *\n * The explicit enable keeps every perspective-only scene byte-identical: without\n * this module `_installOrthographicProjector` tree-shakes, the bundler proves the\n * projector seam in `camera.ts` is always null, and the orthographic branch in\n * `getProjectionMatrix` folds away entirely.\n *\n * Works with any camera that satisfies the `Camera` contract (ArcRotate, Free,\n * Geospatial, …) — the projection is orthogonal to how the camera is positioned.\n */\nimport type { Camera } from \"./camera.js\";\nimport { _installOrthographicProjector } from \"./camera.js\";\nimport { mat4OrthoOffCenterLHToRef } from \"../math/mat4-ortho-lh-to-ref.js\";\nimport type { Mat4Storage } from \"../math/types.js\";\n\n/** Live orthographic view-volume extents, in world units. Mutable and animatable:\n * every setter invalidates the camera's projection cache, so assigning a field —\n * by hand, from a render loop, or through a property animation targeting\n * `\"ortho.halfHeight\"` — takes effect on the next frame.\n *\n * A plane left `null` is derived from `halfHeight`: vertically as `±halfHeight`,\n * horizontally as `±halfHeight * aspectRatio`, so the volume tracks the render\n * target's aspect ratio and never squashes the image. Set a plane to a number for\n * an off-center volume (Babylon's `orthoLeft` / `orthoRight` / `orthoBottom` /\n * `orthoTop`); set it back to `null` to return to the derived extent. */\nexport interface OrthographicBounds {\n /** Vertical half-extent of the view volume. Halving it doubles the zoom. */\n halfHeight: number;\n /** Left clip plane, or null to derive `-halfHeight * aspectRatio`. */\n left: number | null;\n /** Right clip plane, or null to derive `halfHeight * aspectRatio`. */\n right: number | null;\n /** Bottom clip plane, or null to derive `-halfHeight`. */\n bottom: number | null;\n /** Top clip plane, or null to derive `halfHeight`. */\n top: number | null;\n}\n\n/** Initial extents accepted by `enableOrthographicCamera`. Every field is optional;\n * omitted planes are derived from `halfHeight` (default 1). */\nexport interface OrthographicBoundsOptions {\n halfHeight?: number;\n left?: number | null;\n right?: number | null;\n bottom?: number | null;\n top?: number | null;\n}\n\nconst PLANE_KEYS = [\"left\", \"right\", \"bottom\", \"top\"] as const;\n\n/** Invalidate everything downstream of the projection.\n *\n * Per-frame consumers gate their GPU uploads on a camera change key: the forward pass's\n * scene UBO (`_writePassSceneUBO`) returns early when camera identity, that key, aspect,\n * fog, image processing and environment are all unchanged — ShaderMaterial, text, clustered\n * lighting, TAA and CSM have equivalent gates, and the `camera.ts` matrix caches key on the\n * same value. The camera transform does not move when only the view volume changes, so\n * without this bump a steady-state scene would keep rendering the previously uploaded\n * view-projection.\n *\n * Bumping `_projRev` is what makes the change reach the GPU: `_cameraChangeKey` folds it\n * into that key. It is deliberately a *separate* counter from `worldMatrixVersion` — marking\n * the camera transform dirty would additionally invalidate the camera's children and, under\n * floating origin, retrigger origin rebasing across every renderable (`wrapRenderableForFO`),\n * none of which a view-volume change warrants.\n *\n * Bounds are pushed here rather than polled by `_cameraChangeKey` (as `fov` / `nearPlane` /\n * `farPlane` are) because this module already owns accessors for them — pushing costs the\n * poll nothing and is exact. */\nfunction invalidateProjection(camera: Camera): void {\n camera._projRev = (camera._projRev ?? 0) + 1;\n}\n\n/** Build the live bounds object. Each field is an accessor that invalidates the camera's\n * projection state on change. Nothing in the shared `getProjectionMatrix` cache check has to\n * know about orthographic state, so perspective-only scenes are unaffected. Properties are\n * defined (not merely optional) so animation property paths like `\"ortho.halfHeight\"`\n * resolve. `halfHeight` is deliberately a separate `number`-only accessor: the derived\n * extents multiply through it, so accepting `null` there would silently produce a degenerate\n * (NaN) projection, whereas `null` is meaningful on the four planes. */\nfunction createOrthographicBounds(camera: Camera, options: OrthographicBoundsOptions): OrthographicBounds {\n let halfHeight = options.halfHeight ?? 1;\n const planes: Record<string, number | null> = {\n left: options.left ?? null,\n right: options.right ?? null,\n bottom: options.bottom ?? null,\n top: options.top ?? null,\n };\n const bounds = {} as OrthographicBounds;\n Object.defineProperty(bounds, \"halfHeight\", {\n get(): number {\n return halfHeight;\n },\n set(v: number) {\n if (halfHeight !== v) {\n halfHeight = v;\n invalidateProjection(camera);\n }\n },\n enumerable: true,\n configurable: true,\n });\n for (const key of PLANE_KEYS) {\n Object.defineProperty(bounds, key, {\n get(): number | null {\n return planes[key]!;\n },\n set(v: number | null) {\n if (planes[key] !== v) {\n planes[key] = v;\n invalidateProjection(camera);\n }\n },\n enumerable: true,\n configurable: true,\n });\n }\n return bounds;\n}\n\nfunction writeOrthoProjection(camera: Camera, aspectRatio: number, out: Mat4Storage): void {\n const b = camera.ortho!;\n const halfHeight = b.halfHeight;\n const halfWidth = halfHeight * aspectRatio;\n mat4OrthoOffCenterLHToRef(out, b.left ?? -halfWidth, b.right ?? halfWidth, b.bottom ?? -halfHeight, b.top ?? halfHeight, camera.nearPlane, camera.farPlane);\n}\n\n/** Switch a camera to an orthographic projection, and return its live `ortho` bounds.\n *\n * Depth still comes from `camera.nearPlane` / `camera.farPlane`; `camera.fov` has no\n * effect in this mode — an orthographic camera zooms by changing `halfHeight`.\n *\n * The returned object is also reachable as `camera.ortho`, and stays mutable (see\n * `OrthographicBounds`), so this only needs to be called once per camera. Calling it\n * again replaces the bounds with a fresh object. */\nexport function enableOrthographicCamera(camera: Camera, bounds?: OrthographicBoundsOptions): OrthographicBounds {\n _installOrthographicProjector(writeOrthoProjection);\n const ortho = createOrthographicBounds(camera, bounds ?? {});\n camera.ortho = ortho;\n invalidateProjection(camera);\n return ortho;\n}\n\n/** Switch a camera back to its perspective projection (driven by `camera.fov`). */\nexport function disableOrthographicCamera(camera: Camera): void {\n camera.ortho = null;\n // `mat4PerspectiveLHToRef` only writes the terms a perspective matrix needs, relying on the\n // rest of a freshly allocated (zeroed) cache. Clear the extra terms the orthographic writer\n // introduced so the perspective matrix is not rebuilt on top of an off-center, w=1 volume.\n // Owned here rather than in the shared writer so perspective-only scenes pay nothing.\n const p = camera._projCache;\n p[12] = 0;\n p[13] = 0;\n p[15] = 0;\n invalidateProjection(camera);\n}\n"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { _setHpmAllocator } from '../math/_matrix-allocator.js';
3
3
  import { isDomCanvas, _buildSurface, resizeSurface, _refreshScRT, setSurfaceSize } from './surface.js';
4
4
  import { disposeGpuResourceRetirements } from './gpu-resource-retirement.js';
5
5
 
6
- const VERSION = /* @__PURE__ */ (() => "1.14.0" )();
6
+ const VERSION = /* @__PURE__ */ (() => "1.15.0" )();
7
7
  let _vis = 0;
8
8
  function bumpVisibilityEpoch() {
9
9
  _vis = _vis + 1 | 0;
@@ -1,7 +1,7 @@
1
1
  import { F32 } from '../engine/typed-arrays.js';
2
2
  import { _vis } from '../engine/engine.js';
3
3
  import { disposeRenderTarget, buildRenderTarget } from '../engine/render-target.js';
4
- import { getViewMatrix } from '../camera/camera.js';
4
+ import { _cameraChangeKey, getViewMatrix } from '../camera/camera.js';
5
5
  import { getSceneBindGroupLayout } from '../render/scene-helpers.js';
6
6
  import { _packSceneUniforms } from './scene-uniforms-pack.js';
7
7
  import { createEmptyUniformBuffer } from '../resource/gpu-buffers.js';
@@ -348,7 +348,7 @@ function _writePassSceneUBO(task, eng, scene, camera) {
348
348
  const fog = scene.fog;
349
349
  const img = scene.imageProcessing;
350
350
  const envRotationY = scene.envRotationY || 0;
351
- const wv = camera.worldMatrixVersion;
351
+ const wv = _cameraChangeKey(camera);
352
352
  const envTextures = scene._envTextures;
353
353
  const s = task._su;
354
354
  if (s[0] === camera && s[1] === fog && s[2] === wv && s[3] === aspect && s[4] === envRotationY && s[5] === img.exposure && s[6] === img.contrast && s[7] === envTextures) {
@@ -1 +1 @@
1
- {"version":3,"file":"render-task.js","sources":["../../../src/frame-graph/render-task.ts"],"sourcesContent":["/**\n * RenderTask — a frame-graph task that records a single `RenderPass`,\n * binds the scene's `RenderTarget`, and draws renderables into it.\n *\n * - `record()` builds bucketed `DrawBinding` lists from `_renderables`\n * (opaque / direct / transparent), sorts opaque + direct by\n * `order`, then creates a `RenderPass` wired to the task's render target.\n * The pass owns its\n * `GPURenderPassDescriptor` and the per-pass-encoder body lives in a\n * closure passed to `setRenderPassExecuteFunc`.\n * - Before `RenderPass._execute()` begins the GPU pass: writes the scene UBO, refreshes lights, updates\n * per-binding UBOs, mirrors live `scene.clearColor` + `clr` onto the\n * render pass. Shared task execution then calls `_execute()`. The\n * `RenderPass` itself patches the swapchain view + clearColor + loadOp\n * and brackets the body with `beginRenderPass` / `end`.\n *\n * Renderable population:\n * - Explicit: push into `_renderables` directly, or `addMesh(mesh, opts)`\n * which builds a (mesh, material) Renderable at `record()` time.\n * - Auto scene mirror: when `_renderables` is empty at record() time, copy the\n * scene's renderables. Re-sync happens automatically when the scene's\n * `_renderableVersion` changes between frames (mesh add/remove, material swap).\n *\n * The engine `scRT` is just another `RenderTarget` here: a task that\n * targets it (`rt`) or resolves into it (`rst`) re-reads its per-frame color view\n * at execute time (the swap texture is re-acquired each frame). `clr: false`\n * switches color + depth `loadOp` to `\"load\"` so multiple scenes can share the\n * swapchain in one frame (e.g., a 3D scene + a UI overlay scene).\n */\n\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { _vis } from \"../engine/engine.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { Camera } from \"../camera/camera.js\";\nimport type { Renderable, DrawBinding, DrawUpdateContext, DrawUpdateBatch } from \"../render/renderable.js\";\nimport type { RenderTargetSignature } from \"../engine/render-target.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport type { Material } from \"../material/material.js\";\nimport type { RenderTarget } from \"../engine/render-target.js\";\nimport { buildRenderTarget, disposeRenderTarget } from \"../engine/render-target.js\";\nimport { getViewMatrix } from \"../camera/camera.js\";\nimport { getSceneBindGroupLayout } from \"../render/scene-helpers.js\";\nimport { _packSceneUniforms } from \"./scene-uniforms-pack.js\";\nimport { createEmptyUniformBuffer } from \"../resource/gpu-buffers.js\";\nimport { SCENE_UBO_BYTES } from \"../shader/scene-uniforms-size.js\";\nimport { ensureSceneLightState, refreshSceneLightsUBO } from \"../render/lights-ubo.js\";\nimport type { Task } from \"./task.js\";\n\n/** Configuration for `createRenderTask`: render target, clear state, optional camera override, and transmission settings. */\nexport interface RenderTaskConfig {\n name: string;\n /** TODO: rt should not live in this config long-term. Until texture\n * management is virtualized, callers must provide the concrete target; once\n * virtualized, the task should create/manage its own render target. */\n rt: RenderTarget;\n /** Optional single-sample resolve target. When `rt` is multisampled\n * (`sampleCount > 1`), the color attachment resolves into this target's\n * color texture at end-of-pass — letting an MSAA render feed a post-process\n * that requires a single-sample source, without an extra resolve pass.\n * Caller contract (not validated): must be single-sample with a color\n * format and size matching `rt`; WebGPU errors at pass-encode time if not.\n * Ignored when `rt` is single-sample. */\n rst?: RenderTarget;\n /** Optional separate depth/stencil attachment. The pass binds this target's\n * depth view instead of `rt`'s own, and uses its `depthStencilFormat` for\n * pipeline signature matching. The colour `rt` must omit `depthStencilFormat`\n * (so it allocates no internal depth) and match this target in size + sample\n * count. Two ownership modes, distinguished by `_eager`:\n * - `_eager` depth (e.g. a `GeometryRendererTask` output): the task neither\n * builds nor clears nor disposes it — it loads it (`loadOp: \"load\"`) and the\n * caller owns clearing. This is how scenes reuse a pre-rendered depth buffer.\n * - non-`_eager` depth: the task owns it — builds/rebuilds it in `record()`,\n * clears it (`loadOp: \"clear\"`), and disposes it. Used by the default\n * single-sample scene task, whose colour `rt` is the depth-less\n * engine `scRT`. */\n depth?: RenderTarget;\n /** Background clear color. May be mutated frame-to-frame. */\n clrColor?: GPUColorDict;\n /** When true, color `loadOp` is \"clear\"; when false, \"load\" (overlays previous\n * color content). Depth is always cleared when rt-owned and always loaded when\n * supplied via `depth`. */\n clr?: boolean;\n /** Per-pass camera override. Null/undefined uses `scene.camera`. */\n cam?: Camera | null;\n /** Use canvas dimensions, not render-target dimensions, for this pass's scene UBO aspect. */\n cs?: boolean;\n /** Scene-texture transmission settings. `copyCount: 0` copies before every transmissive draw.\n * `generateMipmaps: false` allocates only mip 0 for the refraction texture and skips mip generation.\n * `mipLevelCount` caps the generated chain when a material only samples low explicit LODs.\n * `grabDepth: true` also snapshots the task's DEPTH attachment at the same mid-pass grab (see\n * `TransmissionOptions.grabDepth`). */\n transmission?: { copyCount?: number; generateMipmaps?: boolean; mipLevelCount?: number; grabDepth?: boolean };\n /** @internal Skip clustered-light preparation for passes that never run forward lighting. */\n _skipClusteredLights?: boolean;\n}\n\n/** A frame-graph task that records a single `RenderPass`, binds the scene's `RenderTarget`, and draws renderables into it. */\nexport interface RenderTask extends Task {\n readonly name: string;\n /** Render tasks are scene-bound because they consume scene camera, lights, and renderables. */\n readonly scene: SceneContext;\n /** Live task configuration. Mutating `clr` or `clrColor` affects subsequent frames. */\n /** @internal */\n readonly _config: RenderTaskConfig;\n /** @internal */\n _autoFromScene: boolean;\n\n /** Source-of-truth renderables. Bucketed binding lists below are derived from\n * this list at `record()` (or re-sync when auto-filled and `_renderableVersion` changes). */\n /** @internal */\n _renderables: Renderable[];\n /** @internal */\n _opaqueBindings: DrawBinding[];\n /** @internal */\n _directBindings: DrawBinding[];\n /** @internal */\n _transparentBindings: DrawBinding[];\n /** Cached opaque render bundle. Invalidated by renderable list mutations\n * (`_lastVersion`) and the global visibility/resource epoch (`_lastVis`). */\n /** @internal */\n _opaqueBundles: GPURenderBundle[];\n /** @internal */\n _lastVersion: number;\n /** @internal */\n _lastVis: number;\n /** @internal True once `record()` has run — the task is \"live\" (GPU target allocated, material batch builders\n * present). A runtime `addMesh` after this resolves + re-buckets THIS task immediately (no frame-graph rebuild). */\n _recorded: boolean;\n\n /** @internal */\n _renderPassDescriptor: GPURenderPassDescriptor;\n /** @internal */\n _colorAttachment: GPURenderPassColorAttachment;\n /** @internal External depth source from `config.depth`. When unset,\n * the pass uses `config.rt._depthView`. */\n _depthSrc?: RenderTarget;\n /** @internal External depth/stencil `loadOp` (\"load\" when `config.depth` is\n * set). When unset, defaults to `\"clear\"`. */\n _depthLoadOp?: GPULoadOp;\n\n /** Per-task scene UBO + bind group. Created eagerly in createRenderTask\n * so renderables can reference `_sceneBG` at `bind()` time. Written each\n * frame by `_writePassSceneUBO`. Destroyed in `dispose()`. */\n /** @internal */\n _sceneUBO: GPUBuffer;\n /** @internal */\n _sceneBG: GPUBindGroup;\n /** @internal */\n _lightsUBO: GPUBuffer;\n /** @internal */\n _suData: Float32Array;\n /** @internal */\n _su: unknown[];\n /** Optional transmission-enabled execute path: copies the scene texture for refraction and draws transmissive\n * renderables. Present only when the task was configured with `transmission`. Returns the number of draw calls issued. */\n /** @internal */\n _executeWithTransmission?(sampleCount: number): number;\n /** @internal */\n _targetSignature: RenderTargetSignature;\n /** @internal Lazy feature work flushed after binding updates and before the render pass. */\n _updateBatches: DrawUpdateBatch[];\n\n /** Add a mesh to this task's explicit render list with an optional per-pass material override. Resolved via\n * `material._buildGroup._rebuildSingle`, so the mesh's material family must already have been registered with the\n * scene (its batch builder has run). BEFORE the first `record()` the add is QUEUED and drained at record() time;\n * AFTER (a live/runtime add) it is resolved + re-bucketed into THIS task immediately, so the mesh renders on the\n * next frame without a `frameGraph.build()` (which would re-allocate shared GPU resources across all tasks). */\n addMesh(mesh: Mesh, opts?: { material?: Material }): void;\n /** @internal */\n _pendingMeshes: { mesh: Mesh; material: Material }[];\n}\n\ninterface MutableDrawUpdateContext {\n targetWidth: number;\n targetHeight: number;\n _camera?: Camera | null;\n}\n\n/** Create a render pass task. GPU resources (target textures + descriptor)\n * are not allocated until `record()` runs (via `frameGraph.build()`).\n *\n * Swapchain-targeted tasks acquire the swap view per-frame at execute time. */\nexport function createRenderTask(config: RenderTaskConfig, engine: EngineContext, scene: SceneContext): RenderTask {\n const sc = scene as SceneContext;\n config.clrColor ??= { r: 0.2, g: 0.2, b: 0.3, a: 1.0 };\n config.clr ??= true;\n const desc = config.rt._descriptor;\n // Render upright: row 0 of the GPU texture is the top of the scene. Every\n // RT (offscreen or swapchain) renders without a projection Y-flip; pipelines\n // use the default ccw front face; downstream samplers see upright pixels.\n const targetSignature = {\n _colorFormat: desc.format,\n _depthStencilFormat: config.depth?._descriptor.dFormat ?? desc.dFormat,\n _depthCompare: desc._depthCompare,\n _sampleCount: desc.samples ?? 1,\n };\n\n const sceneBGL = getSceneBindGroupLayout(engine);\n const sceneUBO = createEmptyUniformBuffer(engine, SCENE_UBO_BYTES);\n const lightsUBO = ensureSceneLightState(engine, sc)._buffer;\n const sceneBG = engine._device.createBindGroup({\n layout: sceneBGL,\n entries: [\n { binding: 0, resource: { buffer: sceneUBO } },\n { binding: 1, resource: { buffer: lightsUBO } },\n ],\n });\n const colorAttachment = { loadOp: \"clear\", storeOp: \"store\" } as GPURenderPassColorAttachment;\n const updateContext: MutableDrawUpdateContext = { targetWidth: 0, targetHeight: 0 };\n const task: RenderTask = {\n name: config.name,\n _config: config,\n engine: engine,\n scene: sc,\n _passes: [],\n _autoFromScene: false,\n _renderables: [],\n _opaqueBindings: [],\n _directBindings: [],\n _transparentBindings: [],\n _opaqueBundles: [],\n _lastVersion: -1,\n _lastVis: 0,\n _recorded: false,\n _renderPassDescriptor: { colorAttachments: [colorAttachment] },\n _colorAttachment: colorAttachment,\n _depthSrc: config.depth,\n _depthLoadOp: config.depth ? (config.depth._eager ? \"load\" : \"clear\") : undefined,\n _sceneUBO: sceneUBO,\n _sceneBG: sceneBG,\n _lightsUBO: lightsUBO,\n _suData: new F32(SCENE_UBO_BYTES / 4),\n _su: [],\n _targetSignature: targetSignature,\n _updateBatches: [],\n _pendingMeshes: [],\n addMesh(mesh, opts) {\n const material = opts?.material ?? mesh.material;\n if (!material) {\n return;\n }\n task._pendingMeshes.push({ mesh, material });\n if (task._recorded) {\n // Live (post-record) add: resolve + re-bucket THIS task now — buildBindings clears its bundle cache\n // so it re-records on the next execute. Deliberately NOT a frame-graph rebuild (that re-allocates the\n // shared scene UBO + every task's render target mid-frame and crashes the in-flight submit).\n resolvePendingMeshes(task, sc);\n // A live add makes the render list explicit (mirrors record(), where a pending mesh forces\n // _autoFromScene = false). Without this, an auto-mirroring task's next scene-version resync in\n // prepareRenderTaskPass would clear _renderables and drop the just-added mesh.\n task._autoFromScene = false;\n buildBindings(task, engine, targetSignature);\n }\n },\n record(): void {\n if (task._autoFromScene) {\n task._renderables.length = 0;\n }\n resolvePendingMeshes(task, sc);\n task._autoFromScene = !task._renderables.length;\n if (task._autoFromScene) {\n task._renderables.push(...sc._renderables);\n }\n // Read config.rt dynamically — transmission retargeting swaps it after\n // the task is created, and the engine scRT must never be rebuilt.\n const rt = config.rt;\n buildRenderTarget(rt, engine);\n if (config.rst && (rt._descriptor.samples ?? 1) > 1) {\n buildRenderTarget(config.rst, engine);\n }\n // A non-eager external depth (e.g. the default single-sample scene task's\n // depth, whose colour rt is the depth-less scRT) is task-managed:\n // build/rebuild it here. Eager depths (GeometryRendererTask outputs) are\n // pre-built and skipped by buildRenderTarget.\n if (config.depth && !config.depth._eager) {\n buildRenderTarget(config.depth, engine);\n }\n updateContext.targetWidth = rt._width;\n updateContext.targetHeight = rt._height;\n refreshTaskSceneBindGroup(task, engine);\n buildBindings(task, engine, targetSignature);\n buildRenderPassDescriptor(task, rt);\n task._recorded = true; // task is now live — a subsequent addMesh resolves + re-buckets immediately\n },\n execute(): number {\n return executePass(task, engine, targetSignature, updateContext);\n },\n dispose(): void {\n task._passes.length = 0;\n // disposeRenderTarget no-ops on the engine scRT and on eager\n // GeometryRendererTask depth outputs (both `_eager`), and on an undefined\n // rst/depth — so these can be passed unconditionally.\n disposeRenderTarget(config.rt);\n disposeRenderTarget(config.rst);\n disposeRenderTarget(config.depth);\n task._opaqueBindings.length = 0;\n task._directBindings.length = 0;\n task._transparentBindings.length = 0;\n task._renderables.length = 0;\n task._opaqueBundles.length = 0;\n task._sceneUBO.destroy();\n for (const batch of task._updateBatches) {\n batch.destroy();\n }\n task._updateBatches.length = 0;\n },\n };\n return task;\n}\n\n/** Remove a mesh from this task's renderable + binding lists. Idempotent. */\nexport function removeMeshFromTask(task: RenderTask, mesh: object): void {\n // Not a renderable-bearing task (e.g. a post/effect task that also carries `_config`): nothing to\n // remove. Guard keeps callers that scan all frame-graph tasks (removeFromScene) shape-safe.\n if (!task._renderables) {\n return;\n }\n let removed = false;\n for (let i = task._pendingMeshes.length - 1; i >= 0; i--) {\n if (task._pendingMeshes[i]!.mesh === mesh) {\n task._pendingMeshes.splice(i, 1);\n removed = true;\n }\n }\n for (let i = task._renderables.length - 1; i >= 0; i--) {\n if (task._renderables[i]!.mesh === mesh) {\n task._renderables.splice(i, 1);\n removed = true;\n }\n }\n for (const arr of [task._opaqueBindings, task._directBindings, task._transparentBindings]) {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (arr[i]!.renderable.mesh === mesh) {\n arr.splice(i, 1);\n removed = true;\n }\n }\n }\n if (removed) {\n task._opaqueBundles.length = 0;\n task._lastVersion = -1;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction resolvePendingMeshes(task: RenderTask, sc: SceneContext): void {\n if (!task._pendingMeshes.length) {\n return;\n }\n for (const { mesh, material } of task._pendingMeshes) {\n const builder = material._buildGroup;\n const group = sc._groups.get(builder);\n const rebuild = group ? group.r : builder._rebuildSingle;\n if (!rebuild) {\n throw Error();\n }\n const renderable = rebuild(sc, mesh, material);\n if (!task._renderables.includes(renderable)) {\n task._renderables.push(renderable);\n }\n }\n task._pendingMeshes.length = 0;\n}\n\n/** Per-frame back-to-front sort for transparent bindings using the active camera. */\nfunction sortTransparentBindings(task: RenderTask, camera: Camera | null | undefined): void {\n const arr = task._transparentBindings;\n if (arr.length <= 1 || !camera) {\n return;\n }\n const v = getViewMatrix(camera);\n for (const b of arr) {\n const wc = b.renderable._worldCenter;\n b._sortDistance = wc ? wc[0]! * v[2]! + wc[1]! * v[6]! + wc[2]! * v[10]! + v[14]! : 0;\n }\n arr.sort((a, b) => b._sortDistance! - a._sortDistance! || a.renderable.order - b.renderable.order);\n}\n\n/** (Re)bucket task._renderables into bound lists. */\nfunction buildBindings(task: RenderTask, eng: EngineContext, targetSignature: RenderTargetSignature): void {\n const opaque = task._opaqueBindings;\n const direct = task._directBindings;\n const transparent = task._transparentBindings;\n opaque.length = 0;\n direct.length = 0;\n transparent.length = 0;\n for (const r of task._renderables) {\n const binding = r.bind(eng, targetSignature);\n for (const batch of binding._updateBatches ?? []) {\n if (!task._updateBatches.includes(batch)) {\n task._updateBatches.push(batch);\n }\n }\n if (r.isTransparent || r._transmissive) {\n transparent.push(binding);\n } else if (r._direct) {\n direct.push(binding);\n } else {\n opaque.push(binding);\n }\n }\n opaque.sort((a, b) => a.renderable.order - b.renderable.order);\n direct.sort((a, b) => a.renderable.order - b.renderable.order);\n task._opaqueBundles.length = 0;\n task._lastVersion = (task.scene as SceneContext)._renderableVersion;\n}\n\nfunction buildRenderPassDescriptor(task: RenderTask, rt: RenderTarget): void {\n const att = task._colorAttachment;\n att.view = rt._colorView!;\n // End-of-pass MSAA resolve into a caller-supplied single-sample target.\n // record() only builds the target's color view for an MSAA rt, so its\n // presence is the gate. The swapchain case is wired per-frame in\n // executePass (its view changes each frame); this custom view is stable.\n att.resolveTarget = task._config.rst?._colorView ?? undefined;\n task._renderPassDescriptor.colorAttachments = rt._colorView ? [att] : [];\n\n const depthSrc = task._depthSrc ?? rt;\n const depthView = depthSrc._depthView;\n let depthAttachment: GPURenderPassDepthStencilAttachment | undefined;\n if (depthView) {\n const dd = depthSrc._descriptor;\n const loadOp = task._depthLoadOp ?? \"clear\";\n depthAttachment = {\n view: depthView,\n depthClearValue: dd._depthClearValue ?? 0,\n depthLoadOp: loadOp,\n depthStoreOp: \"store\",\n };\n if (dd.dFormat?.includes(\"stencil\")) {\n depthAttachment.stencilClearValue = 0;\n depthAttachment.stencilLoadOp = loadOp;\n depthAttachment.stencilStoreOp = \"store\";\n }\n }\n\n task._renderPassDescriptor.depthStencilAttachment = depthAttachment;\n}\n\nfunction prepareRenderTaskPass(task: RenderTask, eng: EngineContext, targetSignature: RenderTargetSignature, context: DrawUpdateContext): void {\n const sc = task.scene as SceneContext;\n // Auto-resync when the source scene mutates.\n if (task._autoFromScene && task._lastVersion !== sc._renderableVersion) {\n task._renderables.length = 0;\n task._renderables.push(...sc._renderables);\n buildBindings(task, eng, targetSignature);\n }\n\n // Pre-pass work — runs before beginRenderPass. Updates the task-owned scene\n // UBO, scene-wide lights UBO, and per-binding UBOs. The scene bind group may\n // also need a refresh (lights buffer can be resized when glTF lights\n // extension raises MAX_LIGHTS after this task was first recorded).\n refreshTaskSceneBindGroup(task, eng);\n const camera = task._config.cam ?? sc.camera;\n if (!task._config._skipClusteredLights && targetSignature._colorFormat) {\n sc._clusteredLightUpdater?.(camera, context.targetWidth, context.targetHeight);\n }\n _writePassSceneUBO(task, eng, sc, camera);\n refreshSceneLightsUBO(eng, sc);\n // Expose the active camera to per-binding `update()` calls. Some renderables\n // (e.g. transparent billboard systems) need it to compute view-space sort\n // depths during their update.\n (context as MutableDrawUpdateContext)._camera = camera;\n for (const batch of task._updateBatches) {\n batch.reset();\n }\n updateBindings(task._opaqueBindings, context);\n updateBindings(task._directBindings, context);\n updateBindings(task._transparentBindings, context);\n for (const batch of task._updateBatches) {\n batch.flush(eng);\n }\n // Per-frame back-to-front sort for transparent bindings — must run AFTER\n // updateBindings so renderables that compute `_worldCenter` inside their\n // own `update()` (billboard systems) are seen with current values.\n sortTransparentBindings(task, camera);\n}\n\nfunction executePass(task: RenderTask, eng: EngineContext, targetSignature: RenderTargetSignature, context: DrawUpdateContext): number {\n const sc = task.scene;\n const sampleCount = targetSignature._sampleCount;\n prepareRenderTaskPass(task, eng, targetSignature, context);\n const att = task._colorAttachment;\n const cfg = task._config;\n if (cfg.rt._colorView) {\n // The engine scRT's color view is re-acquired every frame, so re-read\n // it here. Offscreen color views are stable between rebuilds — leaving att.view\n // untouched preserves an external override (swapchain-overlay shares the base\n // scene's MSAA color view). The resolve target (rst) is re-read each frame so an\n // `rst === scRT` picks up its fresh per-frame view.\n if (cfg.rt === eng.scRT) {\n att.view = cfg.rt._colorView;\n }\n att.resolveTarget = cfg.rst?._colorView ?? undefined;\n att.clearValue = task._autoFromScene ? sc.clearColor : cfg.clrColor!;\n att.loadOp = cfg.clr ? \"clear\" : \"load\";\n }\n if (task._executeWithTransmission) {\n return task._executeWithTransmission(sampleCount);\n }\n const pass = eng._currentEncoder.beginRenderPass(task._renderPassDescriptor);\n const draws = executePassBody(task, pass);\n pass.end();\n return draws;\n}\n\n/** Body of the registered `RenderPass`. Receives the live render-pass encoder\n * and issues all draws (viewport/scissor, group(0) bind, opaque bundle replay,\n * then direct-draws non-transparent direct + transparent). Returns the draw count. */\nfunction executePassBody(task: RenderTask, pass: GPURenderPassEncoder): number {\n const eng = task.engine as EngineContext;\n const cfg = task._config;\n const rt = cfg.rt;\n const scene = task.scene as SceneContext;\n const opaqueBindings = task._opaqueBindings;\n const opaqueBundles = task._opaqueBundles;\n const sceneBG = task._sceneBG;\n\n const camera = cfg.cam ?? scene.camera;\n const v = camera?.viewport;\n if (v) {\n const rw = rt._width;\n const rh = rt._height;\n const x = Math.floor(v.x * rw);\n const y = Math.floor((1 - v.y - v.height) * rh);\n const w = Math.ceil((v.x + v.width) * rw) - x;\n const h = Math.ceil((1 - v.y) * rh) - y;\n pass.setViewport(x, y, w, h, 0, 1);\n pass.setScissorRect(x, y, w, h);\n }\n // Scene bind group (group 0) is task-owned and identical for every draw in this pass.\n pass.setBindGroup(0, sceneBG);\n\n // Opaque: cached render bundle. Invalidated by scene mutation (_renderableVersion) or\n // the global visibility/resource epoch (_vis). The bundle records group(0) at its start.\n if (task._lastVersion !== scene._renderableVersion || task._lastVis !== _vis || !opaqueBundles.length) {\n const desc = rt._descriptor;\n const be = eng._device.createRenderBundleEncoder({\n colorFormats: desc.format ? [desc.format] : [],\n // Use the task's target signature, not the RT descriptor: a depth\n // override (config.depth) supplies the depth format externally, so\n // the cached opaque pipelines are built with it while the colour RT\n // carries no depthStencilFormat of its own. The bundle encoder's\n // attachment state must match those pipelines exactly.\n depthStencilFormat: task._targetSignature._depthStencilFormat,\n sampleCount: desc.samples ?? 1,\n });\n be.setBindGroup(0, sceneBG);\n drawList(be, opaqueBindings, eng);\n opaqueBundles[0] = be.finish();\n task._lastVersion = scene._renderableVersion;\n task._lastVis = _vis;\n }\n let draws = opaqueBindings.length;\n pass.executeBundles(opaqueBundles);\n // executeBundles invalidates pass bind-group state — rebind group 0 before further draws.\n pass.setBindGroup(0, sceneBG);\n draws += drawList(pass, task._directBindings, eng);\n draws += drawList(pass, task._transparentBindings, eng);\n return draws;\n}\n\nfunction refreshTaskSceneBindGroup(task: RenderTask, eng: EngineContext): void {\n const lightsUBO = ensureSceneLightState(eng, task.scene as SceneContext)._buffer;\n if (lightsUBO === task._lightsUBO) {\n return;\n }\n task._lightsUBO = lightsUBO;\n task._sceneBG = eng._device.createBindGroup({\n layout: getSceneBindGroupLayout(eng),\n entries: [\n { binding: 0, resource: { buffer: task._sceneUBO } },\n { binding: 1, resource: { buffer: lightsUBO } },\n ],\n });\n task._opaqueBundles.length = 0;\n task._lastVersion = -1;\n}\n\n/** Write the canonical SceneUniforms struct to the task-owned scene UBO.\n * Bails before touching scratch/GPU when all inputs are unchanged.\n * @internal Exported for unit testing of the scene-UBO change-detection guard. */\nexport function _writePassSceneUBO(task: RenderTask, eng: EngineContext, scene: SceneContext, camera: Camera | null): void {\n if (!camera) {\n return;\n }\n\n const v = camera.viewport;\n const rt = task._config.rt;\n const aspect = (task._config.cs ? eng.canvas.width / eng.canvas.height : rt._width / rt._height) * (v ? v.width / v.height : 1);\n const fog = scene.fog;\n const img = scene.imageProcessing;\n const envRotationY = scene.envRotationY || 0;\n const wv = camera.worldMatrixVersion;\n // `envTextures` identity is tracked so an environment loaded (or swapped) AFTER the scene has reached\n // steady state invalidates this cache. Its spherical-harmonics irradiance and `lodGenerationScale` are\n // written into the scene UBO below (via `_packSceneUniforms` + the env-SH contributor); without tracking\n // it, a late env load would change none of the other guarded inputs, so the UBO would never be rewritten\n // and the model would keep zero irradiance (dark diffuse, specular-only \"mirror\" look).\n const envTextures = scene._envTextures;\n const s = task._su;\n if (s[0] === camera && s[1] === fog && s[2] === wv && s[3] === aspect && s[4] === envRotationY && s[5] === img.exposure && s[6] === img.contrast && s[7] === envTextures) {\n return;\n }\n s[0] = camera;\n s[1] = fog;\n s[2] = wv;\n s[3] = aspect;\n s[4] = envRotationY;\n s[5] = img.exposure;\n s[6] = img.contrast;\n s[7] = envTextures;\n\n const data = task._suData;\n _packSceneUniforms(data, eng, scene, camera, aspect);\n const contribs = scene._sceneUboContributors;\n if (contribs) {\n for (const c of contribs) {\n c(data, scene);\n }\n }\n eng._device.queue.writeBuffer(task._sceneUBO, 0, data as Float32Array<ArrayBuffer>);\n}\n\nfunction updateBindings(list: readonly DrawBinding[], context: DrawUpdateContext): void {\n for (const b of list) {\n b.update?.(context);\n }\n}\n\n/** @internal Iterate DrawBindings, deduping setPipeline. */\nexport function drawList(enc: GPURenderPassEncoder | GPURenderBundleEncoder, list: readonly DrawBinding[], engine: EngineContext): number {\n let lp: GPURenderPipeline | null = null;\n let draws = 0;\n for (const b of list) {\n const mesh = b.renderable.mesh;\n if (mesh && mesh.visible === false) {\n continue;\n }\n if (b.pipeline !== lp) {\n enc.setPipeline(b.pipeline);\n lp = b.pipeline;\n }\n draws += b.draw(enc, engine);\n }\n return draws;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAuLO,SAAS,gBAAA,CAAiB,MAAA,EAA0B,MAAA,EAAuB,KAAA,EAAiC;AAC/G,EAAA,MAAM,EAAA,GAAK,KAAA;AACX,EAAA,MAAA,CAAO,QAAA,KAAa,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,CAAA,EAAI;AACrD,EAAA,MAAA,CAAO,GAAA,KAAQ,IAAA;AACf,EAAA,MAAM,IAAA,GAAO,OAAO,EAAA,CAAG,WAAA;AAIvB,EAAA,MAAM,eAAA,GAAkB;AAAA,IACpB,cAAc,IAAA,CAAK,MAAA;AAAA,IACnB,mBAAA,EAAqB,MAAA,CAAO,KAAA,EAAO,WAAA,CAAY,WAAW,IAAA,CAAK,OAAA;AAAA,IAC/D,eAAe,IAAA,CAAK,aAAA;AAAA,IACpB,YAAA,EAAc,KAAK,OAAA,IAAW;AAAA,GAClC;AAEA,EAAA,MAAM,QAAA,GAAW,wBAAwB,MAAM,CAAA;AAC/C,EAAA,MAAM,QAAA,GAAW,wBAAA,CAAyB,MAAA,EAAQ,eAAe,CAAA;AACjE,EAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,MAAA,EAAQ,EAAE,CAAA,CAAE,OAAA;AACpD,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,eAAA,CAAgB;AAAA,IAC3C,MAAA,EAAQ,QAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACL,EAAE,OAAA,EAAS,CAAA,EAAG,UAAU,EAAE,MAAA,EAAQ,UAAS,EAAE;AAAA,MAC7C,EAAE,OAAA,EAAS,CAAA,EAAG,UAAU,EAAE,MAAA,EAAQ,WAAU;AAAE;AAClD,GACH,CAAA;AACD,EAAA,MAAM,eAAA,GAAkB,EAAE,MAAA,EAAQ,OAAA,EAAS,SAAS,OAAA,EAAQ;AAC5D,EAAA,MAAM,aAAA,GAA0C,EAAE,WAAA,EAAa,CAAA,EAAG,cAAc,CAAA,EAAE;AAClF,EAAA,MAAM,IAAA,GAAmB;AAAA,IACrB,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,OAAA,EAAS,MAAA;AAAA,IACT,MAAA;AAAA,IACA,KAAA,EAAO,EAAA;AAAA,IACP,SAAS,EAAC;AAAA,IACV,cAAA,EAAgB,KAAA;AAAA,IAChB,cAAc,EAAC;AAAA,IACf,iBAAiB,EAAC;AAAA,IAClB,iBAAiB,EAAC;AAAA,IAClB,sBAAsB,EAAC;AAAA,IACvB,gBAAgB,EAAC;AAAA,IACjB,YAAA,EAAc,EAAA;AAAA,IACd,QAAA,EAAU,CAAA;AAAA,IACV,SAAA,EAAW,KAAA;AAAA,IACX,qBAAA,EAAuB,EAAE,gBAAA,EAAkB,CAAC,eAAe,CAAA,EAAE;AAAA,IAC7D,gBAAA,EAAkB,eAAA;AAAA,IAClB,WAAW,MAAA,CAAO,KAAA;AAAA,IAClB,cAAc,MAAA,CAAO,KAAA,GAAS,OAAO,KAAA,CAAM,MAAA,GAAS,SAAS,OAAA,GAAW,MAAA;AAAA,IACxE,SAAA,EAAW,QAAA;AAAA,IACX,QAAA,EAAU,OAAA;AAAA,IACV,UAAA,EAAY,SAAA;AAAA,IACZ,OAAA,EAAS,IAAI,GAAA,CAAI,eAAA,GAAkB,CAAC,CAAA;AAAA,IACpC,KAAK,EAAC;AAAA,IACN,gBAAA,EAAkB,eAAA;AAAA,IAClB,gBAAgB,EAAC;AAAA,IACjB,gBAAgB,EAAC;AAAA,IACjB,OAAA,CAAQ,MAAM,IAAA,EAAM;AAChB,MAAA,MAAM,QAAA,GAAW,IAAA,EAAM,QAAA,IAAY,IAAA,CAAK,QAAA;AACxC,MAAA,IAAI,CAAC,QAAA,EAAU;AACX,QAAA;AAAA,MACJ;AACA,MAAA,IAAA,CAAK,cAAA,CAAe,IAAA,CAAK,EAAE,IAAA,EAAM,UAAU,CAAA;AAC3C,MAAA,IAAI,KAAK,SAAA,EAAW;AAIhB,QAAA,oBAAA,CAAqB,MAAM,EAAE,CAAA;AAI7B,QAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,QAAA,aAAA,CAAc,IAAA,EAAM,QAAQ,eAAe,CAAA;AAAA,MAC/C;AAAA,IACJ,CAAA;AAAA,IACA,MAAA,GAAe;AACX,MAAA,IAAI,KAAK,cAAA,EAAgB;AACrB,QAAA,IAAA,CAAK,aAAa,MAAA,GAAS,CAAA;AAAA,MAC/B;AACA,MAAA,oBAAA,CAAqB,MAAM,EAAE,CAAA;AAC7B,MAAA,IAAA,CAAK,cAAA,GAAiB,CAAC,IAAA,CAAK,YAAA,CAAa,MAAA;AACzC,MAAA,IAAI,KAAK,cAAA,EAAgB;AACrB,QAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,GAAG,EAAA,CAAG,YAAY,CAAA;AAAA,MAC7C;AAGA,MAAA,MAAM,KAAK,MAAA,CAAO,EAAA;AAClB,MAAA,iBAAA,CAAkB,IAAI,MAAM,CAAA;AAC5B,MAAA,IAAI,OAAO,GAAA,IAAA,CAAQ,EAAA,CAAG,WAAA,CAAY,OAAA,IAAW,KAAK,CAAA,EAAG;AACjD,QAAA,iBAAA,CAAkB,MAAA,CAAO,KAAK,MAAM,CAAA;AAAA,MACxC;AAKA,MAAA,IAAI,MAAA,CAAO,KAAA,IAAS,CAAC,MAAA,CAAO,MAAM,MAAA,EAAQ;AACtC,QAAA,iBAAA,CAAkB,MAAA,CAAO,OAAO,MAAM,CAAA;AAAA,MAC1C;AACA,MAAA,aAAA,CAAc,cAAc,EAAA,CAAG,MAAA;AAC/B,MAAA,aAAA,CAAc,eAAe,EAAA,CAAG,OAAA;AAChC,MAAA,yBAAA,CAA0B,MAAM,MAAM,CAAA;AACtC,MAAA,aAAA,CAAc,IAAA,EAAM,QAAQ,eAAe,CAAA;AAC3C,MAAA,yBAAA,CAA0B,MAAM,EAAE,CAAA;AAClC,MAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,IACrB,CAAA;AAAA,IACA,OAAA,GAAkB;AACd,MAAA,OAAO,WAAA,CAAY,IAAA,EAAM,MAAA,EAAQ,eAAA,EAAiB,aAAa,CAAA;AAAA,IACnE,CAAA;AAAA,IACA,OAAA,GAAgB;AACZ,MAAA,IAAA,CAAK,QAAQ,MAAA,GAAS,CAAA;AAItB,MAAA,mBAAA,CAAoB,OAAO,EAAE,CAAA;AAC7B,MAAA,mBAAA,CAAoB,OAAO,GAAG,CAAA;AAC9B,MAAA,mBAAA,CAAoB,OAAO,KAAK,CAAA;AAChC,MAAA,IAAA,CAAK,gBAAgB,MAAA,GAAS,CAAA;AAC9B,MAAA,IAAA,CAAK,gBAAgB,MAAA,GAAS,CAAA;AAC9B,MAAA,IAAA,CAAK,qBAAqB,MAAA,GAAS,CAAA;AACnC,MAAA,IAAA,CAAK,aAAa,MAAA,GAAS,CAAA;AAC3B,MAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,MAAA,IAAA,CAAK,UAAU,OAAA,EAAQ;AACvB,MAAA,KAAA,MAAW,KAAA,IAAS,KAAK,cAAA,EAAgB;AACrC,QAAA,KAAA,CAAM,OAAA,EAAQ;AAAA,MAClB;AACA,MAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAAA,IACjC;AAAA,GACJ;AACA,EAAA,OAAO,IAAA;AACX;AAGO,SAAS,kBAAA,CAAmB,MAAkB,IAAA,EAAoB;AAGrE,EAAA,IAAI,CAAC,KAAK,YAAA,EAAc;AACpB,IAAA;AAAA,EACJ;AACA,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,KAAA,IAAS,IAAI,IAAA,CAAK,cAAA,CAAe,SAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACtD,IAAA,IAAI,IAAA,CAAK,cAAA,CAAe,CAAC,CAAA,CAAG,SAAS,IAAA,EAAM;AACvC,MAAA,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA;AAC/B,MAAA,OAAA,GAAU,IAAA;AAAA,IACd;AAAA,EACJ;AACA,EAAA,KAAA,IAAS,IAAI,IAAA,CAAK,YAAA,CAAa,SAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACpD,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,CAAC,CAAA,CAAG,SAAS,IAAA,EAAM;AACrC,MAAA,IAAA,CAAK,YAAA,CAAa,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA;AAC7B,MAAA,OAAA,GAAU,IAAA;AAAA,IACd;AAAA,EACJ;AACA,EAAA,KAAA,MAAW,GAAA,IAAO,CAAC,IAAA,CAAK,eAAA,EAAiB,KAAK,eAAA,EAAiB,IAAA,CAAK,oBAAoB,CAAA,EAAG;AACvF,IAAA,KAAA,IAAS,IAAI,GAAA,CAAI,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AACtC,MAAA,IAAI,GAAA,CAAI,CAAC,CAAA,CAAG,UAAA,CAAW,SAAS,IAAA,EAAM;AAClC,QAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAC,CAAA;AACf,QAAA,OAAA,GAAU,IAAA;AAAA,MACd;AAAA,IACJ;AAAA,EACJ;AACA,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,IAAA,IAAA,CAAK,YAAA,GAAe,EAAA;AAAA,EACxB;AACJ;AAIA,SAAS,oBAAA,CAAqB,MAAkB,EAAA,EAAwB;AACpE,EAAA,IAAI,CAAC,IAAA,CAAK,cAAA,CAAe,MAAA,EAAQ;AAC7B,IAAA;AAAA,EACJ;AACA,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,QAAA,EAAS,IAAK,KAAK,cAAA,EAAgB;AAClD,IAAA,MAAM,UAAU,QAAA,CAAS,WAAA;AACzB,IAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA;AACpC,IAAA,MAAM,OAAA,GAAU,KAAA,GAAQ,KAAA,CAAM,CAAA,GAAI,OAAA,CAAQ,cAAA;AAC1C,IAAA,IAAI,CAAC,OAAA,EAAS;AACV,MAAA,MAAM,KAAA,EAAM;AAAA,IAChB;AACA,IAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,EAAA,EAAI,IAAA,EAAM,QAAQ,CAAA;AAC7C,IAAA,IAAI,CAAC,IAAA,CAAK,YAAA,CAAa,QAAA,CAAS,UAAU,CAAA,EAAG;AACzC,MAAA,IAAA,CAAK,YAAA,CAAa,KAAK,UAAU,CAAA;AAAA,IACrC;AAAA,EACJ;AACA,EAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AACjC;AAGA,SAAS,uBAAA,CAAwB,MAAkB,MAAA,EAAyC;AACxF,EAAA,MAAM,MAAM,IAAA,CAAK,oBAAA;AACjB,EAAA,IAAI,GAAA,CAAI,MAAA,IAAU,CAAA,IAAK,CAAC,MAAA,EAAQ;AAC5B,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,CAAA,GAAI,cAAc,MAAM,CAAA;AAC9B,EAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACjB,IAAA,MAAM,EAAA,GAAK,EAAE,UAAA,CAAW,YAAA;AACxB,IAAA,CAAA,CAAE,aAAA,GAAgB,KAAK,EAAA,CAAG,CAAC,IAAK,CAAA,CAAE,CAAC,CAAA,GAAK,EAAA,CAAG,CAAC,CAAA,GAAK,EAAE,CAAC,CAAA,GAAK,GAAG,CAAC,CAAA,GAAK,EAAE,EAAE,CAAA,GAAK,CAAA,CAAE,EAAE,CAAA,GAAK,CAAA;AAAA,EACxF;AACA,EAAA,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,aAAA,GAAiB,CAAA,CAAE,aAAA,IAAkB,CAAA,CAAE,UAAA,CAAW,KAAA,GAAQ,CAAA,CAAE,WAAW,KAAK,CAAA;AACrG;AAGA,SAAS,aAAA,CAAc,IAAA,EAAkB,GAAA,EAAoB,eAAA,EAA8C;AACvG,EAAA,MAAM,SAAS,IAAA,CAAK,eAAA;AACpB,EAAA,MAAM,SAAS,IAAA,CAAK,eAAA;AACpB,EAAA,MAAM,cAAc,IAAA,CAAK,oBAAA;AACzB,EAAA,MAAA,CAAO,MAAA,GAAS,CAAA;AAChB,EAAA,MAAA,CAAO,MAAA,GAAS,CAAA;AAChB,EAAA,WAAA,CAAY,MAAA,GAAS,CAAA;AACrB,EAAA,KAAA,MAAW,CAAA,IAAK,KAAK,YAAA,EAAc;AAC/B,IAAA,MAAM,OAAA,GAAU,CAAA,CAAE,IAAA,CAAK,GAAA,EAAK,eAAe,CAAA;AAC3C,IAAA,KAAA,MAAW,KAAA,IAAS,OAAA,CAAQ,cAAA,IAAkB,EAAC,EAAG;AAC9C,MAAA,IAAI,CAAC,IAAA,CAAK,cAAA,CAAe,QAAA,CAAS,KAAK,CAAA,EAAG;AACtC,QAAA,IAAA,CAAK,cAAA,CAAe,KAAK,KAAK,CAAA;AAAA,MAClC;AAAA,IACJ;AACA,IAAA,IAAI,CAAA,CAAE,aAAA,IAAiB,CAAA,CAAE,aAAA,EAAe;AACpC,MAAA,WAAA,CAAY,KAAK,OAAO,CAAA;AAAA,IAC5B,CAAA,MAAA,IAAW,EAAE,OAAA,EAAS;AAClB,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,IACvB,CAAA,MAAO;AACH,MAAA,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,IACvB;AAAA,EACJ;AACA,EAAA,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,UAAA,CAAW,KAAA,GAAQ,CAAA,CAAE,UAAA,CAAW,KAAK,CAAA;AAC7D,EAAA,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,UAAA,CAAW,KAAA,GAAQ,CAAA,CAAE,UAAA,CAAW,KAAK,CAAA;AAC7D,EAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,EAAA,IAAA,CAAK,YAAA,GAAgB,KAAK,KAAA,CAAuB,kBAAA;AACrD;AAEA,SAAS,yBAAA,CAA0B,MAAkB,EAAA,EAAwB;AACzE,EAAA,MAAM,MAAM,IAAA,CAAK,gBAAA;AACjB,EAAA,GAAA,CAAI,OAAO,EAAA,CAAG,UAAA;AAKd,EAAA,GAAA,CAAI,aAAA,GAAgB,IAAA,CAAK,OAAA,CAAQ,GAAA,EAAK,UAAA,IAAc,MAAA;AACpD,EAAA,IAAA,CAAK,sBAAsB,gBAAA,GAAmB,EAAA,CAAG,aAAa,CAAC,GAAG,IAAI,EAAC;AAEvE,EAAA,MAAM,QAAA,GAAW,KAAK,SAAA,IAAa,EAAA;AACnC,EAAA,MAAM,YAAY,QAAA,CAAS,UAAA;AAC3B,EAAA,IAAI,eAAA;AACJ,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,MAAM,KAAK,QAAA,CAAS,WAAA;AACpB,IAAA,MAAM,MAAA,GAAS,KAAK,YAAA,IAAgB,OAAA;AACpC,IAAA,eAAA,GAAkB;AAAA,MACd,IAAA,EAAM,SAAA;AAAA,MACN,eAAA,EAAiB,GAAG,gBAAA,IAAoB,CAAA;AAAA,MACxC,WAAA,EAAa,MAAA;AAAA,MACb,YAAA,EAAc;AAAA,KAClB;AACA,IAAA,IAAI,EAAA,CAAG,OAAA,EAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AACjC,MAAA,eAAA,CAAgB,iBAAA,GAAoB,CAAA;AACpC,MAAA,eAAA,CAAgB,aAAA,GAAgB,MAAA;AAChC,MAAA,eAAA,CAAgB,cAAA,GAAiB,OAAA;AAAA,IACrC;AAAA,EACJ;AAEA,EAAA,IAAA,CAAK,sBAAsB,sBAAA,GAAyB,eAAA;AACxD;AAEA,SAAS,qBAAA,CAAsB,IAAA,EAAkB,GAAA,EAAoB,eAAA,EAAwC,OAAA,EAAkC;AAC3I,EAAA,MAAM,KAAK,IAAA,CAAK,KAAA;AAEhB,EAAA,IAAI,IAAA,CAAK,cAAA,IAAkB,IAAA,CAAK,YAAA,KAAiB,GAAG,kBAAA,EAAoB;AACpE,IAAA,IAAA,CAAK,aAAa,MAAA,GAAS,CAAA;AAC3B,IAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,GAAG,EAAA,CAAG,YAAY,CAAA;AACzC,IAAA,aAAA,CAAc,IAAA,EAAM,KAAK,eAAe,CAAA;AAAA,EAC5C;AAMA,EAAA,yBAAA,CAA0B,MAAM,GAAG,CAAA;AACnC,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,EAAA,CAAG,MAAA;AACtC,EAAA,IAAI,CAAC,IAAA,CAAK,OAAA,CAAQ,oBAAA,IAAwB,gBAAgB,YAAA,EAAc;AACpE,IAAA,EAAA,CAAG,sBAAA,GAAyB,MAAA,EAAQ,OAAA,CAAQ,WAAA,EAAa,QAAQ,YAAY,CAAA;AAAA,EACjF;AACA,EAAA,kBAAA,CAAmB,IAAA,EAAM,GAAA,EAAK,EAAA,EAAI,MAAM,CAAA;AACxC,EAAA,qBAAA,CAAsB,KAAK,EAAE,CAAA;AAI7B,EAAC,QAAqC,OAAA,GAAU,MAAA;AAChD,EAAA,KAAA,MAAW,KAAA,IAAS,KAAK,cAAA,EAAgB;AACrC,IAAA,KAAA,CAAM,KAAA,EAAM;AAAA,EAChB;AACA,EAAA,cAAA,CAAe,IAAA,CAAK,iBAAiB,OAAO,CAAA;AAC5C,EAAA,cAAA,CAAe,IAAA,CAAK,iBAAiB,OAAO,CAAA;AAC5C,EAAA,cAAA,CAAe,IAAA,CAAK,sBAAsB,OAAO,CAAA;AACjD,EAAA,KAAA,MAAW,KAAA,IAAS,KAAK,cAAA,EAAgB;AACrC,IAAA,KAAA,CAAM,MAAM,GAAG,CAAA;AAAA,EACnB;AAIA,EAAA,uBAAA,CAAwB,MAAM,MAAM,CAAA;AACxC;AAEA,SAAS,WAAA,CAAY,IAAA,EAAkB,GAAA,EAAoB,eAAA,EAAwC,OAAA,EAAoC;AACnI,EAAA,MAAM,KAAK,IAAA,CAAK,KAAA;AAChB,EAAA,MAAM,cAAc,eAAA,CAAgB,YAAA;AACpC,EAAA,qBAAA,CAAsB,IAAA,EAAM,GAAA,EAAK,eAAA,EAAiB,OAAO,CAAA;AACzD,EAAA,MAAM,MAAM,IAAA,CAAK,gBAAA;AACjB,EAAA,MAAM,MAAM,IAAA,CAAK,OAAA;AACjB,EAAA,IAAI,GAAA,CAAI,GAAG,UAAA,EAAY;AAMnB,IAAA,IAAI,GAAA,CAAI,EAAA,KAAO,GAAA,CAAI,IAAA,EAAM;AACrB,MAAA,GAAA,CAAI,IAAA,GAAO,IAAI,EAAA,CAAG,UAAA;AAAA,IACtB;AACA,IAAA,GAAA,CAAI,aAAA,GAAgB,GAAA,CAAI,GAAA,EAAK,UAAA,IAAc,MAAA;AAC3C,IAAA,GAAA,CAAI,UAAA,GAAa,IAAA,CAAK,cAAA,GAAiB,EAAA,CAAG,aAAa,GAAA,CAAI,QAAA;AAC3D,IAAA,GAAA,CAAI,MAAA,GAAS,GAAA,CAAI,GAAA,GAAM,OAAA,GAAU,MAAA;AAAA,EACrC;AACA,EAAA,IAAI,KAAK,wBAAA,EAA0B;AAC/B,IAAA,OAAO,IAAA,CAAK,yBAAyB,WAAW,CAAA;AAAA,EACpD;AACA,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,eAAA,CAAgB,eAAA,CAAgB,KAAK,qBAAqB,CAAA;AAC3E,EAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,EAAM,IAAI,CAAA;AACxC,EAAA,IAAA,CAAK,GAAA,EAAI;AACT,EAAA,OAAO,KAAA;AACX;AAKA,SAAS,eAAA,CAAgB,MAAkB,IAAA,EAAoC;AAC3E,EAAA,MAAM,MAAM,IAAA,CAAK,MAAA;AACjB,EAAA,MAAM,MAAM,IAAA,CAAK,OAAA;AACjB,EAAA,MAAM,KAAK,GAAA,CAAI,EAAA;AACf,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,EAAA,MAAM,iBAAiB,IAAA,CAAK,eAAA;AAC5B,EAAA,MAAM,gBAAgB,IAAA,CAAK,cAAA;AAC3B,EAAA,MAAM,UAAU,IAAA,CAAK,QAAA;AAErB,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,GAAA,IAAO,KAAA,CAAM,MAAA;AAChC,EAAA,MAAM,IAAI,MAAA,EAAQ,QAAA;AAClB,EAAA,IAAI,CAAA,EAAG;AACH,IAAA,MAAM,KAAK,EAAA,CAAG,MAAA;AACd,IAAA,MAAM,KAAK,EAAA,CAAG,OAAA;AACd,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAA,CAAE,IAAI,EAAE,CAAA;AAC7B,IAAA,MAAM,CAAA,GAAI,KAAK,KAAA,CAAA,CAAO,CAAA,GAAI,EAAE,CAAA,GAAI,CAAA,CAAE,UAAU,EAAE,CAAA;AAC9C,IAAA,MAAM,CAAA,GAAI,KAAK,IAAA,CAAA,CAAM,CAAA,CAAE,IAAI,CAAA,CAAE,KAAA,IAAS,EAAE,CAAA,GAAI,CAAA;AAC5C,IAAA,MAAM,IAAI,IAAA,CAAK,IAAA,CAAA,CAAM,IAAI,CAAA,CAAE,CAAA,IAAK,EAAE,CAAA,GAAI,CAAA;AACtC,IAAA,IAAA,CAAK,YAAY,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAC,CAAA;AACjC,IAAA,IAAA,CAAK,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA,EAClC;AAEA,EAAA,IAAA,CAAK,YAAA,CAAa,GAAG,OAAO,CAAA;AAI5B,EAAA,IAAI,IAAA,CAAK,iBAAiB,KAAA,CAAM,kBAAA,IAAsB,KAAK,QAAA,KAAa,IAAA,IAAQ,CAAC,aAAA,CAAc,MAAA,EAAQ;AACnG,IAAA,MAAM,OAAO,EAAA,CAAG,WAAA;AAChB,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,OAAA,CAAQ,yBAAA,CAA0B;AAAA,MAC7C,cAAc,IAAA,CAAK,MAAA,GAAS,CAAC,IAAA,CAAK,MAAM,IAAI,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAM7C,kBAAA,EAAoB,KAAK,gBAAA,CAAiB,mBAAA;AAAA,MAC1C,WAAA,EAAa,KAAK,OAAA,IAAW;AAAA,KAChC,CAAA;AACD,IAAA,EAAA,CAAG,YAAA,CAAa,GAAG,OAAO,CAAA;AAC1B,IAAA,QAAA,CAAS,EAAA,EAAI,gBAAgB,GAAG,CAAA;AAChC,IAAA,aAAA,CAAc,CAAC,CAAA,GAAI,EAAA,CAAG,MAAA,EAAO;AAC7B,IAAA,IAAA,CAAK,eAAe,KAAA,CAAM,kBAAA;AAC1B,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EACpB;AACA,EAAA,IAAI,QAAQ,cAAA,CAAe,MAAA;AAC3B,EAAA,IAAA,CAAK,eAAe,aAAa,CAAA;AAEjC,EAAA,IAAA,CAAK,YAAA,CAAa,GAAG,OAAO,CAAA;AAC5B,EAAA,KAAA,IAAS,QAAA,CAAS,IAAA,EAAM,IAAA,CAAK,eAAA,EAAiB,GAAG,CAAA;AACjD,EAAA,KAAA,IAAS,QAAA,CAAS,IAAA,EAAM,IAAA,CAAK,oBAAA,EAAsB,GAAG,CAAA;AACtD,EAAA,OAAO,KAAA;AACX;AAEA,SAAS,yBAAA,CAA0B,MAAkB,GAAA,EAA0B;AAC3E,EAAA,MAAM,SAAA,GAAY,qBAAA,CAAsB,GAAA,EAAK,IAAA,CAAK,KAAqB,CAAA,CAAE,OAAA;AACzE,EAAA,IAAI,SAAA,KAAc,KAAK,UAAA,EAAY;AAC/B,IAAA;AAAA,EACJ;AACA,EAAA,IAAA,CAAK,UAAA,GAAa,SAAA;AAClB,EAAA,IAAA,CAAK,QAAA,GAAW,GAAA,CAAI,OAAA,CAAQ,eAAA,CAAgB;AAAA,IACxC,MAAA,EAAQ,wBAAwB,GAAG,CAAA;AAAA,IACnC,OAAA,EAAS;AAAA,MACL,EAAE,SAAS,CAAA,EAAG,QAAA,EAAU,EAAE,MAAA,EAAQ,IAAA,CAAK,WAAU,EAAE;AAAA,MACnD,EAAE,OAAA,EAAS,CAAA,EAAG,UAAU,EAAE,MAAA,EAAQ,WAAU;AAAE;AAClD,GACH,CAAA;AACD,EAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,EAAA,IAAA,CAAK,YAAA,GAAe,EAAA;AACxB;AAKO,SAAS,kBAAA,CAAmB,IAAA,EAAkB,GAAA,EAAoB,KAAA,EAAqB,MAAA,EAA6B;AACvH,EAAA,IAAI,CAAC,MAAA,EAAQ;AACT,IAAA;AAAA,EACJ;AAEA,EAAA,MAAM,IAAI,MAAA,CAAO,QAAA;AACjB,EAAA,MAAM,EAAA,GAAK,KAAK,OAAA,CAAQ,EAAA;AACxB,EAAA,MAAM,UAAU,IAAA,CAAK,OAAA,CAAQ,KAAK,GAAA,CAAI,MAAA,CAAO,QAAQ,GAAA,CAAI,MAAA,CAAO,MAAA,GAAS,EAAA,CAAG,SAAS,EAAA,CAAG,OAAA,KAAY,IAAI,CAAA,CAAE,KAAA,GAAQ,EAAE,MAAA,GAAS,CAAA,CAAA;AAC7H,EAAA,MAAM,MAAM,KAAA,CAAM,GAAA;AAClB,EAAA,MAAM,MAAM,KAAA,CAAM,eAAA;AAClB,EAAA,MAAM,YAAA,GAAe,MAAM,YAAA,IAAgB,CAAA;AAC3C,EAAA,MAAM,KAAK,MAAA,CAAO,kBAAA;AAMlB,EAAA,MAAM,cAAc,KAAA,CAAM,YAAA;AAC1B,EAAA,MAAM,IAAI,IAAA,CAAK,GAAA;AACf,EAAA,IAAI,CAAA,CAAE,CAAC,CAAA,KAAM,MAAA,IAAU,EAAE,CAAC,CAAA,KAAM,GAAA,IAAO,CAAA,CAAE,CAAC,CAAA,KAAM,EAAA,IAAM,CAAA,CAAE,CAAC,CAAA,KAAM,MAAA,IAAU,CAAA,CAAE,CAAC,CAAA,KAAM,YAAA,IAAgB,CAAA,CAAE,CAAC,MAAM,GAAA,CAAI,QAAA,IAAY,CAAA,CAAE,CAAC,MAAM,GAAA,CAAI,QAAA,IAAY,CAAA,CAAE,CAAC,MAAM,WAAA,EAAa;AACtK,IAAA;AAAA,EACJ;AACA,EAAA,CAAA,CAAE,CAAC,CAAA,GAAI,MAAA;AACP,EAAA,CAAA,CAAE,CAAC,CAAA,GAAI,GAAA;AACP,EAAA,CAAA,CAAE,CAAC,CAAA,GAAI,EAAA;AACP,EAAA,CAAA,CAAE,CAAC,CAAA,GAAI,MAAA;AACP,EAAA,CAAA,CAAE,CAAC,CAAA,GAAI,YAAA;AACP,EAAA,CAAA,CAAE,CAAC,IAAI,GAAA,CAAI,QAAA;AACX,EAAA,CAAA,CAAE,CAAC,IAAI,GAAA,CAAI,QAAA;AACX,EAAA,CAAA,CAAE,CAAC,CAAA,GAAI,WAAA;AAEP,EAAA,MAAM,OAAO,IAAA,CAAK,OAAA;AAClB,EAAA,kBAAA,CAAmB,IAAA,EAAM,GAAA,EAAK,KAAA,EAAO,MAAA,EAAQ,MAAM,CAAA;AACnD,EAAA,MAAM,WAAW,KAAA,CAAM,qBAAA;AACvB,EAAA,IAAI,QAAA,EAAU;AACV,IAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACtB,MAAA,CAAA,CAAE,MAAM,KAAK,CAAA;AAAA,IACjB;AAAA,EACJ;AACA,EAAA,GAAA,CAAI,QAAQ,KAAA,CAAM,WAAA,CAAY,IAAA,CAAK,SAAA,EAAW,GAAG,IAAiC,CAAA;AACtF;AAEA,SAAS,cAAA,CAAe,MAA8B,OAAA,EAAkC;AACpF,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AAClB,IAAA,CAAA,CAAE,SAAS,OAAO,CAAA;AAAA,EACtB;AACJ;AAGO,SAAS,QAAA,CAAS,GAAA,EAAoD,IAAA,EAA8B,MAAA,EAA+B;AACtI,EAAA,IAAI,EAAA,GAA+B,IAAA;AACnC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AAClB,IAAA,MAAM,IAAA,GAAO,EAAE,UAAA,CAAW,IAAA;AAC1B,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,OAAA,KAAY,KAAA,EAAO;AAChC,MAAA;AAAA,IACJ;AACA,IAAA,IAAI,CAAA,CAAE,aAAa,EAAA,EAAI;AACnB,MAAA,GAAA,CAAI,WAAA,CAAY,EAAE,QAAQ,CAAA;AAC1B,MAAA,EAAA,GAAK,CAAA,CAAE,QAAA;AAAA,IACX;AACA,IAAA,KAAA,IAAS,CAAA,CAAE,IAAA,CAAK,GAAA,EAAK,MAAM,CAAA;AAAA,EAC/B;AACA,EAAA,OAAO,KAAA;AACX;;;;"}
1
+ {"version":3,"file":"render-task.js","sources":["../../../src/frame-graph/render-task.ts"],"sourcesContent":["/**\n * RenderTask — a frame-graph task that records a single `RenderPass`,\n * binds the scene's `RenderTarget`, and draws renderables into it.\n *\n * - `record()` builds bucketed `DrawBinding` lists from `_renderables`\n * (opaque / direct / transparent), sorts opaque + direct by\n * `order`, then creates a `RenderPass` wired to the task's render target.\n * The pass owns its\n * `GPURenderPassDescriptor` and the per-pass-encoder body lives in a\n * closure passed to `setRenderPassExecuteFunc`.\n * - Before `RenderPass._execute()` begins the GPU pass: writes the scene UBO, refreshes lights, updates\n * per-binding UBOs, mirrors live `scene.clearColor` + `clr` onto the\n * render pass. Shared task execution then calls `_execute()`. The\n * `RenderPass` itself patches the swapchain view + clearColor + loadOp\n * and brackets the body with `beginRenderPass` / `end`.\n *\n * Renderable population:\n * - Explicit: push into `_renderables` directly, or `addMesh(mesh, opts)`\n * which builds a (mesh, material) Renderable at `record()` time.\n * - Auto scene mirror: when `_renderables` is empty at record() time, copy the\n * scene's renderables. Re-sync happens automatically when the scene's\n * `_renderableVersion` changes between frames (mesh add/remove, material swap).\n *\n * The engine `scRT` is just another `RenderTarget` here: a task that\n * targets it (`rt`) or resolves into it (`rst`) re-reads its per-frame color view\n * at execute time (the swap texture is re-acquired each frame). `clr: false`\n * switches color + depth `loadOp` to `\"load\"` so multiple scenes can share the\n * swapchain in one frame (e.g., a 3D scene + a UI overlay scene).\n */\n\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { _vis } from \"../engine/engine.js\";\nimport type { Mesh } from \"../mesh/mesh.js\";\nimport type { Camera } from \"../camera/camera.js\";\nimport type { Renderable, DrawBinding, DrawUpdateContext, DrawUpdateBatch } from \"../render/renderable.js\";\nimport type { RenderTargetSignature } from \"../engine/render-target.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport type { Material } from \"../material/material.js\";\nimport type { RenderTarget } from \"../engine/render-target.js\";\nimport { buildRenderTarget, disposeRenderTarget } from \"../engine/render-target.js\";\nimport { getViewMatrix, _cameraChangeKey } from \"../camera/camera.js\";\nimport { getSceneBindGroupLayout } from \"../render/scene-helpers.js\";\nimport { _packSceneUniforms } from \"./scene-uniforms-pack.js\";\nimport { createEmptyUniformBuffer } from \"../resource/gpu-buffers.js\";\nimport { SCENE_UBO_BYTES } from \"../shader/scene-uniforms-size.js\";\nimport { ensureSceneLightState, refreshSceneLightsUBO } from \"../render/lights-ubo.js\";\nimport type { Task } from \"./task.js\";\n\n/** Configuration for `createRenderTask`: render target, clear state, optional camera override, and transmission settings. */\nexport interface RenderTaskConfig {\n name: string;\n /** TODO: rt should not live in this config long-term. Until texture\n * management is virtualized, callers must provide the concrete target; once\n * virtualized, the task should create/manage its own render target. */\n rt: RenderTarget;\n /** Optional single-sample resolve target. When `rt` is multisampled\n * (`sampleCount > 1`), the color attachment resolves into this target's\n * color texture at end-of-pass — letting an MSAA render feed a post-process\n * that requires a single-sample source, without an extra resolve pass.\n * Caller contract (not validated): must be single-sample with a color\n * format and size matching `rt`; WebGPU errors at pass-encode time if not.\n * Ignored when `rt` is single-sample. */\n rst?: RenderTarget;\n /** Optional separate depth/stencil attachment. The pass binds this target's\n * depth view instead of `rt`'s own, and uses its `depthStencilFormat` for\n * pipeline signature matching. The colour `rt` must omit `depthStencilFormat`\n * (so it allocates no internal depth) and match this target in size + sample\n * count. Two ownership modes, distinguished by `_eager`:\n * - `_eager` depth (e.g. a `GeometryRendererTask` output): the task neither\n * builds nor clears nor disposes it — it loads it (`loadOp: \"load\"`) and the\n * caller owns clearing. This is how scenes reuse a pre-rendered depth buffer.\n * - non-`_eager` depth: the task owns it — builds/rebuilds it in `record()`,\n * clears it (`loadOp: \"clear\"`), and disposes it. Used by the default\n * single-sample scene task, whose colour `rt` is the depth-less\n * engine `scRT`. */\n depth?: RenderTarget;\n /** Background clear color. May be mutated frame-to-frame. */\n clrColor?: GPUColorDict;\n /** When true, color `loadOp` is \"clear\"; when false, \"load\" (overlays previous\n * color content). Depth is always cleared when rt-owned and always loaded when\n * supplied via `depth`. */\n clr?: boolean;\n /** Per-pass camera override. Null/undefined uses `scene.camera`. */\n cam?: Camera | null;\n /** Use canvas dimensions, not render-target dimensions, for this pass's scene UBO aspect. */\n cs?: boolean;\n /** Scene-texture transmission settings. `copyCount: 0` copies before every transmissive draw.\n * `generateMipmaps: false` allocates only mip 0 for the refraction texture and skips mip generation.\n * `mipLevelCount` caps the generated chain when a material only samples low explicit LODs.\n * `grabDepth: true` also snapshots the task's DEPTH attachment at the same mid-pass grab (see\n * `TransmissionOptions.grabDepth`). */\n transmission?: { copyCount?: number; generateMipmaps?: boolean; mipLevelCount?: number; grabDepth?: boolean };\n /** @internal Skip clustered-light preparation for passes that never run forward lighting. */\n _skipClusteredLights?: boolean;\n}\n\n/** A frame-graph task that records a single `RenderPass`, binds the scene's `RenderTarget`, and draws renderables into it. */\nexport interface RenderTask extends Task {\n readonly name: string;\n /** Render tasks are scene-bound because they consume scene camera, lights, and renderables. */\n readonly scene: SceneContext;\n /** Live task configuration. Mutating `clr` or `clrColor` affects subsequent frames. */\n /** @internal */\n readonly _config: RenderTaskConfig;\n /** @internal */\n _autoFromScene: boolean;\n\n /** Source-of-truth renderables. Bucketed binding lists below are derived from\n * this list at `record()` (or re-sync when auto-filled and `_renderableVersion` changes). */\n /** @internal */\n _renderables: Renderable[];\n /** @internal */\n _opaqueBindings: DrawBinding[];\n /** @internal */\n _directBindings: DrawBinding[];\n /** @internal */\n _transparentBindings: DrawBinding[];\n /** Cached opaque render bundle. Invalidated by renderable list mutations\n * (`_lastVersion`) and the global visibility/resource epoch (`_lastVis`). */\n /** @internal */\n _opaqueBundles: GPURenderBundle[];\n /** @internal */\n _lastVersion: number;\n /** @internal */\n _lastVis: number;\n /** @internal True once `record()` has run — the task is \"live\" (GPU target allocated, material batch builders\n * present). A runtime `addMesh` after this resolves + re-buckets THIS task immediately (no frame-graph rebuild). */\n _recorded: boolean;\n\n /** @internal */\n _renderPassDescriptor: GPURenderPassDescriptor;\n /** @internal */\n _colorAttachment: GPURenderPassColorAttachment;\n /** @internal External depth source from `config.depth`. When unset,\n * the pass uses `config.rt._depthView`. */\n _depthSrc?: RenderTarget;\n /** @internal External depth/stencil `loadOp` (\"load\" when `config.depth` is\n * set). When unset, defaults to `\"clear\"`. */\n _depthLoadOp?: GPULoadOp;\n\n /** Per-task scene UBO + bind group. Created eagerly in createRenderTask\n * so renderables can reference `_sceneBG` at `bind()` time. Written each\n * frame by `_writePassSceneUBO`. Destroyed in `dispose()`. */\n /** @internal */\n _sceneUBO: GPUBuffer;\n /** @internal */\n _sceneBG: GPUBindGroup;\n /** @internal */\n _lightsUBO: GPUBuffer;\n /** @internal */\n _suData: Float32Array;\n /** @internal */\n _su: unknown[];\n /** Optional transmission-enabled execute path: copies the scene texture for refraction and draws transmissive\n * renderables. Present only when the task was configured with `transmission`. Returns the number of draw calls issued. */\n /** @internal */\n _executeWithTransmission?(sampleCount: number): number;\n /** @internal */\n _targetSignature: RenderTargetSignature;\n /** @internal Lazy feature work flushed after binding updates and before the render pass. */\n _updateBatches: DrawUpdateBatch[];\n\n /** Add a mesh to this task's explicit render list with an optional per-pass material override. Resolved via\n * `material._buildGroup._rebuildSingle`, so the mesh's material family must already have been registered with the\n * scene (its batch builder has run). BEFORE the first `record()` the add is QUEUED and drained at record() time;\n * AFTER (a live/runtime add) it is resolved + re-bucketed into THIS task immediately, so the mesh renders on the\n * next frame without a `frameGraph.build()` (which would re-allocate shared GPU resources across all tasks). */\n addMesh(mesh: Mesh, opts?: { material?: Material }): void;\n /** @internal */\n _pendingMeshes: { mesh: Mesh; material: Material }[];\n}\n\ninterface MutableDrawUpdateContext {\n targetWidth: number;\n targetHeight: number;\n _camera?: Camera | null;\n}\n\n/** Create a render pass task. GPU resources (target textures + descriptor)\n * are not allocated until `record()` runs (via `frameGraph.build()`).\n *\n * Swapchain-targeted tasks acquire the swap view per-frame at execute time. */\nexport function createRenderTask(config: RenderTaskConfig, engine: EngineContext, scene: SceneContext): RenderTask {\n const sc = scene as SceneContext;\n config.clrColor ??= { r: 0.2, g: 0.2, b: 0.3, a: 1.0 };\n config.clr ??= true;\n const desc = config.rt._descriptor;\n // Render upright: row 0 of the GPU texture is the top of the scene. Every\n // RT (offscreen or swapchain) renders without a projection Y-flip; pipelines\n // use the default ccw front face; downstream samplers see upright pixels.\n const targetSignature = {\n _colorFormat: desc.format,\n _depthStencilFormat: config.depth?._descriptor.dFormat ?? desc.dFormat,\n _depthCompare: desc._depthCompare,\n _sampleCount: desc.samples ?? 1,\n };\n\n const sceneBGL = getSceneBindGroupLayout(engine);\n const sceneUBO = createEmptyUniformBuffer(engine, SCENE_UBO_BYTES);\n const lightsUBO = ensureSceneLightState(engine, sc)._buffer;\n const sceneBG = engine._device.createBindGroup({\n layout: sceneBGL,\n entries: [\n { binding: 0, resource: { buffer: sceneUBO } },\n { binding: 1, resource: { buffer: lightsUBO } },\n ],\n });\n const colorAttachment = { loadOp: \"clear\", storeOp: \"store\" } as GPURenderPassColorAttachment;\n const updateContext: MutableDrawUpdateContext = { targetWidth: 0, targetHeight: 0 };\n const task: RenderTask = {\n name: config.name,\n _config: config,\n engine: engine,\n scene: sc,\n _passes: [],\n _autoFromScene: false,\n _renderables: [],\n _opaqueBindings: [],\n _directBindings: [],\n _transparentBindings: [],\n _opaqueBundles: [],\n _lastVersion: -1,\n _lastVis: 0,\n _recorded: false,\n _renderPassDescriptor: { colorAttachments: [colorAttachment] },\n _colorAttachment: colorAttachment,\n _depthSrc: config.depth,\n _depthLoadOp: config.depth ? (config.depth._eager ? \"load\" : \"clear\") : undefined,\n _sceneUBO: sceneUBO,\n _sceneBG: sceneBG,\n _lightsUBO: lightsUBO,\n _suData: new F32(SCENE_UBO_BYTES / 4),\n _su: [],\n _targetSignature: targetSignature,\n _updateBatches: [],\n _pendingMeshes: [],\n addMesh(mesh, opts) {\n const material = opts?.material ?? mesh.material;\n if (!material) {\n return;\n }\n task._pendingMeshes.push({ mesh, material });\n if (task._recorded) {\n // Live (post-record) add: resolve + re-bucket THIS task now — buildBindings clears its bundle cache\n // so it re-records on the next execute. Deliberately NOT a frame-graph rebuild (that re-allocates the\n // shared scene UBO + every task's render target mid-frame and crashes the in-flight submit).\n resolvePendingMeshes(task, sc);\n // A live add makes the render list explicit (mirrors record(), where a pending mesh forces\n // _autoFromScene = false). Without this, an auto-mirroring task's next scene-version resync in\n // prepareRenderTaskPass would clear _renderables and drop the just-added mesh.\n task._autoFromScene = false;\n buildBindings(task, engine, targetSignature);\n }\n },\n record(): void {\n if (task._autoFromScene) {\n task._renderables.length = 0;\n }\n resolvePendingMeshes(task, sc);\n task._autoFromScene = !task._renderables.length;\n if (task._autoFromScene) {\n task._renderables.push(...sc._renderables);\n }\n // Read config.rt dynamically — transmission retargeting swaps it after\n // the task is created, and the engine scRT must never be rebuilt.\n const rt = config.rt;\n buildRenderTarget(rt, engine);\n if (config.rst && (rt._descriptor.samples ?? 1) > 1) {\n buildRenderTarget(config.rst, engine);\n }\n // A non-eager external depth (e.g. the default single-sample scene task's\n // depth, whose colour rt is the depth-less scRT) is task-managed:\n // build/rebuild it here. Eager depths (GeometryRendererTask outputs) are\n // pre-built and skipped by buildRenderTarget.\n if (config.depth && !config.depth._eager) {\n buildRenderTarget(config.depth, engine);\n }\n updateContext.targetWidth = rt._width;\n updateContext.targetHeight = rt._height;\n refreshTaskSceneBindGroup(task, engine);\n buildBindings(task, engine, targetSignature);\n buildRenderPassDescriptor(task, rt);\n task._recorded = true; // task is now live — a subsequent addMesh resolves + re-buckets immediately\n },\n execute(): number {\n return executePass(task, engine, targetSignature, updateContext);\n },\n dispose(): void {\n task._passes.length = 0;\n // disposeRenderTarget no-ops on the engine scRT and on eager\n // GeometryRendererTask depth outputs (both `_eager`), and on an undefined\n // rst/depth — so these can be passed unconditionally.\n disposeRenderTarget(config.rt);\n disposeRenderTarget(config.rst);\n disposeRenderTarget(config.depth);\n task._opaqueBindings.length = 0;\n task._directBindings.length = 0;\n task._transparentBindings.length = 0;\n task._renderables.length = 0;\n task._opaqueBundles.length = 0;\n task._sceneUBO.destroy();\n for (const batch of task._updateBatches) {\n batch.destroy();\n }\n task._updateBatches.length = 0;\n },\n };\n return task;\n}\n\n/** Remove a mesh from this task's renderable + binding lists. Idempotent. */\nexport function removeMeshFromTask(task: RenderTask, mesh: object): void {\n // Not a renderable-bearing task (e.g. a post/effect task that also carries `_config`): nothing to\n // remove. Guard keeps callers that scan all frame-graph tasks (removeFromScene) shape-safe.\n if (!task._renderables) {\n return;\n }\n let removed = false;\n for (let i = task._pendingMeshes.length - 1; i >= 0; i--) {\n if (task._pendingMeshes[i]!.mesh === mesh) {\n task._pendingMeshes.splice(i, 1);\n removed = true;\n }\n }\n for (let i = task._renderables.length - 1; i >= 0; i--) {\n if (task._renderables[i]!.mesh === mesh) {\n task._renderables.splice(i, 1);\n removed = true;\n }\n }\n for (const arr of [task._opaqueBindings, task._directBindings, task._transparentBindings]) {\n for (let i = arr.length - 1; i >= 0; i--) {\n if (arr[i]!.renderable.mesh === mesh) {\n arr.splice(i, 1);\n removed = true;\n }\n }\n }\n if (removed) {\n task._opaqueBundles.length = 0;\n task._lastVersion = -1;\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction resolvePendingMeshes(task: RenderTask, sc: SceneContext): void {\n if (!task._pendingMeshes.length) {\n return;\n }\n for (const { mesh, material } of task._pendingMeshes) {\n const builder = material._buildGroup;\n const group = sc._groups.get(builder);\n const rebuild = group ? group.r : builder._rebuildSingle;\n if (!rebuild) {\n throw Error();\n }\n const renderable = rebuild(sc, mesh, material);\n if (!task._renderables.includes(renderable)) {\n task._renderables.push(renderable);\n }\n }\n task._pendingMeshes.length = 0;\n}\n\n/** Per-frame back-to-front sort for transparent bindings using the active camera. */\nfunction sortTransparentBindings(task: RenderTask, camera: Camera | null | undefined): void {\n const arr = task._transparentBindings;\n if (arr.length <= 1 || !camera) {\n return;\n }\n const v = getViewMatrix(camera);\n for (const b of arr) {\n const wc = b.renderable._worldCenter;\n b._sortDistance = wc ? wc[0]! * v[2]! + wc[1]! * v[6]! + wc[2]! * v[10]! + v[14]! : 0;\n }\n arr.sort((a, b) => b._sortDistance! - a._sortDistance! || a.renderable.order - b.renderable.order);\n}\n\n/** (Re)bucket task._renderables into bound lists. */\nfunction buildBindings(task: RenderTask, eng: EngineContext, targetSignature: RenderTargetSignature): void {\n const opaque = task._opaqueBindings;\n const direct = task._directBindings;\n const transparent = task._transparentBindings;\n opaque.length = 0;\n direct.length = 0;\n transparent.length = 0;\n for (const r of task._renderables) {\n const binding = r.bind(eng, targetSignature);\n for (const batch of binding._updateBatches ?? []) {\n if (!task._updateBatches.includes(batch)) {\n task._updateBatches.push(batch);\n }\n }\n if (r.isTransparent || r._transmissive) {\n transparent.push(binding);\n } else if (r._direct) {\n direct.push(binding);\n } else {\n opaque.push(binding);\n }\n }\n opaque.sort((a, b) => a.renderable.order - b.renderable.order);\n direct.sort((a, b) => a.renderable.order - b.renderable.order);\n task._opaqueBundles.length = 0;\n task._lastVersion = (task.scene as SceneContext)._renderableVersion;\n}\n\nfunction buildRenderPassDescriptor(task: RenderTask, rt: RenderTarget): void {\n const att = task._colorAttachment;\n att.view = rt._colorView!;\n // End-of-pass MSAA resolve into a caller-supplied single-sample target.\n // record() only builds the target's color view for an MSAA rt, so its\n // presence is the gate. The swapchain case is wired per-frame in\n // executePass (its view changes each frame); this custom view is stable.\n att.resolveTarget = task._config.rst?._colorView ?? undefined;\n task._renderPassDescriptor.colorAttachments = rt._colorView ? [att] : [];\n\n const depthSrc = task._depthSrc ?? rt;\n const depthView = depthSrc._depthView;\n let depthAttachment: GPURenderPassDepthStencilAttachment | undefined;\n if (depthView) {\n const dd = depthSrc._descriptor;\n const loadOp = task._depthLoadOp ?? \"clear\";\n depthAttachment = {\n view: depthView,\n depthClearValue: dd._depthClearValue ?? 0,\n depthLoadOp: loadOp,\n depthStoreOp: \"store\",\n };\n if (dd.dFormat?.includes(\"stencil\")) {\n depthAttachment.stencilClearValue = 0;\n depthAttachment.stencilLoadOp = loadOp;\n depthAttachment.stencilStoreOp = \"store\";\n }\n }\n\n task._renderPassDescriptor.depthStencilAttachment = depthAttachment;\n}\n\nfunction prepareRenderTaskPass(task: RenderTask, eng: EngineContext, targetSignature: RenderTargetSignature, context: DrawUpdateContext): void {\n const sc = task.scene as SceneContext;\n // Auto-resync when the source scene mutates.\n if (task._autoFromScene && task._lastVersion !== sc._renderableVersion) {\n task._renderables.length = 0;\n task._renderables.push(...sc._renderables);\n buildBindings(task, eng, targetSignature);\n }\n\n // Pre-pass work — runs before beginRenderPass. Updates the task-owned scene\n // UBO, scene-wide lights UBO, and per-binding UBOs. The scene bind group may\n // also need a refresh (lights buffer can be resized when glTF lights\n // extension raises MAX_LIGHTS after this task was first recorded).\n refreshTaskSceneBindGroup(task, eng);\n const camera = task._config.cam ?? sc.camera;\n if (!task._config._skipClusteredLights && targetSignature._colorFormat) {\n sc._clusteredLightUpdater?.(camera, context.targetWidth, context.targetHeight);\n }\n _writePassSceneUBO(task, eng, sc, camera);\n refreshSceneLightsUBO(eng, sc);\n // Expose the active camera to per-binding `update()` calls. Some renderables\n // (e.g. transparent billboard systems) need it to compute view-space sort\n // depths during their update.\n (context as MutableDrawUpdateContext)._camera = camera;\n for (const batch of task._updateBatches) {\n batch.reset();\n }\n updateBindings(task._opaqueBindings, context);\n updateBindings(task._directBindings, context);\n updateBindings(task._transparentBindings, context);\n for (const batch of task._updateBatches) {\n batch.flush(eng);\n }\n // Per-frame back-to-front sort for transparent bindings — must run AFTER\n // updateBindings so renderables that compute `_worldCenter` inside their\n // own `update()` (billboard systems) are seen with current values.\n sortTransparentBindings(task, camera);\n}\n\nfunction executePass(task: RenderTask, eng: EngineContext, targetSignature: RenderTargetSignature, context: DrawUpdateContext): number {\n const sc = task.scene;\n const sampleCount = targetSignature._sampleCount;\n prepareRenderTaskPass(task, eng, targetSignature, context);\n const att = task._colorAttachment;\n const cfg = task._config;\n if (cfg.rt._colorView) {\n // The engine scRT's color view is re-acquired every frame, so re-read\n // it here. Offscreen color views are stable between rebuilds — leaving att.view\n // untouched preserves an external override (swapchain-overlay shares the base\n // scene's MSAA color view). The resolve target (rst) is re-read each frame so an\n // `rst === scRT` picks up its fresh per-frame view.\n if (cfg.rt === eng.scRT) {\n att.view = cfg.rt._colorView;\n }\n att.resolveTarget = cfg.rst?._colorView ?? undefined;\n att.clearValue = task._autoFromScene ? sc.clearColor : cfg.clrColor!;\n att.loadOp = cfg.clr ? \"clear\" : \"load\";\n }\n if (task._executeWithTransmission) {\n return task._executeWithTransmission(sampleCount);\n }\n const pass = eng._currentEncoder.beginRenderPass(task._renderPassDescriptor);\n const draws = executePassBody(task, pass);\n pass.end();\n return draws;\n}\n\n/** Body of the registered `RenderPass`. Receives the live render-pass encoder\n * and issues all draws (viewport/scissor, group(0) bind, opaque bundle replay,\n * then direct-draws non-transparent direct + transparent). Returns the draw count. */\nfunction executePassBody(task: RenderTask, pass: GPURenderPassEncoder): number {\n const eng = task.engine as EngineContext;\n const cfg = task._config;\n const rt = cfg.rt;\n const scene = task.scene as SceneContext;\n const opaqueBindings = task._opaqueBindings;\n const opaqueBundles = task._opaqueBundles;\n const sceneBG = task._sceneBG;\n\n const camera = cfg.cam ?? scene.camera;\n const v = camera?.viewport;\n if (v) {\n const rw = rt._width;\n const rh = rt._height;\n const x = Math.floor(v.x * rw);\n const y = Math.floor((1 - v.y - v.height) * rh);\n const w = Math.ceil((v.x + v.width) * rw) - x;\n const h = Math.ceil((1 - v.y) * rh) - y;\n pass.setViewport(x, y, w, h, 0, 1);\n pass.setScissorRect(x, y, w, h);\n }\n // Scene bind group (group 0) is task-owned and identical for every draw in this pass.\n pass.setBindGroup(0, sceneBG);\n\n // Opaque: cached render bundle. Invalidated by scene mutation (_renderableVersion) or\n // the global visibility/resource epoch (_vis). The bundle records group(0) at its start.\n if (task._lastVersion !== scene._renderableVersion || task._lastVis !== _vis || !opaqueBundles.length) {\n const desc = rt._descriptor;\n const be = eng._device.createRenderBundleEncoder({\n colorFormats: desc.format ? [desc.format] : [],\n // Use the task's target signature, not the RT descriptor: a depth\n // override (config.depth) supplies the depth format externally, so\n // the cached opaque pipelines are built with it while the colour RT\n // carries no depthStencilFormat of its own. The bundle encoder's\n // attachment state must match those pipelines exactly.\n depthStencilFormat: task._targetSignature._depthStencilFormat,\n sampleCount: desc.samples ?? 1,\n });\n be.setBindGroup(0, sceneBG);\n drawList(be, opaqueBindings, eng);\n opaqueBundles[0] = be.finish();\n task._lastVersion = scene._renderableVersion;\n task._lastVis = _vis;\n }\n let draws = opaqueBindings.length;\n pass.executeBundles(opaqueBundles);\n // executeBundles invalidates pass bind-group state — rebind group 0 before further draws.\n pass.setBindGroup(0, sceneBG);\n draws += drawList(pass, task._directBindings, eng);\n draws += drawList(pass, task._transparentBindings, eng);\n return draws;\n}\n\nfunction refreshTaskSceneBindGroup(task: RenderTask, eng: EngineContext): void {\n const lightsUBO = ensureSceneLightState(eng, task.scene as SceneContext)._buffer;\n if (lightsUBO === task._lightsUBO) {\n return;\n }\n task._lightsUBO = lightsUBO;\n task._sceneBG = eng._device.createBindGroup({\n layout: getSceneBindGroupLayout(eng),\n entries: [\n { binding: 0, resource: { buffer: task._sceneUBO } },\n { binding: 1, resource: { buffer: lightsUBO } },\n ],\n });\n task._opaqueBundles.length = 0;\n task._lastVersion = -1;\n}\n\n/** Write the canonical SceneUniforms struct to the task-owned scene UBO.\n * Bails before touching scratch/GPU when all inputs are unchanged.\n * @internal Exported for unit testing of the scene-UBO change-detection guard. */\nexport function _writePassSceneUBO(task: RenderTask, eng: EngineContext, scene: SceneContext, camera: Camera | null): void {\n if (!camera) {\n return;\n }\n\n const v = camera.viewport;\n const rt = task._config.rt;\n const aspect = (task._config.cs ? eng.canvas.width / eng.canvas.height : rt._width / rt._height) * (v ? v.width / v.height : 1);\n const fog = scene.fog;\n const img = scene.imageProcessing;\n const envRotationY = scene.envRotationY || 0;\n // Change key = camera transform version + projection revision, the latter covering both\n // `fov` / `nearPlane` / `farPlane` writes and orthographic bounds. See `_cameraChangeKey`.\n const wv = _cameraChangeKey(camera);\n // `envTextures` identity is tracked so an environment loaded (or swapped) AFTER the scene has reached\n // steady state invalidates this cache. Its spherical-harmonics irradiance and `lodGenerationScale` are\n // written into the scene UBO below (via `_packSceneUniforms` + the env-SH contributor); without tracking\n // it, a late env load would change none of the other guarded inputs, so the UBO would never be rewritten\n // and the model would keep zero irradiance (dark diffuse, specular-only \"mirror\" look).\n const envTextures = scene._envTextures;\n const s = task._su;\n if (s[0] === camera && s[1] === fog && s[2] === wv && s[3] === aspect && s[4] === envRotationY && s[5] === img.exposure && s[6] === img.contrast && s[7] === envTextures) {\n return;\n }\n s[0] = camera;\n s[1] = fog;\n s[2] = wv;\n s[3] = aspect;\n s[4] = envRotationY;\n s[5] = img.exposure;\n s[6] = img.contrast;\n s[7] = envTextures;\n\n const data = task._suData;\n _packSceneUniforms(data, eng, scene, camera, aspect);\n const contribs = scene._sceneUboContributors;\n if (contribs) {\n for (const c of contribs) {\n c(data, scene);\n }\n }\n eng._device.queue.writeBuffer(task._sceneUBO, 0, data as Float32Array<ArrayBuffer>);\n}\n\nfunction updateBindings(list: readonly DrawBinding[], context: DrawUpdateContext): void {\n for (const b of list) {\n b.update?.(context);\n }\n}\n\n/** @internal Iterate DrawBindings, deduping setPipeline. */\nexport function drawList(enc: GPURenderPassEncoder | GPURenderBundleEncoder, list: readonly DrawBinding[], engine: EngineContext): number {\n let lp: GPURenderPipeline | null = null;\n let draws = 0;\n for (const b of list) {\n const mesh = b.renderable.mesh;\n if (mesh && mesh.visible === false) {\n continue;\n }\n if (b.pipeline !== lp) {\n enc.setPipeline(b.pipeline);\n lp = b.pipeline;\n }\n draws += b.draw(enc, engine);\n }\n return draws;\n}\n"],"names":[],"mappings":"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"}
package/lib/index.js CHANGED
@@ -3,6 +3,7 @@ export { createNullEngine, runHeadlessSteps, stepScene } from './engine/null-eng
3
3
  export { getRenderTaskGpuTimings, isRenderTaskGpuTimingSupported, setRenderTaskGpuTimingEnabled } from './engine/gpu-task-timing.js';
4
4
  export { createSurface, disposeSurface, resizeSurface, setSurfaceSize } from './engine/surface.js';
5
5
  export { captureScreenshot } from './engine/screenshot.js';
6
+ export { forceWebGpuDeviceLossForTesting } from './engine/device-lost-recovery-testing.js';
6
7
  export { enableDeviceLostSceneRecovery } from './engine/device-lost-scene-recovery.js';
7
8
  export { enableDeviceLostSpriteRecovery } from './engine/device-lost-sprite-recovery.js';
8
9
  export { enableDeviceLostTextRecovery } from './engine/device-lost-text-recovery.js';
@@ -44,6 +45,7 @@ export { attachControl, setCameraLimits } from './camera/arc-rotate-controls.js'
44
45
  export { interpolateArcRotateCamera } from './camera/arc-rotate-interpolate.js';
45
46
  export { createFreeCamera } from './camera/free-camera.js';
46
47
  export { attachFreeControl } from './camera/free-camera-controls.js';
48
+ export { disableOrthographicCamera, enableOrthographicCamera } from './camera/orthographic.js';
47
49
  export { clampCenterFromPoles, computeLocalBasis, computeLookAtFromYawPitch, computeYawPitchFromLookAt, createGeospatialCamera, normalizeRadians, setGeospatialOrientation } from './camera/geospatial-camera.js';
48
50
  export { clampZoomDistance, createGeospatialLimits, getEffectivePitchMax } from './camera/geospatial-limits.js';
49
51
  export { attachGeospatialControls } from './camera/geospatial-camera-controls.js';
@@ -108,6 +110,7 @@ export { cloneTransformNode, createTransformNode } from './scene/transform-node.
108
110
  export { loadBabylon } from './loader-babylon/load-babylon.js';
109
111
  export { l as loadEnvironment } from './_chunks/load-env-ChDWNc4W.js';
110
112
  export { loadDdsEnvironment } from './loader-env/load-dds-env.js';
113
+ export { buildDdsSkyboxRenderable } from './material/pbr/background-dds-skybox.js';
111
114
  export { loadHdrEnvironment } from './loader-hdr/load-hdr.js';
112
115
  export { cloneTexture2D, loadTexture2D } from './texture/texture-2d.js';
113
116
  export { loadSkybox } from './loader-skybox/load-skybox.js';
@@ -233,7 +236,7 @@ export { onPhysicsCollision, setPhysicsBodyCollisionEventsEnabled } from './phys
233
236
  export { onPhysicsTrigger, setPhysicsShapeIsTrigger } from './physics/havok-trigger.js';
234
237
  export { createPhysicsViewer, disposePhysicsViewer, hidePhysicsBody, showPhysicsBody, showPhysicsConstraint } from './physics/physics-viewer.js';
235
238
  export { CharacterCollisionObservable, CharacterSupportedState, PhysicsCharacterController, createPhysicsCharacterController } from './physics/character-controller.js';
236
- export { addAgent, addBoxObstacle, addCylinderObstacle, agentGoto, computePath, createDebugNavMeshGeometry, createNavCrowd, createNavMesh, createNavMeshFromSources, createNavigationPluginAsync, disposeNavigationPlugin, findClosestPointWithin, findRandomPoint, findRandomPointAroundCircle, getAgentPosition, getAgentVelocity, getClosestPoint, getNavigationRandomSeed, raycast, removeObstacle, setNavigationRandomSeed, updateNavCrowd, updateNavMeshObstacles } from './navigation/navigation.js';
239
+ export { addAgent, addBoxObstacle, addCylinderObstacle, agentGoto, computePath, createDebugNavMeshGeometry, createNavCrowd, createNavMesh, createNavMeshFromSources, createNavigationPluginAsync, disposeNavigationPlugin, findClosestPointWithin, findRandomPoint, findRandomPointAroundCircle, getAgentPosition, getAgentVelocity, getClosestPoint, getNavigationRandomSeed, navRayBlocked, raycast, removeObstacle, setNavigationRandomSeed, updateNavCrowd, updateNavMeshObstacles } from './navigation/navigation.js';
237
240
  export { createAudioEngineAsync, disposeAudioEngine, getMasterVolume, setMasterVolume, unlockAudioEngineAsync } from './audio/audio-engine.js';
238
241
  export { createAudioEngineMediaStream, disposeAudioEngineMediaStream } from './audio/media-stream-output.js';
239
242
  export { SoundState, createSoundAsync, disposeSound, pauseSound, playSound, resumeSound, setSoundVolume, stopSound } from './audio/static-sound.js';
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,7 +1,7 @@
1
1
  import { ThrowLiteError } from '../lite-error.js';
2
2
  import { F32, U32 } from '../engine/typed-arrays.js';
3
3
  import { TU, SS } from '../engine/gpu-flags.js';
4
- import { getViewMatrix, getProjectionMatrix } from '../camera/camera.js';
4
+ import { getEffectiveAspectRatio, _cameraChangeKey, getViewMatrix, getProjectionMatrix } from '../camera/camera.js';
5
5
  import { createUniformBuffer } from '../resource/gpu-buffers.js';
6
6
  import { _registerPbrExt } from '../material/pbr/pbr-flags.js';
7
7
  import { CLUSTERED_LIGHT_BLOCK, CLUSTERED_LIGHT_STRUCTS } from '../material/pbr/fragments/clustered-light-wgsl.js';
@@ -123,6 +123,7 @@ function buildClusteredLightGpuState(engine, scene, container) {
123
123
  let lastCameraVersion = -1;
124
124
  let lastTargetWidth = 0;
125
125
  let lastTargetHeight = 0;
126
+ let lastAspect = -1;
126
127
  let lastContainerVersion = -1;
127
128
  let lastLightCount = -1;
128
129
  const state = {
@@ -136,13 +137,14 @@ function buildClusteredLightGpuState(engine, scene, container) {
136
137
  }
137
138
  const safeWidth = Math.max(1, targetWidth);
138
139
  const safeHeight = Math.max(1, targetHeight);
139
- if (activeCamera === lastCamera && activeCamera.worldMatrixVersion === lastCameraVersion && safeWidth === lastTargetWidth && safeHeight === lastTargetHeight && container._version === lastContainerVersion && container.pointLights.length === lastLightCount) {
140
+ const aspect = getEffectiveAspectRatio(activeCamera, safeWidth, safeHeight);
141
+ if (activeCamera === lastCamera && _cameraChangeKey(activeCamera) === lastCameraVersion && safeWidth === lastTargetWidth && safeHeight === lastTargetHeight && aspect === lastAspect && container._version === lastContainerVersion && container.pointLights.length === lastLightCount) {
140
142
  return;
141
143
  }
142
144
  if (container.pointLights.length * 2 > lightTexels || Math.ceil(container.pointLights.length / CLUSTER_BATCH_SIZE) > batchCount) {
143
145
  ThrowLiteError(77);
144
146
  }
145
- let topologyDirty = activeCamera !== lastCamera || activeCamera.worldMatrixVersion !== lastCameraVersion || safeWidth !== lastTargetWidth || safeHeight !== lastTargetHeight || container.pointLights.length !== lastLightCount;
147
+ let topologyDirty = activeCamera !== lastCamera || _cameraChangeKey(activeCamera) !== lastCameraVersion || safeWidth !== lastTargetWidth || safeHeight !== lastTargetHeight || aspect !== lastAspect || container.pointLights.length !== lastLightCount;
146
148
  let lightDataDirty = topologyDirty;
147
149
  if (container._version !== lastContainerVersion || container.pointLights.length !== lastLightCount) {
148
150
  for (let i = 0; i < container.pointLights.length; i++) {
@@ -174,7 +176,6 @@ function buildClusteredLightGpuState(engine, scene, container) {
174
176
  lightDataDirty = true;
175
177
  sliceData.fill(0);
176
178
  activeLights.length = 0;
177
- const aspect = safeWidth / safeHeight;
178
179
  const view = getViewMatrix(activeCamera);
179
180
  const proj = getProjectionMatrix(activeCamera, aspect);
180
181
  const nearZ = activeCamera.nearPlane;
@@ -231,9 +232,10 @@ function buildClusteredLightGpuState(engine, scene, container) {
231
232
  }
232
233
  }
233
234
  lastCamera = activeCamera;
234
- lastCameraVersion = activeCamera.worldMatrixVersion;
235
+ lastCameraVersion = _cameraChangeKey(activeCamera);
235
236
  lastTargetWidth = safeWidth;
236
237
  lastTargetHeight = safeHeight;
238
+ lastAspect = aspect;
237
239
  lastContainerVersion = container._version;
238
240
  lastLightCount = container.pointLights.length;
239
241
  },
@@ -311,7 +313,18 @@ function projectedSphereBounds(vx, vy, vz, range, proj, tileCountX, tileCountY)
311
313
  let maxNdcX = 1;
312
314
  let minNdcY = -1;
313
315
  let maxNdcY = 1;
314
- if (vz > range) {
316
+ if (proj[11] === 0) {
317
+ const sx = proj[0];
318
+ const sy = proj[5];
319
+ const cx = sx * vx + proj[12];
320
+ const cy = sy * vy + proj[13];
321
+ const rx = Math.abs(sx * range);
322
+ const ry = Math.abs(sy * range);
323
+ minNdcX = Math.max(cx - rx, -1);
324
+ maxNdcX = Math.min(cx + rx, 1);
325
+ minNdcY = Math.max(cy - ry, -1);
326
+ maxNdcY = Math.min(cy + ry, 1);
327
+ } else if (vz > range) {
315
328
  const x0 = projectedSphereEdge(vx, vz, rangeSq, proj[0], -1);
316
329
  const x1 = projectedSphereEdge(vx, vz, rangeSq, proj[0], 1);
317
330
  minNdcX = Math.min(x0, x1);