@babylonjs/lite 1.6.0 → 1.7.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.
- package/dist/index.js +284 -279
- package/dist/index.js.map +1 -1
- package/index.d.ts +17 -2
- package/lib/engine/engine.js +1 -1
- package/lib/frame-graph/depth-resolve-task.js +117 -0
- package/lib/frame-graph/depth-resolve-task.js.map +1 -0
- package/lib/frame-graph/transmission.js +4 -3
- package/lib/frame-graph/transmission.js.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/material/shader/shader-material.js +4 -2
- package/lib/material/shader/shader-material.js.map +1 -1
- package/lib/material/shader/shader-pipeline.js +10 -0
- package/lib/material/shader/shader-pipeline.js.map +1 -1
- package/lib/material/shader/shader-renderable.js +19 -6
- package/lib/material/shader/shader-renderable.js.map +1 -1
- package/lib/material/shader/shader-thin-instance.js +1 -1
- package/lib/material/shader/shader-thin-instance.js.map +1 -1
- package/lib/scene/scene-core.js +5 -2
- package/lib/scene/scene-core.js.map +1 -1
- package/lib/shadow/csm-shadow-task-hooks.js +14 -6
- package/lib/shadow/csm-shadow-task-hooks.js.map +1 -1
- package/lib/shadow/pcf-shadow-task-hooks.js +6 -0
- package/lib/shadow/pcf-shadow-task-hooks.js.map +1 -1
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -1903,6 +1903,10 @@ export declare function createDefaultTextData(font: Font, fontSizePx: number, te
|
|
|
1903
1903
|
*/
|
|
1904
1904
|
export declare function createDepthOfFieldPostProcessTask(config: DepthOfFieldPostProcessTaskConfig, engine: EngineContext, scene?: SceneContext): DepthOfFieldPostProcessTask;
|
|
1905
1905
|
|
|
1906
|
+
/** Create a frame-graph task that resolves `sourceTexture`'s multisampled depth into `targetTexture`'s
|
|
1907
|
+
* single-sample depth. Add it AFTER the source render task and BEFORE any depth-sampling consumer. */
|
|
1908
|
+
export declare function createDepthResolveTask(config: DepthResolveTaskConfig, engine: EngineContext, scene: SceneContext): Task;
|
|
1909
|
+
|
|
1906
1910
|
/**
|
|
1907
1911
|
* Creates a directional light shining along `direction` (a parallel light source, like the sun).
|
|
1908
1912
|
* @param direction - World-space direction the light travels along.
|
|
@@ -2871,6 +2875,15 @@ export declare interface DepthOfFieldPostProcessTaskConfig extends PostProcessTa
|
|
|
2871
2875
|
depthNotNormalized?: boolean;
|
|
2872
2876
|
}
|
|
2873
2877
|
|
|
2878
|
+
/** Options for a depth-resolve frame-graph task. */
|
|
2879
|
+
export declare interface DepthResolveTaskConfig {
|
|
2880
|
+
name?: string;
|
|
2881
|
+
/** Multisampled source render target whose DEPTH attachment is resolved (must have sampleCount \> 1). */
|
|
2882
|
+
sourceTexture: RenderTarget;
|
|
2883
|
+
/** Single-sample destination render target whose DEPTH attachment receives the resolved depth. */
|
|
2884
|
+
targetTexture: RenderTarget;
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2874
2887
|
/**
|
|
2875
2888
|
* Detaches a spatial sound/bus — or the engine's listener — from its world
|
|
2876
2889
|
* transform.
|
|
@@ -7566,8 +7579,10 @@ export declare function setUniformEffectUniforms(wrapper: UniformEffectWrapper,
|
|
|
7566
7579
|
*/
|
|
7567
7580
|
export declare function setUnmuteUIEnabled(ui: UnmuteUI, enabled: boolean): void;
|
|
7568
7581
|
|
|
7569
|
-
/** Vertex attribute names a ShaderMaterial can bind.
|
|
7570
|
-
|
|
7582
|
+
/** Vertex attribute names a ShaderMaterial can bind. `joints`/`weights` (and `joints1`/`weights1`
|
|
7583
|
+
* for \>4 bones/vertex) are the skinning attributes — bound from the mesh's skeleton/VAT buffers,
|
|
7584
|
+
* letting a custom material do vertex skinning (e.g. baked vertex-animation). */
|
|
7585
|
+
export declare type ShaderAttributeName = "position" | "normal" | "uv" | "uv2" | "tangent" | "color" | "joints" | "weights" | "joints1" | "weights1";
|
|
7571
7586
|
|
|
7572
7587
|
/** A resolved WGSL preprocessor define (name + value). */
|
|
7573
7588
|
export declare interface ShaderDefine {
|
package/lib/engine/engine.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _setHpmAllocator } from '../math/_matrix-allocator.js';
|
|
2
2
|
import { isDomCanvas, _buildSurface, resizeSurface, _refreshScRT, setSurfaceSize } from './surface.js';
|
|
3
3
|
|
|
4
|
-
const VERSION = /* @__PURE__ */ (() => "1.
|
|
4
|
+
const VERSION = /* @__PURE__ */ (() => "1.7.0" )();
|
|
5
5
|
let _vis = 0;
|
|
6
6
|
function bumpVisibilityEpoch() {
|
|
7
7
|
_vis = _vis + 1 | 0;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { SS } from '../engine/gpu-flags.js';
|
|
2
|
+
import { buildRenderTarget } from '../engine/render-target.js';
|
|
3
|
+
|
|
4
|
+
const VERTEX_WGSL = `struct V{@builtin(position)p:vec4f};
|
|
5
|
+
@vertex fn vs(@builtin(vertex_index)i:u32)->V{
|
|
6
|
+
var pos=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));
|
|
7
|
+
return V(vec4f(pos[i],0,1));}`;
|
|
8
|
+
const FRAGMENT_WGSL = `@group(0)@binding(0)var src:texture_depth_multisampled_2d;
|
|
9
|
+
@fragment fn fs(v:V)->@builtin(frag_depth)f32{return textureLoad(src,vec2i(v.p.xy),0);}`;
|
|
10
|
+
let _cacheDevice = null;
|
|
11
|
+
let _bgl = null;
|
|
12
|
+
let _pipelines = null;
|
|
13
|
+
function getOrCreatePipeline(engine, depthFormat) {
|
|
14
|
+
const device = engine._device;
|
|
15
|
+
if (_cacheDevice !== device) {
|
|
16
|
+
_cacheDevice = device;
|
|
17
|
+
_bgl = null;
|
|
18
|
+
_pipelines = /* @__PURE__ */ new Map();
|
|
19
|
+
}
|
|
20
|
+
const cached = _pipelines.get(depthFormat);
|
|
21
|
+
if (cached) {
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
_bgl ??= device.createBindGroupLayout({
|
|
25
|
+
label: "depth-resolve-bgl",
|
|
26
|
+
entries: [{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: "depth", multisampled: true } }]
|
|
27
|
+
});
|
|
28
|
+
const module = device.createShaderModule({ code: `${VERTEX_WGSL}
|
|
29
|
+
${FRAGMENT_WGSL}`, label: "depth-resolve" });
|
|
30
|
+
const pipeline = device.createRenderPipeline({
|
|
31
|
+
label: `depth-resolve-${depthFormat}`,
|
|
32
|
+
layout: device.createPipelineLayout({ label: "depth-resolve-layout", bindGroupLayouts: [_bgl] }),
|
|
33
|
+
vertex: { module, entryPoint: "vs" },
|
|
34
|
+
fragment: { module, entryPoint: "fs", targets: [] },
|
|
35
|
+
// depth-only: no colour target
|
|
36
|
+
primitive: { topology: "triangle-list" },
|
|
37
|
+
depthStencil: { format: depthFormat, depthWriteEnabled: true, depthCompare: "always" }
|
|
38
|
+
});
|
|
39
|
+
_pipelines.set(depthFormat, pipeline);
|
|
40
|
+
return pipeline;
|
|
41
|
+
}
|
|
42
|
+
function createDepthResolveTask(config, engine, scene) {
|
|
43
|
+
const eng = engine;
|
|
44
|
+
const depthAttachment = {
|
|
45
|
+
view: void 0,
|
|
46
|
+
depthClearValue: 0,
|
|
47
|
+
// every fragment overwrites it (depthCompare "always"), so the clear value is moot
|
|
48
|
+
depthLoadOp: "clear",
|
|
49
|
+
depthStoreOp: "store"
|
|
50
|
+
};
|
|
51
|
+
const renderPassDescriptor = {
|
|
52
|
+
label: config.name ?? "depth-resolve",
|
|
53
|
+
colorAttachments: [],
|
|
54
|
+
depthStencilAttachment: depthAttachment
|
|
55
|
+
};
|
|
56
|
+
let pipeline = null;
|
|
57
|
+
let bindGroup = null;
|
|
58
|
+
let boundSrc = null;
|
|
59
|
+
let boundDst = null;
|
|
60
|
+
const build = () => {
|
|
61
|
+
const source = config.sourceTexture;
|
|
62
|
+
const target = config.targetTexture;
|
|
63
|
+
if (!source._depthTexture) {
|
|
64
|
+
throw new Error(`DepthResolveTask "${config.name}": sourceTexture has no depth attachment.`);
|
|
65
|
+
}
|
|
66
|
+
if ((source._descriptor.samples ?? 1) < 2) {
|
|
67
|
+
throw new Error(`DepthResolveTask "${config.name}": sourceTexture must be multisampled (sampleCount > 1).`);
|
|
68
|
+
}
|
|
69
|
+
if (!target._depthTexture || target._width !== (source._width || 0) || target._height !== (source._height || 0)) {
|
|
70
|
+
buildRenderTarget(target, eng);
|
|
71
|
+
if (target._width !== source._width || target._height !== source._height) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`DepthResolveTask "${config.name}": targetTexture size ${target._width}×${target._height} must match sourceTexture size ${source._width}×${source._height} (size the target's descriptor like the source, e.g. both \`size: surface\`).`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const depthFormat = target._descriptor.dFormat;
|
|
78
|
+
if (!depthFormat) {
|
|
79
|
+
throw new Error(`DepthResolveTask "${config.name}": targetTexture has no depth format.`);
|
|
80
|
+
}
|
|
81
|
+
pipeline = getOrCreatePipeline(eng, depthFormat);
|
|
82
|
+
const srcView = source._depthTexture.createView({ aspect: "depth-only" });
|
|
83
|
+
bindGroup = eng._device.createBindGroup({ label: `${config.name ?? "depth-resolve"}-bg`, layout: _bgl, entries: [{ binding: 0, resource: srcView }] });
|
|
84
|
+
depthAttachment.view = target._depthView;
|
|
85
|
+
boundSrc = source._depthTexture;
|
|
86
|
+
boundDst = target._depthTexture;
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
name: config.name ?? "depth-resolve",
|
|
90
|
+
engine: eng,
|
|
91
|
+
scene,
|
|
92
|
+
_passes: [],
|
|
93
|
+
record() {
|
|
94
|
+
build();
|
|
95
|
+
},
|
|
96
|
+
execute() {
|
|
97
|
+
if (config.sourceTexture._depthTexture !== boundSrc || config.targetTexture._depthTexture !== boundDst) {
|
|
98
|
+
build();
|
|
99
|
+
}
|
|
100
|
+
const pass = eng._currentEncoder.beginRenderPass(renderPassDescriptor);
|
|
101
|
+
pass.setPipeline(pipeline);
|
|
102
|
+
pass.setBindGroup(0, bindGroup);
|
|
103
|
+
pass.draw(3);
|
|
104
|
+
pass.end();
|
|
105
|
+
return 1;
|
|
106
|
+
},
|
|
107
|
+
dispose() {
|
|
108
|
+
pipeline = null;
|
|
109
|
+
bindGroup = null;
|
|
110
|
+
boundSrc = null;
|
|
111
|
+
boundDst = null;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export { createDepthResolveTask };
|
|
117
|
+
//# sourceMappingURL=depth-resolve-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"depth-resolve-task.js","sources":["../../../src/frame-graph/depth-resolve-task.ts"],"sourcesContent":["/**\n * DepthResolveTask — resolve a multisampled depth attachment into a single-sample depth texture.\n *\n * A multisampled depth texture can't be bound to a normal shader (no sampler/textureSample path), so any pass\n * that SAMPLES the scene depth (a screen-space shadow stabiliser, screen-space contact shadows, SSAO — all of\n * which reconstruct world position from depth) breaks once the scene renders to an MSAA target. This task\n * bridges that: a full-screen triangle reads sample 0 of the source `texture_depth_multisampled_2d` and writes\n * it to `@builtin(frag_depth)` through a depth-only render pass (no colour attachment) targeting a single-sample\n * destination depth.\n *\n * Sample 0 (not an average) is deliberate — depth is non-linear, so averaging samples is meaningless; sample 0\n * is a real surface depth at each pixel, which is exactly what depth-reconstruction consumers need. Modelled on\n * copy-to-texture-task's raw-pipeline pattern (cached pipeline + bind-group layout per device).\n */\n\nimport { SS } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport type { RenderTarget } from \"../engine/render-target.js\";\nimport { buildRenderTarget } from \"../engine/render-target.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport type { Task } from \"./task.js\";\n\n/** Options for a depth-resolve frame-graph task. */\nexport interface DepthResolveTaskConfig {\n name?: string;\n /** Multisampled source render target whose DEPTH attachment is resolved (must have sampleCount \\> 1). */\n sourceTexture: RenderTarget;\n /** Single-sample destination render target whose DEPTH attachment receives the resolved depth. */\n targetTexture: RenderTarget;\n}\n\nconst VERTEX_WGSL = `struct V{@builtin(position)p:vec4f};\n@vertex fn vs(@builtin(vertex_index)i:u32)->V{\nvar pos=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));\nreturn V(vec4f(pos[i],0,1));}`;\nconst FRAGMENT_WGSL = `@group(0)@binding(0)var src:texture_depth_multisampled_2d;\n@fragment fn fs(v:V)->@builtin(frag_depth)f32{return textureLoad(src,vec2i(v.p.xy),0);}`;\n\n// Per-device cache (keyed by GPUDevice identity), lazily built on first use so scenes that never resolve depth\n// pay nothing.\nlet _cacheDevice: GPUDevice | null = null;\nlet _bgl: GPUBindGroupLayout | null = null;\nlet _pipelines: Map<GPUTextureFormat, GPURenderPipeline> | null = null;\n\nfunction getOrCreatePipeline(engine: EngineContext, depthFormat: GPUTextureFormat): GPURenderPipeline {\n const device = engine._device;\n if (_cacheDevice !== device) {\n _cacheDevice = device;\n _bgl = null;\n _pipelines = new Map();\n }\n const cached = _pipelines!.get(depthFormat);\n if (cached) {\n return cached;\n }\n _bgl ??= device.createBindGroupLayout({\n label: \"depth-resolve-bgl\",\n entries: [{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: \"depth\", multisampled: true } }],\n });\n const module = device.createShaderModule({ code: `${VERTEX_WGSL}\\n${FRAGMENT_WGSL}`, label: \"depth-resolve\" });\n const pipeline = device.createRenderPipeline({\n label: `depth-resolve-${depthFormat}`,\n layout: device.createPipelineLayout({ label: \"depth-resolve-layout\", bindGroupLayouts: [_bgl] }),\n vertex: { module, entryPoint: \"vs\" },\n fragment: { module, entryPoint: \"fs\", targets: [] }, // depth-only: no colour target\n primitive: { topology: \"triangle-list\" },\n depthStencil: { format: depthFormat, depthWriteEnabled: true, depthCompare: \"always\" },\n });\n _pipelines!.set(depthFormat, pipeline);\n return pipeline;\n}\n\n/** Create a frame-graph task that resolves `sourceTexture`'s multisampled depth into `targetTexture`'s\n * single-sample depth. Add it AFTER the source render task and BEFORE any depth-sampling consumer. */\nexport function createDepthResolveTask(config: DepthResolveTaskConfig, engine: EngineContext, scene: SceneContext): Task {\n const eng = engine;\n const depthAttachment: GPURenderPassDepthStencilAttachment = {\n view: undefined!,\n depthClearValue: 0, // every fragment overwrites it (depthCompare \"always\"), so the clear value is moot\n depthLoadOp: \"clear\",\n depthStoreOp: \"store\",\n };\n const renderPassDescriptor: GPURenderPassDescriptor = {\n label: config.name ?? \"depth-resolve\",\n colorAttachments: [],\n depthStencilAttachment: depthAttachment,\n };\n let pipeline: GPURenderPipeline | null = null;\n let bindGroup: GPUBindGroup | null = null;\n let boundSrc: GPUTexture | null = null;\n let boundDst: GPUTexture | null = null;\n\n // (Re)build the pipeline, bind group and depth-attachment view from the live RT textures. Run at record()\n // and again whenever a resize reallocates either texture (checked in execute, mirroring the DoF getters).\n const build = (): void => {\n const source = config.sourceTexture;\n const target = config.targetTexture;\n if (!source._depthTexture) {\n throw new Error(`DepthResolveTask \"${config.name}\": sourceTexture has no depth attachment.`);\n }\n if ((source._descriptor.samples ?? 1) < 2) {\n throw new Error(`DepthResolveTask \"${config.name}\": sourceTexture must be multisampled (sampleCount > 1).`);\n }\n if (!target._depthTexture || target._width !== (source._width || 0) || target._height !== (source._height || 0)) {\n // Build (or REBUILD) the offscreen destination so it tracks the source size. No render task owns this\n // target, so the frame graph never resizes it on its own — without this, a window resize leaves the\n // resolved depth stuck at the OLD size, and every depth-reconstruction consumer (SSCS, SSAO, the\n // shadow-TAA stabiliser) then samples a mismatched-size depth → screen-space streaks until reload.\n buildRenderTarget(target, eng);\n // buildRenderTarget sizes the target from its OWN descriptor (resolveSize), not the source. The whole\n // point of this task is a 1:1 depth copy, so the target descriptor MUST resolve to the source size\n // (e.g. both `size: surface`). Fail fast on a mismatch instead of silently thrashing — otherwise this\n // branch's condition would stay true and rebuild/destroy the target on every build() call.\n if (target._width !== source._width || target._height !== source._height) {\n throw new Error(\n `DepthResolveTask \"${config.name}\": targetTexture size ${target._width}×${target._height} must match ` +\n `sourceTexture size ${source._width}×${source._height} (size the target's descriptor like the source, e.g. both \\`size: surface\\`).`\n );\n }\n }\n const depthFormat = target._descriptor.dFormat;\n if (!depthFormat) {\n throw new Error(`DepthResolveTask \"${config.name}\": targetTexture has no depth format.`);\n }\n pipeline = getOrCreatePipeline(eng, depthFormat);\n // A DEPTH-aspect view of the MSAA source: a depth-stencil texture must be bound through its depth aspect\n // to read as texture_depth_multisampled_2d.\n const srcView = source._depthTexture.createView({ aspect: \"depth-only\" });\n bindGroup = eng._device.createBindGroup({ label: `${config.name ?? \"depth-resolve\"}-bg`, layout: _bgl!, entries: [{ binding: 0, resource: srcView }] });\n depthAttachment.view = target._depthView!;\n boundSrc = source._depthTexture;\n boundDst = target._depthTexture;\n };\n\n return {\n name: config.name ?? \"depth-resolve\",\n engine: eng,\n scene,\n _passes: [],\n record(): void {\n build();\n },\n execute(): number {\n if (config.sourceTexture._depthTexture !== boundSrc || config.targetTexture._depthTexture !== boundDst) {\n build(); // a resize reallocated the MSAA depth and/or the resolve target — rebind to the new textures\n }\n const pass = eng._currentEncoder.beginRenderPass(renderPassDescriptor);\n pass.setPipeline(pipeline!);\n pass.setBindGroup(0, bindGroup!);\n pass.draw(3);\n pass.end();\n return 1;\n },\n dispose(): void {\n pipeline = null;\n bindGroup = null;\n boundSrc = null;\n boundDst = null;\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -202,7 +202,8 @@ function disposeRenderTaskTransmission(state) {
|
|
|
202
202
|
function executePassWithTransmission(task, engine, state, sampleCount) {
|
|
203
203
|
state._copies = 0;
|
|
204
204
|
const transparent = task._transparentBindings;
|
|
205
|
-
|
|
205
|
+
const resolveView = sampleCount > 1 ? task._config.rst?._colorView ?? null : null;
|
|
206
|
+
let pass = beginTaskPass(task, resolveView, sampleCount, false);
|
|
206
207
|
let draws = drawBaseTask(task, pass);
|
|
207
208
|
let lastPipeline = null;
|
|
208
209
|
let overlay = null;
|
|
@@ -216,7 +217,7 @@ function executePassWithTransmission(task, engine, state, sampleCount) {
|
|
|
216
217
|
if (transmissive && canUpdateTransmission(state)) {
|
|
217
218
|
pass.end();
|
|
218
219
|
updateTransmissionTexture(state, engine);
|
|
219
|
-
pass = beginTaskPass(task,
|
|
220
|
+
pass = beginTaskPass(task, resolveView, sampleCount, true);
|
|
220
221
|
setPassState(task, pass);
|
|
221
222
|
lastPipeline = null;
|
|
222
223
|
}
|
|
@@ -337,7 +338,7 @@ function beginTaskPass(task, resolveTarget, sampleCount, load) {
|
|
|
337
338
|
}
|
|
338
339
|
}
|
|
339
340
|
if (sampleCount > 1) {
|
|
340
|
-
att.resolveTarget = void 0;
|
|
341
|
+
att.resolveTarget = resolveTarget ?? void 0;
|
|
341
342
|
} else {
|
|
342
343
|
att.resolveTarget = void 0;
|
|
343
344
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transmission.js","sources":["../../../src/frame-graph/transmission.ts"],"sourcesContent":["import { TU, SS } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { _vis } from \"../engine/engine.js\";\nimport { createRenderTarget } from \"../engine/render-target.js\";\nimport { getBilinearSampler } from \"../resource/samplers.js\";\nimport { getTrilinearAnisotropicSampler } from \"../resource/trilinear-anisotropic-sampler.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { recordMipmaps } from \"../texture/generate-mipmaps.js\";\nimport { biasedMipLevelCount } from \"../texture/mip-count.js\";\nimport type { DrawBinding } from \"../render/renderable.js\";\nimport type { RenderTask } from \"./render-task.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport { createImageProcessingTask } from \"./image-processing-task.js\";\n\nexport interface RenderTaskTransmissionState {\n readonly texture: Texture2D;\n /** @internal */\n readonly _baseView: GPUTextureView;\n /** @internal */\n _sourceWidth: number;\n /** @internal */\n _sourceHeight: number;\n /** @internal */\n _sourceTexture: GPUTexture | null;\n /** @internal */\n _blit: TransmissionBlitState | null;\n /** @internal */\n readonly _copyCount: number;\n /** @internal */\n readonly _generateMipmaps: boolean;\n /** @internal */\n _copies: number;\n}\n\ninterface TransmissionBlitState {\n readonly _pipeline: GPURenderPipeline;\n readonly _bindGroup: GPUBindGroup;\n}\n\nconst BLIT_SHADER = `@group(0)@binding(0)var t:texture_2d<f32>;@group(0)@binding(1)var s:sampler;struct V{@builtin(position)p:vec4f,@location(0)u:vec2f};@vertex fn vs(@builtin(vertex_index)i:u32)->V{var p=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));var u=array<vec2f,3>(vec2f(0,1),vec2f(2,1),vec2f(0,-1));return V(vec4f(p[i],0,1),u[i]);}@fragment fn fs(v:V)->@location(0)vec4f{return textureSample(t,s,v.u);}`;\nconst BLIT_MSAA_SHADER = `@group(0)@binding(0)var t:texture_multisampled_2d<f32>;struct V{@builtin(position)p:vec4f,@location(0)u:vec2f};@vertex fn vs(@builtin(vertex_index)i:u32)->V{var p=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));var u=array<vec2f,3>(vec2f(0,1),vec2f(2,1),vec2f(0,-1));return V(vec4f(p[i],0,1),u[i]);}fn l(p:vec2i)->vec4f{let n=textureNumSamples(t);var c=vec4f(0);for(var i=0u;i<n;i++){c+=textureLoad(t,p,i);}return c/f32(n);}@fragment fn fs(v:V)->@location(0)vec4f{let d=vec2i(textureDimensions(t));let q=clamp(v.u*vec2f(d)-.5,vec2f(0),vec2f(d-vec2i(1)));let p=vec2i(floor(q));let f=fract(q);let p1=min(p+vec2i(1),d-vec2i(1));return mix(mix(l(p),l(vec2i(p1.x,p.y)),f.x),mix(l(vec2i(p.x,p1.y)),l(p1),f.x),f.y);}`;\nconst REFRACTION_LOD_BIAS = 4;\nlet blitPipelines: Map<string, GPURenderPipeline> | null = null;\nlet blitShader: GPUShaderModule | null = null;\nlet blitMsaaShader: GPUShaderModule | null = null;\nlet blitBgl: GPUBindGroupLayout | null = null;\nlet blitMsaaBgl: GPUBindGroupLayout | null = null;\nlet blitDevice: GPUDevice | null = null;\n\n/** Enable scene-color transmission for every render task currently registered in a scene. PBR materials are marked for linear transmission, and a trailing image-processing task is appended when needed. */\nexport function enableSceneTransmission(scene: SceneContext, engine: EngineContext): void {\n markPbrMaterialsLinear(scene);\n let lastRenderTask: RenderTask | null = null;\n for (const task of scene._frameGraph._tasks) {\n if (\"_renderables\" in task) {\n const renderTask = task as RenderTask;\n enableRenderTaskTransmission(renderTask, engine);\n lastRenderTask = renderTask;\n }\n }\n if (lastRenderTask && !scene._frameGraph._tasks.some((task) => task.name === \"transmission-image-processing\")) {\n scene._frameGraph._tasks.push(createImageProcessingTask({ name: \"transmission-image-processing\", source: lastRenderTask._config.rt }, engine, scene));\n }\n}\n\n/** Options controlling how a render task exposes opaque scene color to transmissive materials. Use these to opt out of the linear offscreen path, control refresh frequency, and limit mipmap generation cost. */\nexport interface TransmissionOptions {\n /** When true (the default), retarget the task's color buffer to a linear `rgba16float`\n * offscreen and tone-map it in a trailing image-processing pass — the model PBR\n * transmission uses so refractive materials read scene color in *linear* space.\n *\n * Set false to perform ONLY the mid-pass scene-color grab: the task's render target\n * format / sample count / clear are left untouched and no tone-map pass is added. Use\n * this for consumers that own their tone mapping / post (e.g. a custom depth-of-field\n * stack) and just need the opaque scene color exposed to a custom transmissive\n * `ShaderMaterial`. */\n linear?: boolean;\n /** Override how many times the scene-colour grab is refreshed per frame. `0` means before every\n * transmissive draw; the default is once before the first transmissive draw. */\n copyCount?: number;\n /** Set false when the transmissive material never samples the scene-colour grab above mip 0. */\n generateMipmaps?: boolean;\n /** Cap the scene-colour grab mip chain. Use this when the material samples explicit low LODs only, so\n * unused tiny mips are not regenerated every frame. Ignored when `generateMipmaps` is false. */\n mipLevelCount?: number;\n}\n\n/** Handle to a render task's scene-color grab, returned by `enableRenderTaskTransmission`. */\nexport interface SceneColorGrab {\n /** The live opaque-scene-color texture sampled by transmissive surfaces, or null before the\n * frame graph has built the task at least once. Its identity changes when the task rebuilds\n * (e.g. on resize), so consumers that bind it to a custom material should re-bind when it\n * changes. */\n readonly texture: Texture2D | null;\n}\n\n/** Enable mid-pass scene-color grabs for a single render task and return the live texture handle. The task is wrapped so transmissive draw calls can sample the opaque color rendered earlier in the same pass. */\nexport function enableRenderTaskTransmission(task: RenderTask, engine: EngineContext, options?: TransmissionOptions): SceneColorGrab {\n const linear = options?.linear !== false;\n applyTransmissionOptions(task, options);\n const grab: SceneColorGrab = {\n get texture(): Texture2D | null {\n return (task._targetSignature as { _transmissionTexture?: Texture2D })._transmissionTexture ?? null;\n },\n };\n if (task._executeWithTransmission) {\n return grab;\n }\n if (linear) {\n retargetRenderTaskToLinearOffscreen(task);\n }\n let state: RenderTaskTransmissionState | null = null;\n const record = task.record.bind(task);\n const execute = task.execute?.bind(task);\n const dispose = task.dispose?.bind(task);\n task.record = () => {\n disposeRenderTaskTransmission(state);\n state = createRenderTaskTransmission(task, engine);\n (task._targetSignature as { _transmissionTexture?: Texture2D })._transmissionTexture = state.texture;\n record();\n configureTransmissionSource(state, task, engine);\n };\n if (linear && execute) {\n task.execute = () => executeRenderTaskLinear(task.scene, execute);\n }\n task.dispose = () => {\n disposeRenderTaskTransmission(state);\n state = null;\n dispose?.();\n };\n task._executeWithTransmission = (sampleCount) => executePassWithTransmission(task, engine, state!, sampleCount);\n return grab;\n}\n\nfunction retargetRenderTaskToLinearOffscreen(task: RenderTask): void {\n const cfg = task._config;\n const oldDesc = cfg.rt._descriptor;\n const surface = task.scene.surface;\n const sampleCount = surface.msaaSamples;\n // The scene render task may target the shared engine scRT (single-sample,\n // colour-only — single-sample default path) or an MSAA colour RT that resolves into it\n // via `rst` (MSAA default path). Never mutate the shared scRT descriptor —\n // instead point the task at a fresh offscreen HDR target and stop resolving to swap.\n // Transmission samples this linear HDR result in its own final image-processing pass\n // that writes the tonemapped result to the swapchain.\n //\n // Depth ownership: when the task already carries an external depth (`cfg.depth`, the\n // single-sample default path), keep it; otherwise the new target owns depth (matching\n // the MSAA colour RT it replaces).\n const ownsDepth = !cfg.depth;\n const newRt = createRenderTarget({\n lbl: \"transmission-linear\",\n format: \"rgba16float\",\n dFormat: ownsDepth ? (oldDesc.dFormat ?? \"depth24plus-stencil8\") : undefined,\n _depthClearValue: oldDesc._depthClearValue,\n _depthCompare: oldDesc._depthCompare,\n samples: sampleCount,\n size: surface,\n });\n cfg.rt = newRt;\n cfg.rst = undefined;\n const sig = task._targetSignature as {\n _colorFormat?: GPUTextureFormat;\n _depthStencilFormat?: GPUTextureFormat;\n _depthCompare?: GPUCompareFunction;\n _sampleCount: number;\n };\n sig._colorFormat = \"rgba16float\";\n sig._depthStencilFormat = cfg.depth?._descriptor.dFormat ?? newRt._descriptor.dFormat;\n sig._depthCompare = newRt._descriptor._depthCompare;\n sig._sampleCount = sampleCount;\n task._opaqueBundles.length = 0;\n task._lastVersion = -1;\n}\n\nfunction executeRenderTaskLinear(scene: SceneContext, execute: () => number): number {\n const imageProcessing = scene.imageProcessing as { exposure: number; contrast: number; toneMappingEnabled: boolean | number };\n const toneMappingEnabled = imageProcessing.toneMappingEnabled;\n const clearColor = scene.clearColor;\n const linearClearColor = inverseImageProcessedColor(clearColor, imageProcessing.exposure, imageProcessing.contrast, toneMappingEnabled === true);\n imageProcessing.toneMappingEnabled = -1;\n scene.clearColor = linearClearColor;\n try {\n return execute();\n } finally {\n scene.clearColor = clearColor;\n imageProcessing.toneMappingEnabled = toneMappingEnabled;\n }\n}\n\nfunction inverseImageProcessedColor(color: GPUColorDict, exposure: number, contrast: number, toneMapping: boolean): GPUColorDict {\n return {\n r: inverseImageProcessedChannel(color.r, exposure, contrast, toneMapping),\n g: inverseImageProcessedChannel(color.g, exposure, contrast, toneMapping),\n b: inverseImageProcessedChannel(color.b, exposure, contrast, toneMapping),\n a: color.a,\n };\n}\n\nfunction inverseImageProcessedChannel(value: number, exposure: number, contrast: number, toneMapping: boolean): number {\n let c = clamp01(value);\n if (contrast < 1) {\n c = contrast > 0 ? clamp01((c - 0.5 * (1 - contrast)) / contrast) : 0.5;\n } else if (contrast > 1) {\n const mixAmount = contrast - 1;\n let lo = 0;\n let hi = 1;\n for (let i = 0; i < 16; i++) {\n const mid = (lo + hi) * 0.5;\n const high = mid * mid * (3 - 2 * mid);\n const out = mid + (high - mid) * mixAmount;\n if (out < c) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n c = (lo + hi) * 0.5;\n }\n c = c ** 2.2;\n if (toneMapping) {\n c = -Math.log2(Math.max(1 - c, 1e-6)) / 1.5905790328979492;\n }\n return exposure > 0 ? c / exposure : c;\n}\n\nfunction clamp01(v: number): number {\n return Math.min(Math.max(v, 0), 1);\n}\n\nfunction markPbrMaterialsLinear(scene: SceneContext): void {\n for (const mesh of scene.meshes) {\n const mat = mesh.material as { _linearImageProcessing?: boolean; _renderFeatures?: unknown } | undefined;\n if (mat) {\n mat._linearImageProcessing = true;\n mat._renderFeatures = undefined;\n }\n }\n}\n\nfunction createRenderTaskTransmission(task: RenderTask, engine: EngineContext): RenderTaskTransmissionState {\n const rt = task._config.rt;\n const width = 1024;\n const height = 1024;\n const format: GPUTextureFormat = \"rgba16float\";\n const mipLevelCount = transmissionMipLevelCount(task._config.transmission, width, height);\n const generateMipmaps = mipLevelCount > 1;\n const texture = engine._device.createTexture({\n label: task.name,\n size: { width, height },\n format,\n mipLevelCount,\n usage: TU.RENDER_ATTACHMENT | TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n const tex: Texture2D = {\n texture,\n view: texture.createView(),\n sampler: getTrilinearAnisotropicSampler(engine),\n width,\n height,\n invertY: false,\n };\n return {\n texture: tex,\n _baseView: texture.createView({ baseMipLevel: 0, mipLevelCount: 1 }),\n _sourceWidth: rt._width,\n _sourceHeight: rt._height,\n _sourceTexture: null,\n _blit: null,\n _copyCount: normalizeCopyCount(task._config.transmission),\n _generateMipmaps: generateMipmaps,\n _copies: 0,\n };\n}\n\nfunction configureTransmissionSource(state: RenderTaskTransmissionState, task: RenderTask, engine: EngineContext): void {\n const rt = task._config.rt;\n state._sourceWidth = rt._width;\n state._sourceHeight = rt._height;\n state._sourceTexture = rt._colorTexture;\n const sampleCount = task._targetSignature._sampleCount;\n if (!state._sourceTexture) {\n return;\n }\n state._blit = shouldBlitTransmission(state, sampleCount) ? createTransmissionBlit(state, engine, state._sourceTexture, sampleCount > 1) : null;\n}\n\nfunction disposeRenderTaskTransmission(state: RenderTaskTransmissionState | null | undefined): void {\n state?.texture.texture.destroy();\n}\n\nexport function executePassWithTransmission(task: RenderTask, engine: EngineContext, state: RenderTaskTransmissionState, sampleCount: number): number {\n state._copies = 0;\n const transparent = task._transparentBindings;\n let pass = beginTaskPass(task, null, sampleCount, false);\n let draws = drawBaseTask(task, pass);\n let lastPipeline: GPURenderPipeline | null = null;\n let overlay: DrawBinding[] | null = null;\n for (let i = 0; i < transparent.length; i++) {\n const binding = transparent[i]!;\n // `Mesh.renderOnTop` surfaces draw last — after the scene-colour grab — so they sit on top of the\n // transmissive surface and are excluded from what it refracts (e.g. lily pads on water).\n if (binding.renderable.mesh?.renderOnTop === true) {\n (overlay ??= []).push(binding);\n continue;\n }\n const transmissive = binding.renderable._transmissive === true;\n if (transmissive && canUpdateTransmission(state)) {\n pass.end();\n updateTransmissionTexture(state, engine);\n pass = beginTaskPass(task, null, sampleCount, true);\n setPassState(task, pass);\n lastPipeline = null;\n }\n const mesh = binding.renderable.mesh;\n if (mesh && mesh.visible === false) {\n continue;\n }\n if (binding.pipeline !== lastPipeline) {\n pass.setPipeline(binding.pipeline);\n lastPipeline = binding.pipeline;\n }\n draws += binding.draw(pass, engine);\n }\n if (overlay) {\n draws += drawList(pass, overlay, engine);\n }\n pass.end();\n return draws;\n}\n\nfunction updateTransmissionTexture(state: RenderTaskTransmissionState, engine: EngineContext): void {\n if (!state._sourceTexture) {\n throw new Error(\"No transmission source\");\n }\n if (state._blit) {\n blitToTransmission(state, engine);\n } else {\n engine._currentEncoder.copyTextureToTexture(\n { texture: state._sourceTexture },\n { texture: state.texture.texture },\n { width: state.texture.width, height: state.texture.height }\n );\n }\n if (state._generateMipmaps) {\n recordMipmaps(engine, state.texture.texture, engine._currentEncoder);\n }\n state._copies++;\n}\n\nfunction getBlitPipeline(engine: EngineContext, format: GPUTextureFormat, multisampled: boolean): GPURenderPipeline {\n const device = engine._device;\n if (device !== blitDevice) {\n blitPipelines?.clear();\n blitPipelines = null;\n blitShader = null;\n blitMsaaShader = null;\n blitBgl = null;\n blitMsaaBgl = null;\n blitDevice = device;\n }\n if (multisampled) {\n blitMsaaShader ??= device.createShaderModule({ code: BLIT_MSAA_SHADER });\n blitMsaaBgl ??= device.createBindGroupLayout({\n entries: [{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: \"unfilterable-float\", multisampled: true } }],\n });\n } else {\n blitShader ??= device.createShaderModule({ code: BLIT_SHADER });\n blitBgl ??= device.createBindGroupLayout({\n entries: [\n { binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: \"float\" } },\n { binding: 1, visibility: SS.FRAGMENT, sampler: {} },\n ],\n });\n }\n blitPipelines ??= new Map();\n const key = `${format}:${multisampled ? \"msaa\" : \"\"}`;\n let pipeline = blitPipelines.get(key);\n if (!pipeline) {\n const bgl = multisampled ? blitMsaaBgl! : blitBgl!;\n pipeline = device.createRenderPipeline({\n label: \"transmission-copy\",\n layout: device.createPipelineLayout({ bindGroupLayouts: [bgl] }),\n vertex: { module: multisampled ? blitMsaaShader! : blitShader!, entryPoint: \"vs\" },\n fragment: { module: multisampled ? blitMsaaShader! : blitShader!, entryPoint: \"fs\", targets: [{ format }] },\n primitive: { topology: \"triangle-list\" },\n });\n blitPipelines.set(key, pipeline);\n }\n return pipeline;\n}\n\nfunction shouldBlitTransmission(state: RenderTaskTransmissionState, sampleCount: number): boolean {\n return sampleCount > 1 || state._sourceWidth !== state.texture.width || state._sourceHeight !== state.texture.height;\n}\n\nfunction createTransmissionBlit(state: RenderTaskTransmissionState, engine: EngineContext, source: GPUTexture, multisampled: boolean): TransmissionBlitState {\n const device = engine._device;\n const pipeline = getBlitPipeline(engine, state.texture.texture.format, multisampled);\n const bindGroup = device.createBindGroup({\n layout: multisampled ? blitMsaaBgl! : blitBgl!,\n entries: multisampled\n ? [{ binding: 0, resource: source.createView() }]\n : [\n { binding: 0, resource: source.createView() },\n { binding: 1, resource: getBilinearSampler(engine) },\n ],\n });\n return { _pipeline: pipeline, _bindGroup: bindGroup };\n}\n\nfunction blitToTransmission(state: RenderTaskTransmissionState, engine: EngineContext): void {\n const blit = state._blit!;\n const pass = engine._currentEncoder.beginRenderPass({\n colorAttachments: [{ view: state._baseView, loadOp: \"clear\", storeOp: \"store\", clearValue: { r: 0, g: 0, b: 0, a: 0 } }],\n });\n pass.setPipeline(blit._pipeline);\n pass.setBindGroup(0, blit._bindGroup);\n pass.draw(3);\n pass.end();\n}\n\nfunction canUpdateTransmission(state: RenderTaskTransmissionState): boolean {\n return state._copyCount === 0 || state._copies < state._copyCount;\n}\n\nfunction beginTaskPass(task: RenderTask, resolveTarget: GPUTextureView | null, sampleCount: number, load: boolean): GPURenderPassEncoder {\n const att = task._colorAttachment;\n const depthLoadOp = load || !task._config.clr ? \"load\" : \"clear\";\n if (load) {\n att.loadOp = \"load\";\n }\n const depthAttachment = task._renderPassDescriptor.depthStencilAttachment;\n if (depthAttachment) {\n depthAttachment.depthLoadOp = depthLoadOp;\n if (depthAttachment.stencilLoadOp) {\n depthAttachment.stencilLoadOp = depthLoadOp;\n }\n }\n if (sampleCount > 1) {\n att.resolveTarget = resolveTarget ?? undefined;\n } else {\n att.resolveTarget = undefined;\n }\n return task.engine._currentEncoder.beginRenderPass(task._renderPassDescriptor);\n}\n\nfunction setPassState(task: RenderTask, pass: GPURenderPassEncoder): void {\n const cfg = task._config;\n const rt = cfg.rt;\n const scene = task.scene;\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 pass.setBindGroup(0, task._sceneBG);\n}\n\nfunction drawBaseTask(task: RenderTask, pass: GPURenderPassEncoder): number {\n const eng = task.engine;\n const rt = task._config.rt;\n const scene = task.scene;\n const opaqueBindings = task._opaqueBindings;\n const opaqueBundles = task._opaqueBundles;\n\n setPassState(task, pass);\n\n if (task._lastVersion !== scene._renderableVersion || task._lastVis !== _vis || opaqueBundles.length === 0) {\n const desc = rt._descriptor;\n const be = eng._device.createRenderBundleEncoder({\n colorFormats: desc.format ? [desc.format] : [],\n depthStencilFormat: desc.dFormat,\n sampleCount: desc.samples ?? 1,\n });\n be.setBindGroup(0, task._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 pass.setBindGroup(0, task._sceneBG);\n draws += drawList(pass, task._directBindings, eng);\n return draws;\n}\n\nfunction 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\nfunction normalizeCopyCount(cfg: RenderTask[\"_config\"][\"transmission\"]): number {\n const count = cfg?.copyCount ?? 1;\n return count === Infinity ? 0 : Math.max(0, count | 0);\n}\n\nfunction applyTransmissionOptions(task: RenderTask, options: TransmissionOptions | undefined): void {\n if (!options) {\n return;\n }\n let next = task._config.transmission;\n let changed = false;\n const set = <K extends keyof NonNullable<RenderTask[\"_config\"][\"transmission\"]>>(key: K, value: NonNullable<RenderTask[\"_config\"][\"transmission\"]>[K] | undefined): void => {\n if (value === undefined) {\n return;\n }\n next = { ...next, [key]: value };\n changed = true;\n };\n set(\"copyCount\", options.copyCount);\n set(\"generateMipmaps\", options.generateMipmaps);\n set(\"mipLevelCount\", options.mipLevelCount);\n if (changed) {\n task._config.transmission = next;\n }\n}\n\nfunction transmissionMipLevelCount(cfg: RenderTask[\"_config\"][\"transmission\"], width: number, height: number): number {\n if (cfg?.generateMipmaps === false) {\n return 1;\n }\n const full = Math.floor(Math.log2(Math.max(width, height))) + 1;\n const defaultCount = biasedMipLevelCount(width, height, REFRACTION_LOD_BIAS);\n const requested = cfg?.mipLevelCount;\n if (requested === undefined) {\n return Math.min(full, defaultCount);\n }\n return Math.min(full, Math.max(1, requested | 0));\n}\n"],"names":[],"mappings":";;;;;;;;;AAuCA,MAAM,WAAA,GAAc,CAAA,4YAAA,CAAA;AACpB,MAAM,gBAAA,GAAmB,CAAA,0sBAAA,CAAA;AACzB,MAAM,mBAAA,GAAsB,CAAA;AAC5B,IAAI,aAAA,GAAuD,IAAA;AAC3D,IAAI,UAAA,GAAqC,IAAA;AACzC,IAAI,cAAA,GAAyC,IAAA;AAC7C,IAAI,OAAA,GAAqC,IAAA;AACzC,IAAI,WAAA,GAAyC,IAAA;AAC7C,IAAI,UAAA,GAA+B,IAAA;AAG5B,SAAS,uBAAA,CAAwB,OAAqB,MAAA,EAA6B;AACtF,EAAA,sBAAA,CAAuB,KAAK,CAAA;AAC5B,EAAA,IAAI,cAAA,GAAoC,IAAA;AACxC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,CAAM,WAAA,CAAY,MAAA,EAAQ;AACzC,IAAA,IAAI,kBAAkB,IAAA,EAAM;AACxB,MAAA,MAAM,UAAA,GAAa,IAAA;AACnB,MAAA,4BAAA,CAA6B,YAAY,MAAM,CAAA;AAC/C,MAAA,cAAA,GAAiB,UAAA;AAAA,IACrB;AAAA,EACJ;AACA,EAAA,IAAI,cAAA,IAAkB,CAAC,KAAA,CAAM,WAAA,CAAY,MAAA,CAAO,IAAA,CAAK,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,KAAS,+BAA+B,CAAA,EAAG;AAC3G,IAAA,KAAA,CAAM,WAAA,CAAY,MAAA,CAAO,IAAA,CAAK,yBAAA,CAA0B,EAAE,IAAA,EAAM,+BAAA,EAAiC,MAAA,EAAQ,cAAA,CAAe,OAAA,CAAQ,EAAA,EAAG,EAAG,MAAA,EAAQ,KAAK,CAAC,CAAA;AAAA,EACxJ;AACJ;AAkCO,SAAS,4BAAA,CAA6B,IAAA,EAAkB,MAAA,EAAuB,OAAA,EAA+C;AACjI,EAAA,MAAM,MAAA,GAAS,SAAS,MAAA,KAAW,KAAA;AACnC,EAAA,wBAAA,CAAyB,MAAM,OAAO,CAAA;AACtC,EAAA,MAAM,IAAA,GAAuB;AAAA,IACzB,IAAI,OAAA,GAA4B;AAC5B,MAAA,OAAQ,IAAA,CAAK,iBAA0D,oBAAA,IAAwB,IAAA;AAAA,IACnG;AAAA,GACJ;AACA,EAAA,IAAI,KAAK,wBAAA,EAA0B;AAC/B,IAAA,OAAO,IAAA;AAAA,EACX;AACA,EAAA,IAAI,MAAA,EAAQ;AACR,IAAA,mCAAA,CAAoC,IAAI,CAAA;AAAA,EAC5C;AACA,EAAA,IAAI,KAAA,GAA4C,IAAA;AAChD,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,IAAI,CAAA;AACvC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,IAAI,CAAA;AACvC,EAAA,IAAA,CAAK,SAAS,MAAM;AAChB,IAAA,6BAAA,CAA8B,KAAK,CAAA;AACnC,IAAA,KAAA,GAAQ,4BAAA,CAA6B,MAAM,MAAM,CAAA;AACjD,IAAC,IAAA,CAAK,gBAAA,CAA0D,oBAAA,GAAuB,KAAA,CAAM,OAAA;AAC7F,IAAA,MAAA,EAAO;AACP,IAAA,2BAAA,CAA4B,KAAA,EAAO,MAAM,MAAM,CAAA;AAAA,EACnD,CAAA;AACA,EAAA,IAAI,UAAU,OAAA,EAAS;AACnB,IAAA,IAAA,CAAK,OAAA,GAAU,MAAM,uBAAA,CAAwB,IAAA,CAAK,OAAO,OAAO,CAAA;AAAA,EACpE;AACA,EAAA,IAAA,CAAK,UAAU,MAAM;AACjB,IAAA,6BAAA,CAA8B,KAAK,CAAA;AACnC,IAAA,KAAA,GAAQ,IAAA;AACR,IAAA,OAAA,IAAU;AAAA,EACd,CAAA;AACA,EAAA,IAAA,CAAK,2BAA2B,CAAC,WAAA,KAAgB,4BAA4B,IAAA,EAAM,MAAA,EAAQ,OAAQ,WAAW,CAAA;AAC9G,EAAA,OAAO,IAAA;AACX;AAEA,SAAS,oCAAoC,IAAA,EAAwB;AACjE,EAAA,MAAM,MAAM,IAAA,CAAK,OAAA;AACjB,EAAA,MAAM,OAAA,GAAU,IAAI,EAAA,CAAG,WAAA;AACvB,EAAA,MAAM,OAAA,GAAU,KAAK,KAAA,CAAM,OAAA;AAC3B,EAAA,MAAM,cAAc,OAAA,CAAQ,WAAA;AAW5B,EAAA,MAAM,SAAA,GAAY,CAAC,GAAA,CAAI,KAAA;AACvB,EAAA,MAAM,QAAQ,kBAAA,CAAmB;AAAA,IAC7B,GAAA,EAAK,qBAAA;AAAA,IACL,MAAA,EAAQ,aAAA;AAAA,IACR,OAAA,EAAS,SAAA,GAAa,OAAA,CAAQ,OAAA,IAAW,sBAAA,GAA0B,MAAA;AAAA,IACnE,kBAAkB,OAAA,CAAQ,gBAAA;AAAA,IAC1B,eAAe,OAAA,CAAQ,aAAA;AAAA,IACvB,OAAA,EAAS,WAAA;AAAA,IACT,IAAA,EAAM;AAAA,GACT,CAAA;AACD,EAAA,GAAA,CAAI,EAAA,GAAK,KAAA;AACT,EAAA,GAAA,CAAI,GAAA,GAAM,MAAA;AACV,EAAA,MAAM,MAAM,IAAA,CAAK,gBAAA;AAMjB,EAAA,GAAA,CAAI,YAAA,GAAe,aAAA;AACnB,EAAA,GAAA,CAAI,sBAAsB,GAAA,CAAI,KAAA,EAAO,WAAA,CAAY,OAAA,IAAW,MAAM,WAAA,CAAY,OAAA;AAC9E,EAAA,GAAA,CAAI,aAAA,GAAgB,MAAM,WAAA,CAAY,aAAA;AACtC,EAAA,GAAA,CAAI,YAAA,GAAe,WAAA;AACnB,EAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,EAAA,IAAA,CAAK,YAAA,GAAe,EAAA;AACxB;AAEA,SAAS,uBAAA,CAAwB,OAAqB,OAAA,EAA+B;AACjF,EAAA,MAAM,kBAAkB,KAAA,CAAM,eAAA;AAC9B,EAAA,MAAM,qBAAqB,eAAA,CAAgB,kBAAA;AAC3C,EAAA,MAAM,aAAa,KAAA,CAAM,UAAA;AACzB,EAAA,MAAM,gBAAA,GAAmB,2BAA2B,UAAA,EAAY,eAAA,CAAgB,UAAU,eAAA,CAAgB,QAAA,EAAU,uBAAuB,IAAI,CAAA;AAC/I,EAAA,eAAA,CAAgB,kBAAA,GAAqB,EAAA;AACrC,EAAA,KAAA,CAAM,UAAA,GAAa,gBAAA;AACnB,EAAA,IAAI;AACA,IAAA,OAAO,OAAA,EAAQ;AAAA,EACnB,CAAA,SAAE;AACE,IAAA,KAAA,CAAM,UAAA,GAAa,UAAA;AACnB,IAAA,eAAA,CAAgB,kBAAA,GAAqB,kBAAA;AAAA,EACzC;AACJ;AAEA,SAAS,0BAAA,CAA2B,KAAA,EAAqB,QAAA,EAAkB,QAAA,EAAkB,WAAA,EAAoC;AAC7H,EAAA,OAAO;AAAA,IACH,GAAG,4BAAA,CAA6B,KAAA,CAAM,CAAA,EAAG,QAAA,EAAU,UAAU,WAAW,CAAA;AAAA,IACxE,GAAG,4BAAA,CAA6B,KAAA,CAAM,CAAA,EAAG,QAAA,EAAU,UAAU,WAAW,CAAA;AAAA,IACxE,GAAG,4BAAA,CAA6B,KAAA,CAAM,CAAA,EAAG,QAAA,EAAU,UAAU,WAAW,CAAA;AAAA,IACxE,GAAG,KAAA,CAAM;AAAA,GACb;AACJ;AAEA,SAAS,4BAAA,CAA6B,KAAA,EAAe,QAAA,EAAkB,QAAA,EAAkB,WAAA,EAA8B;AACnH,EAAA,IAAI,CAAA,GAAI,QAAQ,KAAK,CAAA;AACrB,EAAA,IAAI,WAAW,CAAA,EAAG;AACd,IAAA,CAAA,GAAI,QAAA,GAAW,IAAI,OAAA,CAAA,CAAS,CAAA,GAAI,OAAO,CAAA,GAAI,QAAA,CAAA,IAAa,QAAQ,CAAA,GAAI,GAAA;AAAA,EACxE,CAAA,MAAA,IAAW,WAAW,CAAA,EAAG;AACrB,IAAA,MAAM,YAAY,QAAA,GAAW,CAAA;AAC7B,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,IAAI,EAAA,GAAK,CAAA;AACT,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AACzB,MAAA,MAAM,GAAA,GAAA,CAAO,KAAK,EAAA,IAAM,GAAA;AACxB,MAAA,MAAM,IAAA,GAAO,GAAA,GAAM,GAAA,IAAO,CAAA,GAAI,CAAA,GAAI,GAAA,CAAA;AAClC,MAAA,MAAM,GAAA,GAAM,GAAA,GAAA,CAAO,IAAA,GAAO,GAAA,IAAO,SAAA;AACjC,MAAA,IAAI,MAAM,CAAA,EAAG;AACT,QAAA,EAAA,GAAK,GAAA;AAAA,MACT,CAAA,MAAO;AACH,QAAA,EAAA,GAAK,GAAA;AAAA,MACT;AAAA,IACJ;AACA,IAAA,CAAA,GAAA,CAAK,KAAK,EAAA,IAAM,GAAA;AAAA,EACpB;AACA,EAAA,CAAA,GAAI,CAAA,IAAK,GAAA;AACT,EAAA,IAAI,WAAA,EAAa;AACb,IAAA,CAAA,GAAI,CAAC,KAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,GAAI,CAAA,EAAG,IAAI,CAAC,CAAA,GAAI,kBAAA;AAAA,EAC5C;AACA,EAAA,OAAO,QAAA,GAAW,CAAA,GAAI,CAAA,GAAI,QAAA,GAAW,CAAA;AACzC;AAEA,SAAS,QAAQ,CAAA,EAAmB;AAChC,EAAA,OAAO,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AACrC;AAEA,SAAS,uBAAuB,KAAA,EAA2B;AACvD,EAAA,KAAA,MAAW,IAAA,IAAQ,MAAM,MAAA,EAAQ;AAC7B,IAAA,MAAM,MAAM,IAAA,CAAK,QAAA;AACjB,IAAA,IAAI,GAAA,EAAK;AACL,MAAA,GAAA,CAAI,sBAAA,GAAyB,IAAA;AAC7B,MAAA,GAAA,CAAI,eAAA,GAAkB,MAAA;AAAA,IAC1B;AAAA,EACJ;AACJ;AAEA,SAAS,4BAAA,CAA6B,MAAkB,MAAA,EAAoD;AACxG,EAAA,MAAM,EAAA,GAAK,KAAK,OAAA,CAAQ,EAAA;AACxB,EAAA,MAAM,KAAA,GAAQ,IAAA;AACd,EAAA,MAAM,MAAA,GAAS,IAAA;AACf,EAAA,MAAM,MAAA,GAA2B,aAAA;AACjC,EAAA,MAAM,gBAAgB,yBAAA,CAA0B,IAAA,CAAK,OAAA,CAAQ,YAAA,EAAc,OAAO,MAAM,CAAA;AACxF,EAAA,MAAM,kBAAkB,aAAA,GAAgB,CAAA;AACxC,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,aAAA,CAAc;AAAA,IACzC,OAAO,IAAA,CAAK,IAAA;AAAA,IACZ,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,IACtB,MAAA;AAAA,IACA,aAAA;AAAA,IACA,KAAA,EAAO,EAAA,CAAG,iBAAA,GAAoB,EAAA,CAAG,kBAAkB,EAAA,CAAG;AAAA,GACzD,CAAA;AACD,EAAA,MAAM,GAAA,GAAiB;AAAA,IACnB,OAAA;AAAA,IACA,IAAA,EAAM,QAAQ,UAAA,EAAW;AAAA,IACzB,OAAA,EAAS,+BAA+B,MAAM,CAAA;AAAA,IAC9C,KAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACb;AACA,EAAA,OAAO;AAAA,IACH,OAAA,EAAS,GAAA;AAAA,IACT,SAAA,EAAW,QAAQ,UAAA,CAAW,EAAE,cAAc,CAAA,EAAG,aAAA,EAAe,GAAG,CAAA;AAAA,IACnE,cAAc,EAAA,CAAG,MAAA;AAAA,IACjB,eAAe,EAAA,CAAG,OAAA;AAAA,IAClB,cAAA,EAAgB,IAAA;AAAA,IAChB,KAAA,EAAO,IAAA;AAAA,IACP,UAAA,EAAY,kBAAA,CAAmB,IAAA,CAAK,OAAA,CAAQ,YAAY,CAAA;AAAA,IACxD,gBAAA,EAAkB,eAAA;AAAA,IAClB,OAAA,EAAS;AAAA,GACb;AACJ;AAEA,SAAS,2BAAA,CAA4B,KAAA,EAAoC,IAAA,EAAkB,MAAA,EAA6B;AACpH,EAAA,MAAM,EAAA,GAAK,KAAK,OAAA,CAAQ,EAAA;AACxB,EAAA,KAAA,CAAM,eAAe,EAAA,CAAG,MAAA;AACxB,EAAA,KAAA,CAAM,gBAAgB,EAAA,CAAG,OAAA;AACzB,EAAA,KAAA,CAAM,iBAAiB,EAAA,CAAG,aAAA;AAC1B,EAAA,MAAM,WAAA,GAAc,KAAK,gBAAA,CAAiB,YAAA;AAC1C,EAAA,IAAI,CAAC,MAAM,cAAA,EAAgB;AACvB,IAAA;AAAA,EACJ;AACA,EAAA,KAAA,CAAM,KAAA,GAAQ,sBAAA,CAAuB,KAAA,EAAO,WAAW,CAAA,GAAI,sBAAA,CAAuB,KAAA,EAAO,MAAA,EAAQ,KAAA,CAAM,cAAA,EAAgB,WAAA,GAAc,CAAC,CAAA,GAAI,IAAA;AAC9I;AAEA,SAAS,8BAA8B,KAAA,EAA6D;AAChG,EAAA,KAAA,EAAO,OAAA,CAAQ,QAAQ,OAAA,EAAQ;AACnC;AAEO,SAAS,2BAAA,CAA4B,IAAA,EAAkB,MAAA,EAAuB,KAAA,EAAoC,WAAA,EAA6B;AAClJ,EAAA,KAAA,CAAM,OAAA,GAAU,CAAA;AAChB,EAAA,MAAM,cAAc,IAAA,CAAK,oBAAA;AACzB,EAAA,IAAI,IAAA,GAAO,aAAA,CAAc,IAAA,EAAM,IAAA,EAAM,aAAa,KAAK,CAAA;AACvD,EAAA,IAAI,KAAA,GAAQ,YAAA,CAAa,IAAA,EAAM,IAAI,CAAA;AACnC,EAAA,IAAI,YAAA,GAAyC,IAAA;AAC7C,EAAA,IAAI,OAAA,GAAgC,IAAA;AACpC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,WAAA,CAAY,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,OAAA,GAAU,YAAY,CAAC,CAAA;AAG7B,IAAA,IAAI,OAAA,CAAQ,UAAA,CAAW,IAAA,EAAM,WAAA,KAAgB,IAAA,EAAM;AAC/C,MAAA,CAAC,OAAA,KAAY,EAAC,EAAG,IAAA,CAAK,OAAO,CAAA;AAC7B,MAAA;AAAA,IACJ;AACA,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,UAAA,CAAW,aAAA,KAAkB,IAAA;AAC1D,IAAA,IAAI,YAAA,IAAgB,qBAAA,CAAsB,KAAK,CAAA,EAAG;AAC9C,MAAA,IAAA,CAAK,GAAA,EAAI;AACT,MAAA,yBAAA,CAA0B,OAAO,MAAM,CAAA;AACvC,MAAA,IAAA,GAAO,aAAA,CAAc,IAAA,EAAM,IAAA,EAAM,WAAA,EAAa,IAAI,CAAA;AAClD,MAAA,YAAA,CAAa,MAAM,IAAI,CAAA;AACvB,MAAA,YAAA,GAAe,IAAA;AAAA,IACnB;AACA,IAAA,MAAM,IAAA,GAAO,QAAQ,UAAA,CAAW,IAAA;AAChC,IAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,OAAA,KAAY,KAAA,EAAO;AAChC,MAAA;AAAA,IACJ;AACA,IAAA,IAAI,OAAA,CAAQ,aAAa,YAAA,EAAc;AACnC,MAAA,IAAA,CAAK,WAAA,CAAY,QAAQ,QAAQ,CAAA;AACjC,MAAA,YAAA,GAAe,OAAA,CAAQ,QAAA;AAAA,IAC3B;AACA,IAAA,KAAA,IAAS,OAAA,CAAQ,IAAA,CAAK,IAAA,EAAM,MAAM,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,KAAA,IAAS,QAAA,CAAS,IAAA,EAAM,OAAA,EAAS,MAAM,CAAA;AAAA,EAC3C;AACA,EAAA,IAAA,CAAK,GAAA,EAAI;AACT,EAAA,OAAO,KAAA;AACX;AAEA,SAAS,yBAAA,CAA0B,OAAoC,MAAA,EAA6B;AAChG,EAAA,IAAI,CAAC,MAAM,cAAA,EAAgB;AACvB,IAAA,MAAM,IAAI,MAAM,wBAAwB,CAAA;AAAA,EAC5C;AACA,EAAA,IAAI,MAAM,KAAA,EAAO;AACb,IAAA,kBAAA,CAAmB,OAAO,MAAM,CAAA;AAAA,EACpC,CAAA,MAAO;AACH,IAAA,MAAA,CAAO,eAAA,CAAgB,oBAAA;AAAA,MACnB,EAAE,OAAA,EAAS,KAAA,CAAM,cAAA,EAAe;AAAA,MAChC,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,OAAA,EAAQ;AAAA,MACjC,EAAE,OAAO,KAAA,CAAM,OAAA,CAAQ,OAAO,MAAA,EAAQ,KAAA,CAAM,QAAQ,MAAA;AAAO,KAC/D;AAAA,EACJ;AACA,EAAA,IAAI,MAAM,gBAAA,EAAkB;AACxB,IAAA,aAAA,CAAc,MAAA,EAAQ,KAAA,CAAM,OAAA,CAAQ,OAAA,EAAS,OAAO,eAAe,CAAA;AAAA,EACvE;AACA,EAAA,KAAA,CAAM,OAAA,EAAA;AACV;AAEA,SAAS,eAAA,CAAgB,MAAA,EAAuB,MAAA,EAA0B,YAAA,EAA0C;AAChH,EAAA,MAAM,SAAS,MAAA,CAAO,OAAA;AACtB,EAAA,IAAI,WAAW,UAAA,EAAY;AACvB,IAAA,aAAA,EAAe,KAAA,EAAM;AACrB,IAAA,aAAA,GAAgB,IAAA;AAChB,IAAA,UAAA,GAAa,IAAA;AACb,IAAA,cAAA,GAAiB,IAAA;AACjB,IAAA,OAAA,GAAU,IAAA;AACV,IAAA,WAAA,GAAc,IAAA;AACd,IAAA,UAAA,GAAa,MAAA;AAAA,EACjB;AACA,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,cAAA,KAAmB,MAAA,CAAO,kBAAA,CAAmB,EAAE,IAAA,EAAM,kBAAkB,CAAA;AACvE,IAAA,WAAA,KAAgB,OAAO,qBAAA,CAAsB;AAAA,MACzC,OAAA,EAAS,CAAC,EAAE,OAAA,EAAS,GAAG,UAAA,EAAY,EAAA,CAAG,QAAA,EAAU,OAAA,EAAS,EAAE,UAAA,EAAY,oBAAA,EAAsB,YAAA,EAAc,IAAA,IAAQ;AAAA,KACvH,CAAA;AAAA,EACL,CAAA,MAAO;AACH,IAAA,UAAA,KAAe,MAAA,CAAO,kBAAA,CAAmB,EAAE,IAAA,EAAM,aAAa,CAAA;AAC9D,IAAA,OAAA,KAAY,OAAO,qBAAA,CAAsB;AAAA,MACrC,OAAA,EAAS;AAAA,QACL,EAAE,OAAA,EAAS,CAAA,EAAG,UAAA,EAAY,EAAA,CAAG,UAAU,OAAA,EAAS,EAAE,UAAA,EAAY,OAAA,EAAQ,EAAE;AAAA,QACxE,EAAE,SAAS,CAAA,EAAG,UAAA,EAAY,GAAG,QAAA,EAAU,OAAA,EAAS,EAAC;AAAE;AACvD,KACH,CAAA;AAAA,EACL;AACA,EAAA,aAAA,yBAAsB,GAAA,EAAI;AAC1B,EAAA,MAAM,MAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,YAAA,GAAe,SAAS,EAAE,CAAA,CAAA;AACnD,EAAA,IAAI,QAAA,GAAW,aAAA,CAAc,GAAA,CAAI,GAAG,CAAA;AACpC,EAAA,IAAI,CAAC,QAAA,EAAU;AACX,IAAA,MAAM,GAAA,GAAM,eAAe,WAAA,GAAe,OAAA;AAC1C,IAAA,QAAA,GAAW,OAAO,oBAAA,CAAqB;AAAA,MACnC,KAAA,EAAO,mBAAA;AAAA,MACP,MAAA,EAAQ,OAAO,oBAAA,CAAqB,EAAE,kBAAkB,CAAC,GAAG,GAAG,CAAA;AAAA,MAC/D,QAAQ,EAAE,MAAA,EAAQ,eAAe,cAAA,GAAkB,UAAA,EAAa,YAAY,IAAA,EAAK;AAAA,MACjF,QAAA,EAAU,EAAE,MAAA,EAAQ,YAAA,GAAe,cAAA,GAAkB,UAAA,EAAa,UAAA,EAAY,IAAA,EAAM,OAAA,EAAS,CAAC,EAAE,MAAA,EAAQ,CAAA,EAAE;AAAA,MAC1G,SAAA,EAAW,EAAE,QAAA,EAAU,eAAA;AAAgB,KAC1C,CAAA;AACD,IAAA,aAAA,CAAc,GAAA,CAAI,KAAK,QAAQ,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,QAAA;AACX;AAEA,SAAS,sBAAA,CAAuB,OAAoC,WAAA,EAA8B;AAC9F,EAAA,OAAO,WAAA,GAAc,CAAA,IAAK,KAAA,CAAM,YAAA,KAAiB,KAAA,CAAM,QAAQ,KAAA,IAAS,KAAA,CAAM,aAAA,KAAkB,KAAA,CAAM,OAAA,CAAQ,MAAA;AAClH;AAEA,SAAS,sBAAA,CAAuB,KAAA,EAAoC,MAAA,EAAuB,MAAA,EAAoB,YAAA,EAA8C;AACzJ,EAAA,MAAM,SAAS,MAAA,CAAO,OAAA;AACtB,EAAA,MAAM,WAAW,eAAA,CAAgB,MAAA,EAAQ,MAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,YAAY,CAAA;AACnF,EAAA,MAAM,SAAA,GAAY,OAAO,eAAA,CAAgB;AAAA,IACrC,MAAA,EAAQ,eAAe,WAAA,GAAe,OAAA;AAAA,IACtC,OAAA,EAAS,YAAA,GACH,CAAC,EAAE,OAAA,EAAS,CAAA,EAAG,QAAA,EAAU,MAAA,CAAO,UAAA,EAAW,EAAG,CAAA,GAC9C;AAAA,MACI,EAAE,OAAA,EAAS,CAAA,EAAG,QAAA,EAAU,MAAA,CAAO,YAAW,EAAE;AAAA,MAC5C,EAAE,OAAA,EAAS,CAAA,EAAG,QAAA,EAAU,kBAAA,CAAmB,MAAM,CAAA;AAAE;AACvD,GACT,CAAA;AACD,EAAA,OAAO,EAAE,SAAA,EAAW,QAAA,EAAU,UAAA,EAAY,SAAA,EAAU;AACxD;AAEA,SAAS,kBAAA,CAAmB,OAAoC,MAAA,EAA6B;AACzF,EAAA,MAAM,OAAO,KAAA,CAAM,KAAA;AACnB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,eAAA,CAAgB,eAAA,CAAgB;AAAA,IAChD,gBAAA,EAAkB,CAAC,EAAE,IAAA,EAAM,MAAM,SAAA,EAAW,MAAA,EAAQ,SAAS,OAAA,EAAS,OAAA,EAAS,YAAY,EAAE,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE,EAAG;AAAA,GAC1H,CAAA;AACD,EAAA,IAAA,CAAK,WAAA,CAAY,KAAK,SAAS,CAAA;AAC/B,EAAA,IAAA,CAAK,YAAA,CAAa,CAAA,EAAG,IAAA,CAAK,UAAU,CAAA;AACpC,EAAA,IAAA,CAAK,KAAK,CAAC,CAAA;AACX,EAAA,IAAA,CAAK,GAAA,EAAI;AACb;AAEA,SAAS,sBAAsB,KAAA,EAA6C;AACxE,EAAA,OAAO,KAAA,CAAM,UAAA,KAAe,CAAA,IAAK,KAAA,CAAM,UAAU,KAAA,CAAM,UAAA;AAC3D;AAEA,SAAS,aAAA,CAAc,IAAA,EAAkB,aAAA,EAAsC,WAAA,EAAqB,IAAA,EAAqC;AACrI,EAAA,MAAM,MAAM,IAAA,CAAK,gBAAA;AACjB,EAAA,MAAM,cAAc,IAAA,IAAQ,CAAC,IAAA,CAAK,OAAA,CAAQ,MAAM,MAAA,GAAS,OAAA;AACzD,EAAA,IAAI,IAAA,EAAM;AACN,IAAA,GAAA,CAAI,MAAA,GAAS,MAAA;AAAA,EACjB;AACA,EAAA,MAAM,eAAA,GAAkB,KAAK,qBAAA,CAAsB,sBAAA;AACnD,EAAA,IAAI,eAAA,EAAiB;AACjB,IAAA,eAAA,CAAgB,WAAA,GAAc,WAAA;AAC9B,IAAA,IAAI,gBAAgB,aAAA,EAAe;AAC/B,MAAA,eAAA,CAAgB,aAAA,GAAgB,WAAA;AAAA,IACpC;AAAA,EACJ;AACA,EAAA,IAAI,cAAc,CAAA,EAAG;AACjB,IAAA,GAAA,CAAI,gBAAiC,MAAA;AAAA,EACzC,CAAA,MAAO;AACH,IAAA,GAAA,CAAI,aAAA,GAAgB,MAAA;AAAA,EACxB;AACA,EAAA,OAAO,IAAA,CAAK,MAAA,CAAO,eAAA,CAAgB,eAAA,CAAgB,KAAK,qBAAqB,CAAA;AACjF;AAEA,SAAS,YAAA,CAAa,MAAkB,IAAA,EAAkC;AACtE,EAAA,MAAM,MAAM,IAAA,CAAK,OAAA;AACjB,EAAA,MAAM,KAAK,GAAA,CAAI,EAAA;AACf,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,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;AACA,EAAA,IAAA,CAAK,YAAA,CAAa,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA;AACtC;AAEA,SAAS,YAAA,CAAa,MAAkB,IAAA,EAAoC;AACxE,EAAA,MAAM,MAAM,IAAA,CAAK,MAAA;AACjB,EAAA,MAAM,EAAA,GAAK,KAAK,OAAA,CAAQ,EAAA;AACxB,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,EAAA,MAAM,iBAAiB,IAAA,CAAK,eAAA;AAC5B,EAAA,MAAM,gBAAgB,IAAA,CAAK,cAAA;AAE3B,EAAA,YAAA,CAAa,MAAM,IAAI,CAAA;AAEvB,EAAA,IAAI,IAAA,CAAK,iBAAiB,KAAA,CAAM,kBAAA,IAAsB,KAAK,QAAA,KAAa,IAAA,IAAQ,aAAA,CAAc,MAAA,KAAW,CAAA,EAAG;AACxG,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,MAC7C,oBAAoB,IAAA,CAAK,OAAA;AAAA,MACzB,WAAA,EAAa,KAAK,OAAA,IAAW;AAAA,KAChC,CAAA;AACD,IAAA,EAAA,CAAG,YAAA,CAAa,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA;AAChC,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;AACjC,EAAA,IAAA,CAAK,YAAA,CAAa,CAAA,EAAG,IAAA,CAAK,QAAQ,CAAA;AAClC,EAAA,KAAA,IAAS,QAAA,CAAS,IAAA,EAAM,IAAA,CAAK,eAAA,EAAiB,GAAG,CAAA;AACjD,EAAA,OAAO,KAAA;AACX;AAEA,SAAS,QAAA,CAAS,GAAA,EAAoD,IAAA,EAA8B,MAAA,EAA+B;AAC/H,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;AAEA,SAAS,mBAAmB,GAAA,EAAoD;AAC5E,EAAA,MAAM,KAAA,GAAQ,KAAK,SAAA,IAAa,CAAA;AAChC,EAAA,OAAO,UAAU,QAAA,GAAW,CAAA,GAAI,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AACzD;AAEA,SAAS,wBAAA,CAAyB,MAAkB,OAAA,EAAgD;AAChG,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA;AAAA,EACJ;AACA,EAAA,IAAI,IAAA,GAAO,KAAK,OAAA,CAAQ,YAAA;AACxB,EAAA,IAAI,OAAA,GAAU,KAAA;AACd,EAAA,MAAM,GAAA,GAAM,CAAqE,GAAA,EAAQ,KAAA,KAAmF;AACxK,IAAA,IAAI,UAAU,MAAA,EAAW;AACrB,MAAA;AAAA,IACJ;AACA,IAAA,IAAA,GAAO,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,GAAG,KAAA,EAAM;AAC/B,IAAA,OAAA,GAAU,IAAA;AAAA,EACd,CAAA;AACA,EAAA,GAAA,CAAI,WAAA,EAAa,QAAQ,SAAS,CAAA;AAClC,EAAA,GAAA,CAAI,iBAAA,EAAmB,QAAQ,eAAe,CAAA;AAC9C,EAAA,GAAA,CAAI,eAAA,EAAiB,QAAQ,aAAa,CAAA;AAC1C,EAAA,IAAI,OAAA,EAAS;AACT,IAAA,IAAA,CAAK,QAAQ,YAAA,GAAe,IAAA;AAAA,EAChC;AACJ;AAEA,SAAS,yBAAA,CAA0B,GAAA,EAA4C,KAAA,EAAe,MAAA,EAAwB;AAClH,EAAA,IAAI,GAAA,EAAK,oBAAoB,KAAA,EAAO;AAChC,IAAA,OAAO,CAAA;AAAA,EACX;AACA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,KAAA,EAAO,MAAM,CAAC,CAAC,CAAA,GAAI,CAAA;AAC9D,EAAA,MAAM,YAAA,GAAe,mBAAA,CAAoB,KAAA,EAAO,MAAA,EAAQ,mBAAmB,CAAA;AAC3E,EAAA,MAAM,YAAY,GAAA,EAAK,aAAA;AACvB,EAAA,IAAI,cAAc,MAAA,EAAW;AACzB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,YAAY,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,IAAA,CAAK,IAAI,IAAA,EAAM,IAAA,CAAK,IAAI,CAAA,EAAG,SAAA,GAAY,CAAC,CAAC,CAAA;AACpD;;;;"}
|
|
1
|
+
{"version":3,"file":"transmission.js","sources":["../../../src/frame-graph/transmission.ts"],"sourcesContent":["import { TU, SS } from \"../engine/gpu-flags.js\";\nimport type { EngineContext } from \"../engine/engine.js\";\nimport { _vis } from \"../engine/engine.js\";\nimport { createRenderTarget } from \"../engine/render-target.js\";\nimport { getBilinearSampler } from \"../resource/samplers.js\";\nimport { getTrilinearAnisotropicSampler } from \"../resource/trilinear-anisotropic-sampler.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport { recordMipmaps } from \"../texture/generate-mipmaps.js\";\nimport { biasedMipLevelCount } from \"../texture/mip-count.js\";\nimport type { DrawBinding } from \"../render/renderable.js\";\nimport type { RenderTask } from \"./render-task.js\";\nimport type { SceneContext } from \"../scene/scene-core.js\";\nimport { createImageProcessingTask } from \"./image-processing-task.js\";\n\nexport interface RenderTaskTransmissionState {\n readonly texture: Texture2D;\n /** @internal */\n readonly _baseView: GPUTextureView;\n /** @internal */\n _sourceWidth: number;\n /** @internal */\n _sourceHeight: number;\n /** @internal */\n _sourceTexture: GPUTexture | null;\n /** @internal */\n _blit: TransmissionBlitState | null;\n /** @internal */\n readonly _copyCount: number;\n /** @internal */\n readonly _generateMipmaps: boolean;\n /** @internal */\n _copies: number;\n}\n\ninterface TransmissionBlitState {\n readonly _pipeline: GPURenderPipeline;\n readonly _bindGroup: GPUBindGroup;\n}\n\nconst BLIT_SHADER = `@group(0)@binding(0)var t:texture_2d<f32>;@group(0)@binding(1)var s:sampler;struct V{@builtin(position)p:vec4f,@location(0)u:vec2f};@vertex fn vs(@builtin(vertex_index)i:u32)->V{var p=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));var u=array<vec2f,3>(vec2f(0,1),vec2f(2,1),vec2f(0,-1));return V(vec4f(p[i],0,1),u[i]);}@fragment fn fs(v:V)->@location(0)vec4f{return textureSample(t,s,v.u);}`;\nconst BLIT_MSAA_SHADER = `@group(0)@binding(0)var t:texture_multisampled_2d<f32>;struct V{@builtin(position)p:vec4f,@location(0)u:vec2f};@vertex fn vs(@builtin(vertex_index)i:u32)->V{var p=array<vec2f,3>(vec2f(-1,-1),vec2f(3,-1),vec2f(-1,3));var u=array<vec2f,3>(vec2f(0,1),vec2f(2,1),vec2f(0,-1));return V(vec4f(p[i],0,1),u[i]);}fn l(p:vec2i)->vec4f{let n=textureNumSamples(t);var c=vec4f(0);for(var i=0u;i<n;i++){c+=textureLoad(t,p,i);}return c/f32(n);}@fragment fn fs(v:V)->@location(0)vec4f{let d=vec2i(textureDimensions(t));let q=clamp(v.u*vec2f(d)-.5,vec2f(0),vec2f(d-vec2i(1)));let p=vec2i(floor(q));let f=fract(q);let p1=min(p+vec2i(1),d-vec2i(1));return mix(mix(l(p),l(vec2i(p1.x,p.y)),f.x),mix(l(vec2i(p.x,p1.y)),l(p1),f.x),f.y);}`;\nconst REFRACTION_LOD_BIAS = 4;\nlet blitPipelines: Map<string, GPURenderPipeline> | null = null;\nlet blitShader: GPUShaderModule | null = null;\nlet blitMsaaShader: GPUShaderModule | null = null;\nlet blitBgl: GPUBindGroupLayout | null = null;\nlet blitMsaaBgl: GPUBindGroupLayout | null = null;\nlet blitDevice: GPUDevice | null = null;\n\n/** Enable scene-color transmission for every render task currently registered in a scene. PBR materials are marked for linear transmission, and a trailing image-processing task is appended when needed. */\nexport function enableSceneTransmission(scene: SceneContext, engine: EngineContext): void {\n markPbrMaterialsLinear(scene);\n let lastRenderTask: RenderTask | null = null;\n for (const task of scene._frameGraph._tasks) {\n if (\"_renderables\" in task) {\n const renderTask = task as RenderTask;\n enableRenderTaskTransmission(renderTask, engine);\n lastRenderTask = renderTask;\n }\n }\n if (lastRenderTask && !scene._frameGraph._tasks.some((task) => task.name === \"transmission-image-processing\")) {\n scene._frameGraph._tasks.push(createImageProcessingTask({ name: \"transmission-image-processing\", source: lastRenderTask._config.rt }, engine, scene));\n }\n}\n\n/** Options controlling how a render task exposes opaque scene color to transmissive materials. Use these to opt out of the linear offscreen path, control refresh frequency, and limit mipmap generation cost. */\nexport interface TransmissionOptions {\n /** When true (the default), retarget the task's color buffer to a linear `rgba16float`\n * offscreen and tone-map it in a trailing image-processing pass — the model PBR\n * transmission uses so refractive materials read scene color in *linear* space.\n *\n * Set false to perform ONLY the mid-pass scene-color grab: the task's render target\n * format / sample count / clear are left untouched and no tone-map pass is added. Use\n * this for consumers that own their tone mapping / post (e.g. a custom depth-of-field\n * stack) and just need the opaque scene color exposed to a custom transmissive\n * `ShaderMaterial`. */\n linear?: boolean;\n /** Override how many times the scene-colour grab is refreshed per frame. `0` means before every\n * transmissive draw; the default is once before the first transmissive draw. */\n copyCount?: number;\n /** Set false when the transmissive material never samples the scene-colour grab above mip 0. */\n generateMipmaps?: boolean;\n /** Cap the scene-colour grab mip chain. Use this when the material samples explicit low LODs only, so\n * unused tiny mips are not regenerated every frame. Ignored when `generateMipmaps` is false. */\n mipLevelCount?: number;\n}\n\n/** Handle to a render task's scene-color grab, returned by `enableRenderTaskTransmission`. */\nexport interface SceneColorGrab {\n /** The live opaque-scene-color texture sampled by transmissive surfaces, or null before the\n * frame graph has built the task at least once. Its identity changes when the task rebuilds\n * (e.g. on resize), so consumers that bind it to a custom material should re-bind when it\n * changes. */\n readonly texture: Texture2D | null;\n}\n\n/** Enable mid-pass scene-color grabs for a single render task and return the live texture handle. The task is wrapped so transmissive draw calls can sample the opaque color rendered earlier in the same pass. */\nexport function enableRenderTaskTransmission(task: RenderTask, engine: EngineContext, options?: TransmissionOptions): SceneColorGrab {\n const linear = options?.linear !== false;\n applyTransmissionOptions(task, options);\n const grab: SceneColorGrab = {\n get texture(): Texture2D | null {\n return (task._targetSignature as { _transmissionTexture?: Texture2D })._transmissionTexture ?? null;\n },\n };\n if (task._executeWithTransmission) {\n return grab;\n }\n if (linear) {\n retargetRenderTaskToLinearOffscreen(task);\n }\n let state: RenderTaskTransmissionState | null = null;\n const record = task.record.bind(task);\n const execute = task.execute?.bind(task);\n const dispose = task.dispose?.bind(task);\n task.record = () => {\n disposeRenderTaskTransmission(state);\n state = createRenderTaskTransmission(task, engine);\n (task._targetSignature as { _transmissionTexture?: Texture2D })._transmissionTexture = state.texture;\n record();\n configureTransmissionSource(state, task, engine);\n };\n if (linear && execute) {\n task.execute = () => executeRenderTaskLinear(task.scene, execute);\n }\n task.dispose = () => {\n disposeRenderTaskTransmission(state);\n state = null;\n dispose?.();\n };\n task._executeWithTransmission = (sampleCount) => executePassWithTransmission(task, engine, state!, sampleCount);\n return grab;\n}\n\nfunction retargetRenderTaskToLinearOffscreen(task: RenderTask): void {\n const cfg = task._config;\n const oldDesc = cfg.rt._descriptor;\n const surface = task.scene.surface;\n const sampleCount = surface.msaaSamples;\n // The scene render task may target the shared engine scRT (single-sample,\n // colour-only — single-sample default path) or an MSAA colour RT that resolves into it\n // via `rst` (MSAA default path). Never mutate the shared scRT descriptor —\n // instead point the task at a fresh offscreen HDR target and stop resolving to swap.\n // Transmission samples this linear HDR result in its own final image-processing pass\n // that writes the tonemapped result to the swapchain.\n //\n // Depth ownership: when the task already carries an external depth (`cfg.depth`, the\n // single-sample default path), keep it; otherwise the new target owns depth (matching\n // the MSAA colour RT it replaces).\n const ownsDepth = !cfg.depth;\n const newRt = createRenderTarget({\n lbl: \"transmission-linear\",\n format: \"rgba16float\",\n dFormat: ownsDepth ? (oldDesc.dFormat ?? \"depth24plus-stencil8\") : undefined,\n _depthClearValue: oldDesc._depthClearValue,\n _depthCompare: oldDesc._depthCompare,\n samples: sampleCount,\n size: surface,\n });\n cfg.rt = newRt;\n cfg.rst = undefined;\n const sig = task._targetSignature as {\n _colorFormat?: GPUTextureFormat;\n _depthStencilFormat?: GPUTextureFormat;\n _depthCompare?: GPUCompareFunction;\n _sampleCount: number;\n };\n sig._colorFormat = \"rgba16float\";\n sig._depthStencilFormat = cfg.depth?._descriptor.dFormat ?? newRt._descriptor.dFormat;\n sig._depthCompare = newRt._descriptor._depthCompare;\n sig._sampleCount = sampleCount;\n task._opaqueBundles.length = 0;\n task._lastVersion = -1;\n}\n\nfunction executeRenderTaskLinear(scene: SceneContext, execute: () => number): number {\n const imageProcessing = scene.imageProcessing as { exposure: number; contrast: number; toneMappingEnabled: boolean | number };\n const toneMappingEnabled = imageProcessing.toneMappingEnabled;\n const clearColor = scene.clearColor;\n const linearClearColor = inverseImageProcessedColor(clearColor, imageProcessing.exposure, imageProcessing.contrast, toneMappingEnabled === true);\n imageProcessing.toneMappingEnabled = -1;\n scene.clearColor = linearClearColor;\n try {\n return execute();\n } finally {\n scene.clearColor = clearColor;\n imageProcessing.toneMappingEnabled = toneMappingEnabled;\n }\n}\n\nfunction inverseImageProcessedColor(color: GPUColorDict, exposure: number, contrast: number, toneMapping: boolean): GPUColorDict {\n return {\n r: inverseImageProcessedChannel(color.r, exposure, contrast, toneMapping),\n g: inverseImageProcessedChannel(color.g, exposure, contrast, toneMapping),\n b: inverseImageProcessedChannel(color.b, exposure, contrast, toneMapping),\n a: color.a,\n };\n}\n\nfunction inverseImageProcessedChannel(value: number, exposure: number, contrast: number, toneMapping: boolean): number {\n let c = clamp01(value);\n if (contrast < 1) {\n c = contrast > 0 ? clamp01((c - 0.5 * (1 - contrast)) / contrast) : 0.5;\n } else if (contrast > 1) {\n const mixAmount = contrast - 1;\n let lo = 0;\n let hi = 1;\n for (let i = 0; i < 16; i++) {\n const mid = (lo + hi) * 0.5;\n const high = mid * mid * (3 - 2 * mid);\n const out = mid + (high - mid) * mixAmount;\n if (out < c) {\n lo = mid;\n } else {\n hi = mid;\n }\n }\n c = (lo + hi) * 0.5;\n }\n c = c ** 2.2;\n if (toneMapping) {\n c = -Math.log2(Math.max(1 - c, 1e-6)) / 1.5905790328979492;\n }\n return exposure > 0 ? c / exposure : c;\n}\n\nfunction clamp01(v: number): number {\n return Math.min(Math.max(v, 0), 1);\n}\n\nfunction markPbrMaterialsLinear(scene: SceneContext): void {\n for (const mesh of scene.meshes) {\n const mat = mesh.material as { _linearImageProcessing?: boolean; _renderFeatures?: unknown } | undefined;\n if (mat) {\n mat._linearImageProcessing = true;\n mat._renderFeatures = undefined;\n }\n }\n}\n\nfunction createRenderTaskTransmission(task: RenderTask, engine: EngineContext): RenderTaskTransmissionState {\n const rt = task._config.rt;\n const width = 1024;\n const height = 1024;\n const format: GPUTextureFormat = \"rgba16float\";\n const mipLevelCount = transmissionMipLevelCount(task._config.transmission, width, height);\n const generateMipmaps = mipLevelCount > 1;\n const texture = engine._device.createTexture({\n label: task.name,\n size: { width, height },\n format,\n mipLevelCount,\n usage: TU.RENDER_ATTACHMENT | TU.TEXTURE_BINDING | TU.COPY_DST,\n });\n const tex: Texture2D = {\n texture,\n view: texture.createView(),\n sampler: getTrilinearAnisotropicSampler(engine),\n width,\n height,\n invertY: false,\n };\n return {\n texture: tex,\n _baseView: texture.createView({ baseMipLevel: 0, mipLevelCount: 1 }),\n _sourceWidth: rt._width,\n _sourceHeight: rt._height,\n _sourceTexture: null,\n _blit: null,\n _copyCount: normalizeCopyCount(task._config.transmission),\n _generateMipmaps: generateMipmaps,\n _copies: 0,\n };\n}\n\nfunction configureTransmissionSource(state: RenderTaskTransmissionState, task: RenderTask, engine: EngineContext): void {\n const rt = task._config.rt;\n state._sourceWidth = rt._width;\n state._sourceHeight = rt._height;\n state._sourceTexture = rt._colorTexture;\n const sampleCount = task._targetSignature._sampleCount;\n if (!state._sourceTexture) {\n return;\n }\n state._blit = shouldBlitTransmission(state, sampleCount) ? createTransmissionBlit(state, engine, state._sourceTexture, sampleCount > 1) : null;\n}\n\nfunction disposeRenderTaskTransmission(state: RenderTaskTransmissionState | null | undefined): void {\n state?.texture.texture.destroy();\n}\n\nexport function executePassWithTransmission(task: RenderTask, engine: EngineContext, state: RenderTaskTransmissionState, sampleCount: number): number {\n state._copies = 0;\n const transparent = task._transparentBindings;\n // MSAA: resolve the FINAL scene colour into the task's single-sample resolve target (`rst`) so downstream\n // passes that SAMPLE the scene RTT (e.g. a custom DoF/present stack) get a resolved image. The multisampled\n // colour is preserved across the split segments (store/load), so resolving on every segment leaves the LAST\n // (complete) resolve in `rst`. No-op when single-sample (resolveView stays null) — existing scenes unchanged.\n const resolveView = sampleCount > 1 ? (task._config.rst?._colorView ?? null) : null;\n let pass = beginTaskPass(task, resolveView, sampleCount, false);\n let draws = drawBaseTask(task, pass);\n let lastPipeline: GPURenderPipeline | null = null;\n let overlay: DrawBinding[] | null = null;\n for (let i = 0; i < transparent.length; i++) {\n const binding = transparent[i]!;\n // `Mesh.renderOnTop` surfaces draw last — after the scene-colour grab — so they sit on top of the\n // transmissive surface and are excluded from what it refracts (e.g. lily pads on water).\n if (binding.renderable.mesh?.renderOnTop === true) {\n (overlay ??= []).push(binding);\n continue;\n }\n const transmissive = binding.renderable._transmissive === true;\n if (transmissive && canUpdateTransmission(state)) {\n pass.end();\n updateTransmissionTexture(state, engine);\n pass = beginTaskPass(task, resolveView, sampleCount, true);\n setPassState(task, pass);\n lastPipeline = null;\n }\n const mesh = binding.renderable.mesh;\n if (mesh && mesh.visible === false) {\n continue;\n }\n if (binding.pipeline !== lastPipeline) {\n pass.setPipeline(binding.pipeline);\n lastPipeline = binding.pipeline;\n }\n draws += binding.draw(pass, engine);\n }\n if (overlay) {\n draws += drawList(pass, overlay, engine);\n }\n pass.end();\n return draws;\n}\n\nfunction updateTransmissionTexture(state: RenderTaskTransmissionState, engine: EngineContext): void {\n if (!state._sourceTexture) {\n throw new Error(\"No transmission source\");\n }\n if (state._blit) {\n blitToTransmission(state, engine);\n } else {\n engine._currentEncoder.copyTextureToTexture(\n { texture: state._sourceTexture },\n { texture: state.texture.texture },\n { width: state.texture.width, height: state.texture.height }\n );\n }\n if (state._generateMipmaps) {\n recordMipmaps(engine, state.texture.texture, engine._currentEncoder);\n }\n state._copies++;\n}\n\nfunction getBlitPipeline(engine: EngineContext, format: GPUTextureFormat, multisampled: boolean): GPURenderPipeline {\n const device = engine._device;\n if (device !== blitDevice) {\n blitPipelines?.clear();\n blitPipelines = null;\n blitShader = null;\n blitMsaaShader = null;\n blitBgl = null;\n blitMsaaBgl = null;\n blitDevice = device;\n }\n if (multisampled) {\n blitMsaaShader ??= device.createShaderModule({ code: BLIT_MSAA_SHADER });\n blitMsaaBgl ??= device.createBindGroupLayout({\n entries: [{ binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: \"unfilterable-float\", multisampled: true } }],\n });\n } else {\n blitShader ??= device.createShaderModule({ code: BLIT_SHADER });\n blitBgl ??= device.createBindGroupLayout({\n entries: [\n { binding: 0, visibility: SS.FRAGMENT, texture: { sampleType: \"float\" } },\n { binding: 1, visibility: SS.FRAGMENT, sampler: {} },\n ],\n });\n }\n blitPipelines ??= new Map();\n const key = `${format}:${multisampled ? \"msaa\" : \"\"}`;\n let pipeline = blitPipelines.get(key);\n if (!pipeline) {\n const bgl = multisampled ? blitMsaaBgl! : blitBgl!;\n pipeline = device.createRenderPipeline({\n label: \"transmission-copy\",\n layout: device.createPipelineLayout({ bindGroupLayouts: [bgl] }),\n vertex: { module: multisampled ? blitMsaaShader! : blitShader!, entryPoint: \"vs\" },\n fragment: { module: multisampled ? blitMsaaShader! : blitShader!, entryPoint: \"fs\", targets: [{ format }] },\n primitive: { topology: \"triangle-list\" },\n });\n blitPipelines.set(key, pipeline);\n }\n return pipeline;\n}\n\nfunction shouldBlitTransmission(state: RenderTaskTransmissionState, sampleCount: number): boolean {\n return sampleCount > 1 || state._sourceWidth !== state.texture.width || state._sourceHeight !== state.texture.height;\n}\n\nfunction createTransmissionBlit(state: RenderTaskTransmissionState, engine: EngineContext, source: GPUTexture, multisampled: boolean): TransmissionBlitState {\n const device = engine._device;\n const pipeline = getBlitPipeline(engine, state.texture.texture.format, multisampled);\n const bindGroup = device.createBindGroup({\n layout: multisampled ? blitMsaaBgl! : blitBgl!,\n entries: multisampled\n ? [{ binding: 0, resource: source.createView() }]\n : [\n { binding: 0, resource: source.createView() },\n { binding: 1, resource: getBilinearSampler(engine) },\n ],\n });\n return { _pipeline: pipeline, _bindGroup: bindGroup };\n}\n\nfunction blitToTransmission(state: RenderTaskTransmissionState, engine: EngineContext): void {\n const blit = state._blit!;\n const pass = engine._currentEncoder.beginRenderPass({\n colorAttachments: [{ view: state._baseView, loadOp: \"clear\", storeOp: \"store\", clearValue: { r: 0, g: 0, b: 0, a: 0 } }],\n });\n pass.setPipeline(blit._pipeline);\n pass.setBindGroup(0, blit._bindGroup);\n pass.draw(3);\n pass.end();\n}\n\nfunction canUpdateTransmission(state: RenderTaskTransmissionState): boolean {\n return state._copyCount === 0 || state._copies < state._copyCount;\n}\n\nfunction beginTaskPass(task: RenderTask, resolveTarget: GPUTextureView | null, sampleCount: number, load: boolean): GPURenderPassEncoder {\n const att = task._colorAttachment;\n const depthLoadOp = load || !task._config.clr ? \"load\" : \"clear\";\n if (load) {\n att.loadOp = \"load\";\n }\n const depthAttachment = task._renderPassDescriptor.depthStencilAttachment;\n if (depthAttachment) {\n depthAttachment.depthLoadOp = depthLoadOp;\n if (depthAttachment.stencilLoadOp) {\n depthAttachment.stencilLoadOp = depthLoadOp;\n }\n }\n if (sampleCount > 1) {\n att.resolveTarget = resolveTarget ?? undefined;\n } else {\n att.resolveTarget = undefined;\n }\n return task.engine._currentEncoder.beginRenderPass(task._renderPassDescriptor);\n}\n\nfunction setPassState(task: RenderTask, pass: GPURenderPassEncoder): void {\n const cfg = task._config;\n const rt = cfg.rt;\n const scene = task.scene;\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 pass.setBindGroup(0, task._sceneBG);\n}\n\nfunction drawBaseTask(task: RenderTask, pass: GPURenderPassEncoder): number {\n const eng = task.engine;\n const rt = task._config.rt;\n const scene = task.scene;\n const opaqueBindings = task._opaqueBindings;\n const opaqueBundles = task._opaqueBundles;\n\n setPassState(task, pass);\n\n if (task._lastVersion !== scene._renderableVersion || task._lastVis !== _vis || opaqueBundles.length === 0) {\n const desc = rt._descriptor;\n const be = eng._device.createRenderBundleEncoder({\n colorFormats: desc.format ? [desc.format] : [],\n depthStencilFormat: desc.dFormat,\n sampleCount: desc.samples ?? 1,\n });\n be.setBindGroup(0, task._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 pass.setBindGroup(0, task._sceneBG);\n draws += drawList(pass, task._directBindings, eng);\n return draws;\n}\n\nfunction 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\nfunction normalizeCopyCount(cfg: RenderTask[\"_config\"][\"transmission\"]): number {\n const count = cfg?.copyCount ?? 1;\n return count === Infinity ? 0 : Math.max(0, count | 0);\n}\n\nfunction applyTransmissionOptions(task: RenderTask, options: TransmissionOptions | undefined): void {\n if (!options) {\n return;\n }\n let next = task._config.transmission;\n let changed = false;\n const set = <K extends keyof NonNullable<RenderTask[\"_config\"][\"transmission\"]>>(key: K, value: NonNullable<RenderTask[\"_config\"][\"transmission\"]>[K] | undefined): void => {\n if (value === undefined) {\n return;\n }\n next = { ...next, [key]: value };\n changed = true;\n };\n set(\"copyCount\", options.copyCount);\n set(\"generateMipmaps\", options.generateMipmaps);\n set(\"mipLevelCount\", options.mipLevelCount);\n if (changed) {\n task._config.transmission = next;\n }\n}\n\nfunction transmissionMipLevelCount(cfg: RenderTask[\"_config\"][\"transmission\"], width: number, height: number): number {\n if (cfg?.generateMipmaps === false) {\n return 1;\n }\n const full = Math.floor(Math.log2(Math.max(width, height))) + 1;\n const defaultCount = biasedMipLevelCount(width, height, REFRACTION_LOD_BIAS);\n const requested = cfg?.mipLevelCount;\n if (requested === undefined) {\n return Math.min(full, defaultCount);\n }\n return Math.min(full, Math.max(1, requested | 0));\n}\n"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -14,6 +14,7 @@ export { addPassDependencies } from './frame-graph/pass.js';
|
|
|
14
14
|
export { createRenderTask, removeMeshFromTask } from './frame-graph/render-task.js';
|
|
15
15
|
export { createImageProcessingTask } from './frame-graph/image-processing-task.js';
|
|
16
16
|
export { createCopyToTextureTask } from './frame-graph/copy-to-texture-task.js';
|
|
17
|
+
export { createDepthResolveTask } from './frame-graph/depth-resolve-task.js';
|
|
17
18
|
export { createGeometryRendererTask } from './frame-graph/geometry-renderer-task.js';
|
|
18
19
|
export { GeometryTextureType } from './frame-graph/geometry-types.js';
|
|
19
20
|
export { createRenderTarget } from './engine/render-target.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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -10,7 +10,7 @@ function assertIdentifier(kind, name) {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
function isSupportedAttribute(name) {
|
|
13
|
-
return name === "position" || name === "normal" || name === "uv" || name === "uv2" || name === "tangent" || name === "color";
|
|
13
|
+
return name === "position" || name === "normal" || name === "uv" || name === "uv2" || name === "tangent" || name === "color" || name === "joints" || name === "weights" || name === "joints1" || name === "weights1";
|
|
14
14
|
}
|
|
15
15
|
function isSystemUniform(name) {
|
|
16
16
|
return name === "world" || name === "view" || name === "projection" || name === "viewProjection" || name === "worldView" || name === "worldViewProjection" || name === "cameraPosition" || name === "screenSize" || name === "alphaCutoff";
|
|
@@ -38,7 +38,9 @@ function createShaderMaterial(options) {
|
|
|
38
38
|
const seenAttributes = /* @__PURE__ */ new Set();
|
|
39
39
|
for (const attr of options.attributes) {
|
|
40
40
|
if (!isSupportedAttribute(attr)) {
|
|
41
|
-
throw new Error(
|
|
41
|
+
throw new Error(
|
|
42
|
+
`ShaderMaterial: unsupported attribute "${String(attr)}". Supported attributes: position, normal, uv, uv2, tangent, color, joints, weights, joints1, weights1.`
|
|
43
|
+
);
|
|
42
44
|
}
|
|
43
45
|
if (seenAttributes.has(attr)) {
|
|
44
46
|
throw new Error(`ShaderMaterial: duplicate attribute "${attr}".`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shader-material.js","sources":["../../../../src/material/shader/shader-material.ts"],"sourcesContent":["import { F32 } from \"../../engine/typed-arrays.js\";\nimport type { Material, StencilState } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport { getShaderGroupBuilder } from \"./shader-group-builder.js\";\n\n/** Vertex attribute names a ShaderMaterial can bind. */\nexport type ShaderAttributeName = \"position\" | \"normal\" | \"uv\" | \"uv2\" | \"tangent\" | \"color\";\n/** WGSL scalar/vector/matrix types supported for ShaderMaterial uniforms. */\nexport type ShaderUniformType = \"f32\" | \"u32\" | \"i32\" | \"vec2<f32>\" | \"vec3<f32>\" | \"vec4<f32>\" | \"mat4x4<f32>\";\n/** Built-in uniform names automatically populated by the renderer each frame\n * (transforms, camera position, screen size, alpha cutoff). */\nexport type ShaderSystemUniformName = \"world\" | \"view\" | \"projection\" | \"viewProjection\" | \"worldView\" | \"worldViewProjection\" | \"cameraPosition\" | \"screenSize\" | \"alphaCutoff\";\n/** A uniform entry: either a system uniform name or an explicit custom declaration. */\nexport type ShaderUniformOption = ShaderSystemUniformName | ShaderUniformDecl;\n/** Accepted value shape when setting a ShaderMaterial uniform. */\nexport type ShaderUniformValue = number | readonly number[] | Float32Array;\n/** A sampler entry: either a bare sampler name or an explicit declaration. */\nexport type ShaderSamplerOption = string | ShaderSamplerDecl;\n/** A storage-buffer entry: a read-only WGSL storage binding declaration. */\nexport type ShaderStorageBufferOption = ShaderStorageBufferDecl;\n/** Value of a WGSL preprocessor define — boolean toggle or numeric constant. */\nexport type ShaderDefineValue = boolean | number;\n/** Map of WGSL preprocessor define names to their values. */\nexport type ShaderDefineMap = Readonly<Record<string, ShaderDefineValue>>;\n\n/** Options describing a ShaderMaterial: WGSL sources, attributes, uniforms,\n * samplers, defines, and blend/depth state. Passed to `createShaderMaterial()`. */\nexport interface ShaderMaterialOptions {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniforms?: readonly ShaderUniformOption[];\n readonly samplers?: readonly ShaderSamplerOption[];\n readonly storageBuffers?: readonly ShaderStorageBufferOption[];\n readonly defines?: ShaderDefineMap;\n readonly needAlphaBlending?: boolean;\n /** Blend equation used when `needAlphaBlending` is set. \"alpha\" (default) is\n * standard src-over; \"additive\" adds the fragment's premultiplied-by-alpha\n * color to the framebuffer, which is the right choice for glows/light FX. */\n readonly blendMode?: \"alpha\" | \"additive\";\n /** Mark this surface as transmissive/refractive: the renderer grabs the opaque scene color\n * behind it just before it draws, so the fragment can sample what is *through* it (water,\n * glass). Requires `needAlphaBlending` (the surface composites over the grabbed scene\n * color). Enable the scene-color grab on the surface's render task with\n * `enableRenderTaskTransmission`, then bind the resulting texture via `setShaderTexture`.\n * Default false. */\n readonly transmissive?: boolean;\n readonly needAlphaTesting?: boolean;\n readonly backFaceCulling?: boolean;\n readonly depthWrite?: boolean;\n readonly depthCompare?: GPUCompareFunction;\n /** Compile/run the fragment stage even for depth-only render targets (no colour attachments).\n * Use for depth-only casters that need `discard` (alpha/clip masks). The fragment shader must not\n * declare colour outputs when drawn into a depth-only target. Default false. */\n readonly depthOnlyFragment?: boolean;\n /** Constant depth-bias added in the pipeline's depth-stencil state (units of the depth format's minimum\n * representable value). Lets a surface that hugs another (e.g. tiles overlapping a cone, decals) win the\n * depth test consistently and avoid z-fighting. Default 0 (no bias). */\n readonly depthBias?: number;\n /** Slope-scaled depth bias — extra bias proportional to the depth gradient, so steeply-angled (grazing)\n * surfaces get more bias. Pairs with `depthBias` to kill z-fighting at oblique angles. Default 0. */\n readonly depthBiasSlopeScale?: number;\n}\n\n/** A custom uniform declaration: WGSL identifier, type, and optional default. */\nexport interface ShaderUniformDecl {\n readonly name: string;\n readonly type: ShaderUniformType;\n readonly defaultValue?: number | readonly number[];\n}\n\n/** A sampler declaration: WGSL identifier and the bound texture's sample type. */\nexport interface ShaderSamplerDecl {\n readonly name: string;\n readonly sampleType?: \"float\" | \"unfilterable-float\" | \"depth\";\n /** Texture view dimension. Default \"2d\". Use \"2d-array\" for layered maps such as\n * cascaded-shadow (CSM) depth arrays. */\n readonly viewDimension?: \"2d\" | \"2d-array\";\n /** Bind a hardware comparison sampler (`sampler_comparison`) for depth compare / PCF\n * filtering. Implies a depth texture. Default false. */\n readonly comparison?: boolean;\n}\n\n/** A storage buffer declaration. `type` is the WGSL variable type, e.g. `array<vec4<f32>>`. */\nexport interface ShaderStorageBufferDecl {\n readonly name: string;\n readonly type: string;\n}\n\n/** A resolved WGSL preprocessor define (name + value). */\nexport interface ShaderDefine {\n readonly name: string;\n readonly value: ShaderDefineValue;\n}\n\nexport interface ShaderUniformSlot {\n readonly decl: ShaderUniformDecl;\n readonly value: Float32Array;\n}\n\nexport interface ShaderTextureSlot {\n readonly decl: ShaderSamplerDecl;\n current: Texture2D | null;\n}\n\nexport interface ShaderStorageBufferSlot {\n readonly decl: ShaderStorageBufferDecl;\n current: GPUBuffer | null;\n}\n\n/** A custom WGSL material: compiled from user-supplied vertex/fragment sources\n * with declared attributes, uniforms, samplers, and defines. Update its values\n * via `setShaderUniform()` / `setShaderTexture()` and friends. */\nexport interface ShaderMaterial extends Material {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniformDecls: readonly ShaderUniformDecl[];\n readonly samplerDecls: readonly ShaderSamplerDecl[];\n readonly storageBufferDecls: readonly ShaderStorageBufferDecl[];\n readonly defines: readonly ShaderDefine[];\n readonly needAlphaBlending: boolean;\n readonly blendMode: \"alpha\" | \"additive\";\n /** True for transmissive/refractive surfaces (see `ShaderMaterialOptions.transmissive`). */\n readonly transmissive: boolean;\n readonly needAlphaTesting: boolean;\n readonly backFaceCulling: boolean;\n readonly depthWrite: boolean;\n readonly depthCompare: GPUCompareFunction;\n readonly depthOnlyFragment: boolean;\n readonly depthBias: number;\n readonly depthBiasSlopeScale: number;\n /** Optional stencil-test state baked into the main-pass pipeline (mask write / discard). Set after\n * creation (`mat.stencil = { ... }`) and call `enableMaterialStencil()` before `registerScene`. Default\n * none. See `StencilState`. */\n stencil?: StencilState;\n /** @internal */\n _uniformValues: Map<string, ShaderUniformSlot>;\n /** @internal */\n _textureSlots: Map<string, ShaderTextureSlot>;\n /** @internal */\n _storageBufferSlots: Map<string, ShaderStorageBufferSlot>;\n /** @internal */\n _uniformVersion: number;\n /** @internal */\n _resourceVersion: number;\n}\n\nfunction isIdentifier(name: string): boolean {\n return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);\n}\n\nfunction assertIdentifier(kind: string, name: string): void {\n if (!isIdentifier(name)) {\n throw new Error(`ShaderMaterial: ${kind} name \"${name}\" is not a valid WGSL identifier.`);\n }\n}\n\nfunction isSupportedAttribute(name: string): name is ShaderAttributeName {\n return name === \"position\" || name === \"normal\" || name === \"uv\" || name === \"uv2\" || name === \"tangent\" || name === \"color\";\n}\n\nfunction isSystemUniform(name: string): name is ShaderSystemUniformName {\n return (\n name === \"world\" ||\n name === \"view\" ||\n name === \"projection\" ||\n name === \"viewProjection\" ||\n name === \"worldView\" ||\n name === \"worldViewProjection\" ||\n name === \"cameraPosition\" ||\n name === \"screenSize\" ||\n name === \"alphaCutoff\"\n );\n}\n\nfunction systemUniformType(name: ShaderSystemUniformName): ShaderUniformType {\n if (name === \"cameraPosition\") {\n return \"vec3<f32>\";\n }\n if (name === \"screenSize\") {\n return \"vec2<f32>\";\n }\n if (name === \"alphaCutoff\") {\n return \"f32\";\n }\n return \"mat4x4<f32>\";\n}\n\nexport function _isShaderSystemUniform(name: string): name is ShaderSystemUniformName {\n return isSystemUniform(name);\n}\n\n/** Create a ShaderMaterial from WGSL sources and declarations, validating\n * attributes, uniforms, samplers, and defines.\n * @param options - Sources, attributes, uniforms, samplers, defines, and render state.\n * @returns The constructed `ShaderMaterial`. */\nexport function createShaderMaterial(options: ShaderMaterialOptions): ShaderMaterial {\n if (!options.vertexSource || !options.fragmentSource) {\n throw new Error(\"ShaderMaterial: vertexSource and fragmentSource must be non-empty WGSL strings.\");\n }\n const attributes: ShaderAttributeName[] = [];\n const seenAttributes = new Set<string>();\n for (const attr of options.attributes) {\n if (!isSupportedAttribute(attr)) {\n throw new Error(`ShaderMaterial: unsupported attribute \"${String(attr)}\". Supported attributes: position, normal, uv, uv2, tangent, color.`);\n }\n if (seenAttributes.has(attr)) {\n throw new Error(`ShaderMaterial: duplicate attribute \"${attr}\".`);\n }\n seenAttributes.add(attr);\n attributes.push(attr);\n }\n if (!seenAttributes.has(\"position\")) {\n throw new Error('ShaderMaterial: \"position\" attribute is required for mesh rendering.');\n }\n\n const uniformDecls: ShaderUniformDecl[] = [];\n const uniformValues = new Map<string, ShaderUniformSlot>();\n const usedNames = new Set<string>();\n for (const opt of options.uniforms ?? []) {\n const decl = typeof opt === \"string\" ? normalizeSystemUniform(opt) : normalizeCustomUniform(opt);\n assertUniqueName(usedNames, \"uniform\", decl.name);\n uniformDecls.push(decl);\n uniformValues.set(decl.name, { decl, value: normalizeUniformValue(decl, decl.defaultValue ?? defaultUniformValue(decl)) });\n }\n\n const samplerDecls: ShaderSamplerDecl[] = [];\n const textureSlots = new Map<string, ShaderTextureSlot>();\n for (const opt of options.samplers ?? []) {\n const decl: ShaderSamplerDecl =\n typeof opt === \"string\"\n ? { name: opt, sampleType: \"float\" }\n : {\n name: opt.name,\n sampleType: opt.sampleType ?? (opt.comparison ? \"depth\" : \"float\"),\n viewDimension: opt.viewDimension ?? \"2d\",\n comparison: opt.comparison ?? false,\n };\n assertIdentifier(\"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", `${decl.name}Sampler`);\n samplerDecls.push(decl);\n textureSlots.set(decl.name, { decl, current: null });\n }\n\n const storageBufferDecls: ShaderStorageBufferDecl[] = [];\n const storageBufferSlots = new Map<string, ShaderStorageBufferSlot>();\n for (const opt of options.storageBuffers ?? []) {\n assertIdentifier(\"storage buffer\", opt.name);\n assertUniqueName(usedNames, \"storage buffer\", opt.name);\n storageBufferDecls.push(opt);\n storageBufferSlots.set(opt.name, { decl: opt, current: null });\n }\n\n const defines: ShaderDefine[] = [];\n for (const [name, value] of Object.entries(options.defines ?? {})) {\n assertIdentifier(\"define\", name);\n assertUniqueName(usedNames, \"define\", name);\n if (typeof value !== \"boolean\" && typeof value !== \"number\") {\n throw new Error(`ShaderMaterial: define \"${name}\" must be a boolean or number.`);\n }\n defines.push({ name, value });\n }\n defines.sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.transmissive && !(options.needAlphaBlending ?? false)) {\n throw new Error(\"ShaderMaterial: `transmissive` requires `needAlphaBlending` (the surface composites over the grabbed opaque scene color).\");\n }\n\n return {\n name: options.name,\n vertexSource: options.vertexSource,\n fragmentSource: options.fragmentSource,\n attributes,\n uniformDecls,\n samplerDecls,\n storageBufferDecls,\n defines,\n needAlphaBlending: options.needAlphaBlending ?? false,\n blendMode: options.blendMode ?? \"alpha\",\n transmissive: options.transmissive ?? false,\n needAlphaTesting: options.needAlphaTesting ?? false,\n backFaceCulling: options.backFaceCulling ?? true,\n depthWrite: options.depthWrite ?? true,\n depthCompare: options.depthCompare ?? \"greater-equal\",\n depthOnlyFragment: options.depthOnlyFragment ?? false,\n depthBias: options.depthBias ?? 0,\n depthBiasSlopeScale: options.depthBiasSlopeScale ?? 0,\n _buildGroup: getShaderGroupBuilder(),\n _uboVersion: 0,\n _uniformValues: uniformValues,\n _textureSlots: textureSlots,\n _storageBufferSlots: storageBufferSlots,\n _uniformVersion: 0,\n _resourceVersion: 0,\n };\n}\n\nfunction normalizeSystemUniform(name: string): ShaderUniformDecl {\n if (!isSystemUniform(name)) {\n throw new Error(`ShaderMaterial: custom uniform \"${name}\" must use an explicit typed declaration.`);\n }\n return { name, type: systemUniformType(name) };\n}\n\nfunction normalizeCustomUniform(decl: ShaderUniformDecl): ShaderUniformDecl {\n assertIdentifier(\"uniform\", decl.name);\n if (!isUniformType(decl.type)) {\n throw new Error(`ShaderMaterial: unsupported uniform type \"${String(decl.type)}\" for \"${decl.name}\".`);\n }\n return decl;\n}\n\nfunction isUniformType(type: string): type is ShaderUniformType {\n return type === \"f32\" || type === \"u32\" || type === \"i32\" || type === \"vec2<f32>\" || type === \"vec3<f32>\" || type === \"vec4<f32>\" || type === \"mat4x4<f32>\";\n}\n\nfunction assertUniqueName(usedNames: Set<string>, kind: string, name: string): void {\n if (usedNames.has(name)) {\n throw new Error(`ShaderMaterial: duplicate generated identifier \"${name}\" while adding ${kind}.`);\n }\n usedNames.add(name);\n}\n\nfunction elementCount(type: ShaderUniformType): number {\n switch (type) {\n case \"f32\":\n case \"u32\":\n case \"i32\":\n return 1;\n case \"vec2<f32>\":\n return 2;\n case \"vec3<f32>\":\n return 3;\n case \"vec4<f32>\":\n return 4;\n case \"mat4x4<f32>\":\n return 16;\n }\n}\n\nfunction defaultUniformValue(decl: ShaderUniformDecl): ShaderUniformValue {\n if (decl.name === \"alphaCutoff\") {\n return 0.4;\n }\n const count = elementCount(decl.type);\n return count === 1 ? 0 : new Array(count).fill(0);\n}\n\nfunction normalizeUniformValue(decl: ShaderUniformDecl, value: ShaderUniformValue): Float32Array {\n const count = elementCount(decl.type);\n const arr = typeof value === \"number\" ? new F32([value]) : value instanceof F32 ? new F32(value) : new F32(value);\n if (arr.length !== count) {\n throw new Error(`ShaderMaterial: uniform \"${decl.name}\" of type ${decl.type} expects ${count} value(s), got ${arr.length}.`);\n }\n return arr;\n}\n\n/** Set a declared uniform's value, validating its element count against the\n * declared type and bumping the material's UBO version.\n * @param material - Target material.\n * @param name - Declared uniform name.\n * @param value - New value (scalar, array, or `Float32Array`). */\nexport function setShaderUniform(material: ShaderMaterial, name: string, value: ShaderUniformValue): void {\n const slot = material._uniformValues.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: uniform \"${name}\" was not declared.`);\n }\n slot.value.set(normalizeUniformValue(slot.decl, value));\n material._uniformVersion++;\n material._uboVersion = material._uniformVersion;\n}\n\n/** Bind (or clear) the texture for a declared sampler, enforcing that depth and\n * non-depth samplers receive a matching `Texture2D`.\n * @param material - Target material.\n * @param name - Declared sampler name.\n * @param texture - Texture to bind, or `null` to clear. */\nexport function setShaderTexture(material: ShaderMaterial, name: string, texture: Texture2D | null): void {\n const slot = material._textureSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" was not declared.`);\n }\n if (texture) {\n const expectsDepth = slot.decl.comparison || slot.decl.sampleType === \"depth\";\n const isDepthTexture = texture._sampleType === \"depth\";\n if (expectsDepth && !isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" expects a depth Texture2D.`);\n }\n if (!expectsDepth && isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" cannot use a depth Texture2D.`);\n }\n }\n // Only invalidate the cached bind groups when the bound texture HANDLE actually changes. The bind group\n // references the texture's view + sampler (see createShaderBindGroup), so re-binding the SAME Texture2D (the\n // common \"keep my shadow map / scene-depth bound every frame\" pattern) leaves those identical. Bumping the\n // resource version unconditionally therefore forced a BRAND-NEW bind group every frame (per material, for every\n // packet using it), churning the D3D12 descriptor heap until it OOMed on content-heavy scenes (e.g. reloading\n // a big save). A texture's CONTENTS can change freely without a new bind group (the bound view is live), so\n // identity comparison is correct.\n if (slot.current !== texture) {\n slot.current = texture;\n material._resourceVersion++;\n }\n}\n\n/** Bind (or clear) a declared read-only storage buffer. */\nexport function setShaderStorageBuffer(material: ShaderMaterial, name: string, buffer: GPUBuffer | null): void {\n const slot = material._storageBufferSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: storage buffer \"${name}\" was not declared.`);\n }\n // See setShaderTexture: only invalidate the bind groups when the bound buffer HANDLE changes; re-binding the\n // same GPUBuffer is a no-op (contents update live), so an unconditional bump churned the descriptor heap.\n if (slot.current !== buffer) {\n slot.current = buffer;\n material._resourceVersion++;\n }\n}\n\n/** Set a declared `f32` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderFloat(material: ShaderMaterial, name: string, value: number): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `vec3<f32>` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderVector3(material: ShaderMaterial, name: string, value: readonly [number, number, number]): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `mat4x4<f32>` uniform. Convenience wrapper over `setShaderUniform()`.\n * Accepts a raw `Float32Array` or the engine's branded `Mat4` (e.g. the result of\n * `getViewProjectionMatrix()` / `mat4Invert()`), so camera/math matrices can be fed\n * straight into a matrix uniform without laundering through a typed array. */\nexport function setShaderMatrix(material: ShaderMaterial, name: string, value: Float32Array | Mat4): void {\n setShaderUniform(material, name, value instanceof Float32Array ? value : Array.from(value));\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shader-material.js","sources":["../../../../src/material/shader/shader-material.ts"],"sourcesContent":["import { F32 } from \"../../engine/typed-arrays.js\";\nimport type { Material, StencilState } from \"../material.js\";\nimport type { Texture2D } from \"../../texture/texture-2d.js\";\nimport type { Mat4 } from \"../../math/types.js\";\nimport { getShaderGroupBuilder } from \"./shader-group-builder.js\";\n\n/** Vertex attribute names a ShaderMaterial can bind. `joints`/`weights` (and `joints1`/`weights1`\n * for \\>4 bones/vertex) are the skinning attributes — bound from the mesh's skeleton/VAT buffers,\n * letting a custom material do vertex skinning (e.g. baked vertex-animation). */\nexport type ShaderAttributeName = \"position\" | \"normal\" | \"uv\" | \"uv2\" | \"tangent\" | \"color\" | \"joints\" | \"weights\" | \"joints1\" | \"weights1\";\n/** WGSL scalar/vector/matrix types supported for ShaderMaterial uniforms. */\nexport type ShaderUniformType = \"f32\" | \"u32\" | \"i32\" | \"vec2<f32>\" | \"vec3<f32>\" | \"vec4<f32>\" | \"mat4x4<f32>\";\n/** Built-in uniform names automatically populated by the renderer each frame\n * (transforms, camera position, screen size, alpha cutoff). */\nexport type ShaderSystemUniformName = \"world\" | \"view\" | \"projection\" | \"viewProjection\" | \"worldView\" | \"worldViewProjection\" | \"cameraPosition\" | \"screenSize\" | \"alphaCutoff\";\n/** A uniform entry: either a system uniform name or an explicit custom declaration. */\nexport type ShaderUniformOption = ShaderSystemUniformName | ShaderUniformDecl;\n/** Accepted value shape when setting a ShaderMaterial uniform. */\nexport type ShaderUniformValue = number | readonly number[] | Float32Array;\n/** A sampler entry: either a bare sampler name or an explicit declaration. */\nexport type ShaderSamplerOption = string | ShaderSamplerDecl;\n/** A storage-buffer entry: a read-only WGSL storage binding declaration. */\nexport type ShaderStorageBufferOption = ShaderStorageBufferDecl;\n/** Value of a WGSL preprocessor define — boolean toggle or numeric constant. */\nexport type ShaderDefineValue = boolean | number;\n/** Map of WGSL preprocessor define names to their values. */\nexport type ShaderDefineMap = Readonly<Record<string, ShaderDefineValue>>;\n\n/** Options describing a ShaderMaterial: WGSL sources, attributes, uniforms,\n * samplers, defines, and blend/depth state. Passed to `createShaderMaterial()`. */\nexport interface ShaderMaterialOptions {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniforms?: readonly ShaderUniformOption[];\n readonly samplers?: readonly ShaderSamplerOption[];\n readonly storageBuffers?: readonly ShaderStorageBufferOption[];\n readonly defines?: ShaderDefineMap;\n readonly needAlphaBlending?: boolean;\n /** Blend equation used when `needAlphaBlending` is set. \"alpha\" (default) is\n * standard src-over; \"additive\" adds the fragment's premultiplied-by-alpha\n * color to the framebuffer, which is the right choice for glows/light FX. */\n readonly blendMode?: \"alpha\" | \"additive\";\n /** Mark this surface as transmissive/refractive: the renderer grabs the opaque scene color\n * behind it just before it draws, so the fragment can sample what is *through* it (water,\n * glass). Requires `needAlphaBlending` (the surface composites over the grabbed scene\n * color). Enable the scene-color grab on the surface's render task with\n * `enableRenderTaskTransmission`, then bind the resulting texture via `setShaderTexture`.\n * Default false. */\n readonly transmissive?: boolean;\n readonly needAlphaTesting?: boolean;\n readonly backFaceCulling?: boolean;\n readonly depthWrite?: boolean;\n readonly depthCompare?: GPUCompareFunction;\n /** Compile/run the fragment stage even for depth-only render targets (no colour attachments).\n * Use for depth-only casters that need `discard` (alpha/clip masks). The fragment shader must not\n * declare colour outputs when drawn into a depth-only target. Default false. */\n readonly depthOnlyFragment?: boolean;\n /** Constant depth-bias added in the pipeline's depth-stencil state (units of the depth format's minimum\n * representable value). Lets a surface that hugs another (e.g. tiles overlapping a cone, decals) win the\n * depth test consistently and avoid z-fighting. Default 0 (no bias). */\n readonly depthBias?: number;\n /** Slope-scaled depth bias — extra bias proportional to the depth gradient, so steeply-angled (grazing)\n * surfaces get more bias. Pairs with `depthBias` to kill z-fighting at oblique angles. Default 0. */\n readonly depthBiasSlopeScale?: number;\n}\n\n/** A custom uniform declaration: WGSL identifier, type, and optional default. */\nexport interface ShaderUniformDecl {\n readonly name: string;\n readonly type: ShaderUniformType;\n readonly defaultValue?: number | readonly number[];\n}\n\n/** A sampler declaration: WGSL identifier and the bound texture's sample type. */\nexport interface ShaderSamplerDecl {\n readonly name: string;\n readonly sampleType?: \"float\" | \"unfilterable-float\" | \"depth\";\n /** Texture view dimension. Default \"2d\". Use \"2d-array\" for layered maps such as\n * cascaded-shadow (CSM) depth arrays. */\n readonly viewDimension?: \"2d\" | \"2d-array\";\n /** Bind a hardware comparison sampler (`sampler_comparison`) for depth compare / PCF\n * filtering. Implies a depth texture. Default false. */\n readonly comparison?: boolean;\n}\n\n/** A storage buffer declaration. `type` is the WGSL variable type, e.g. `array<vec4<f32>>`. */\nexport interface ShaderStorageBufferDecl {\n readonly name: string;\n readonly type: string;\n}\n\n/** A resolved WGSL preprocessor define (name + value). */\nexport interface ShaderDefine {\n readonly name: string;\n readonly value: ShaderDefineValue;\n}\n\nexport interface ShaderUniformSlot {\n readonly decl: ShaderUniformDecl;\n readonly value: Float32Array;\n}\n\nexport interface ShaderTextureSlot {\n readonly decl: ShaderSamplerDecl;\n current: Texture2D | null;\n}\n\nexport interface ShaderStorageBufferSlot {\n readonly decl: ShaderStorageBufferDecl;\n current: GPUBuffer | null;\n}\n\n/** A custom WGSL material: compiled from user-supplied vertex/fragment sources\n * with declared attributes, uniforms, samplers, and defines. Update its values\n * via `setShaderUniform()` / `setShaderTexture()` and friends. */\nexport interface ShaderMaterial extends Material {\n readonly name?: string;\n readonly vertexSource: string;\n readonly fragmentSource: string;\n readonly attributes: readonly ShaderAttributeName[];\n readonly uniformDecls: readonly ShaderUniformDecl[];\n readonly samplerDecls: readonly ShaderSamplerDecl[];\n readonly storageBufferDecls: readonly ShaderStorageBufferDecl[];\n readonly defines: readonly ShaderDefine[];\n readonly needAlphaBlending: boolean;\n readonly blendMode: \"alpha\" | \"additive\";\n /** True for transmissive/refractive surfaces (see `ShaderMaterialOptions.transmissive`). */\n readonly transmissive: boolean;\n readonly needAlphaTesting: boolean;\n readonly backFaceCulling: boolean;\n readonly depthWrite: boolean;\n readonly depthCompare: GPUCompareFunction;\n readonly depthOnlyFragment: boolean;\n readonly depthBias: number;\n readonly depthBiasSlopeScale: number;\n /** Optional stencil-test state baked into the main-pass pipeline (mask write / discard). Set after\n * creation (`mat.stencil = { ... }`) and call `enableMaterialStencil()` before `registerScene`. Default\n * none. See `StencilState`. */\n stencil?: StencilState;\n /** @internal */\n _uniformValues: Map<string, ShaderUniformSlot>;\n /** @internal */\n _textureSlots: Map<string, ShaderTextureSlot>;\n /** @internal */\n _storageBufferSlots: Map<string, ShaderStorageBufferSlot>;\n /** @internal */\n _uniformVersion: number;\n /** @internal */\n _resourceVersion: number;\n}\n\nfunction isIdentifier(name: string): boolean {\n return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);\n}\n\nfunction assertIdentifier(kind: string, name: string): void {\n if (!isIdentifier(name)) {\n throw new Error(`ShaderMaterial: ${kind} name \"${name}\" is not a valid WGSL identifier.`);\n }\n}\n\nfunction isSupportedAttribute(name: string): name is ShaderAttributeName {\n return (\n name === \"position\" ||\n name === \"normal\" ||\n name === \"uv\" ||\n name === \"uv2\" ||\n name === \"tangent\" ||\n name === \"color\" ||\n name === \"joints\" ||\n name === \"weights\" ||\n name === \"joints1\" ||\n name === \"weights1\"\n );\n}\n\nfunction isSystemUniform(name: string): name is ShaderSystemUniformName {\n return (\n name === \"world\" ||\n name === \"view\" ||\n name === \"projection\" ||\n name === \"viewProjection\" ||\n name === \"worldView\" ||\n name === \"worldViewProjection\" ||\n name === \"cameraPosition\" ||\n name === \"screenSize\" ||\n name === \"alphaCutoff\"\n );\n}\n\nfunction systemUniformType(name: ShaderSystemUniformName): ShaderUniformType {\n if (name === \"cameraPosition\") {\n return \"vec3<f32>\";\n }\n if (name === \"screenSize\") {\n return \"vec2<f32>\";\n }\n if (name === \"alphaCutoff\") {\n return \"f32\";\n }\n return \"mat4x4<f32>\";\n}\n\nexport function _isShaderSystemUniform(name: string): name is ShaderSystemUniformName {\n return isSystemUniform(name);\n}\n\n/** Create a ShaderMaterial from WGSL sources and declarations, validating\n * attributes, uniforms, samplers, and defines.\n * @param options - Sources, attributes, uniforms, samplers, defines, and render state.\n * @returns The constructed `ShaderMaterial`. */\nexport function createShaderMaterial(options: ShaderMaterialOptions): ShaderMaterial {\n if (!options.vertexSource || !options.fragmentSource) {\n throw new Error(\"ShaderMaterial: vertexSource and fragmentSource must be non-empty WGSL strings.\");\n }\n const attributes: ShaderAttributeName[] = [];\n const seenAttributes = new Set<string>();\n for (const attr of options.attributes) {\n if (!isSupportedAttribute(attr)) {\n throw new Error(\n `ShaderMaterial: unsupported attribute \"${String(attr)}\". Supported attributes: position, normal, uv, uv2, tangent, color, joints, weights, joints1, weights1.`\n );\n }\n if (seenAttributes.has(attr)) {\n throw new Error(`ShaderMaterial: duplicate attribute \"${attr}\".`);\n }\n seenAttributes.add(attr);\n attributes.push(attr);\n }\n if (!seenAttributes.has(\"position\")) {\n throw new Error('ShaderMaterial: \"position\" attribute is required for mesh rendering.');\n }\n\n const uniformDecls: ShaderUniformDecl[] = [];\n const uniformValues = new Map<string, ShaderUniformSlot>();\n const usedNames = new Set<string>();\n for (const opt of options.uniforms ?? []) {\n const decl = typeof opt === \"string\" ? normalizeSystemUniform(opt) : normalizeCustomUniform(opt);\n assertUniqueName(usedNames, \"uniform\", decl.name);\n uniformDecls.push(decl);\n uniformValues.set(decl.name, { decl, value: normalizeUniformValue(decl, decl.defaultValue ?? defaultUniformValue(decl)) });\n }\n\n const samplerDecls: ShaderSamplerDecl[] = [];\n const textureSlots = new Map<string, ShaderTextureSlot>();\n for (const opt of options.samplers ?? []) {\n const decl: ShaderSamplerDecl =\n typeof opt === \"string\"\n ? { name: opt, sampleType: \"float\" }\n : {\n name: opt.name,\n sampleType: opt.sampleType ?? (opt.comparison ? \"depth\" : \"float\"),\n viewDimension: opt.viewDimension ?? \"2d\",\n comparison: opt.comparison ?? false,\n };\n assertIdentifier(\"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", decl.name);\n assertUniqueName(usedNames, \"sampler\", `${decl.name}Sampler`);\n samplerDecls.push(decl);\n textureSlots.set(decl.name, { decl, current: null });\n }\n\n const storageBufferDecls: ShaderStorageBufferDecl[] = [];\n const storageBufferSlots = new Map<string, ShaderStorageBufferSlot>();\n for (const opt of options.storageBuffers ?? []) {\n assertIdentifier(\"storage buffer\", opt.name);\n assertUniqueName(usedNames, \"storage buffer\", opt.name);\n storageBufferDecls.push(opt);\n storageBufferSlots.set(opt.name, { decl: opt, current: null });\n }\n\n const defines: ShaderDefine[] = [];\n for (const [name, value] of Object.entries(options.defines ?? {})) {\n assertIdentifier(\"define\", name);\n assertUniqueName(usedNames, \"define\", name);\n if (typeof value !== \"boolean\" && typeof value !== \"number\") {\n throw new Error(`ShaderMaterial: define \"${name}\" must be a boolean or number.`);\n }\n defines.push({ name, value });\n }\n defines.sort((a, b) => a.name.localeCompare(b.name));\n\n if (options.transmissive && !(options.needAlphaBlending ?? false)) {\n throw new Error(\"ShaderMaterial: `transmissive` requires `needAlphaBlending` (the surface composites over the grabbed opaque scene color).\");\n }\n\n return {\n name: options.name,\n vertexSource: options.vertexSource,\n fragmentSource: options.fragmentSource,\n attributes,\n uniformDecls,\n samplerDecls,\n storageBufferDecls,\n defines,\n needAlphaBlending: options.needAlphaBlending ?? false,\n blendMode: options.blendMode ?? \"alpha\",\n transmissive: options.transmissive ?? false,\n needAlphaTesting: options.needAlphaTesting ?? false,\n backFaceCulling: options.backFaceCulling ?? true,\n depthWrite: options.depthWrite ?? true,\n depthCompare: options.depthCompare ?? \"greater-equal\",\n depthOnlyFragment: options.depthOnlyFragment ?? false,\n depthBias: options.depthBias ?? 0,\n depthBiasSlopeScale: options.depthBiasSlopeScale ?? 0,\n _buildGroup: getShaderGroupBuilder(),\n _uboVersion: 0,\n _uniformValues: uniformValues,\n _textureSlots: textureSlots,\n _storageBufferSlots: storageBufferSlots,\n _uniformVersion: 0,\n _resourceVersion: 0,\n };\n}\n\nfunction normalizeSystemUniform(name: string): ShaderUniformDecl {\n if (!isSystemUniform(name)) {\n throw new Error(`ShaderMaterial: custom uniform \"${name}\" must use an explicit typed declaration.`);\n }\n return { name, type: systemUniformType(name) };\n}\n\nfunction normalizeCustomUniform(decl: ShaderUniformDecl): ShaderUniformDecl {\n assertIdentifier(\"uniform\", decl.name);\n if (!isUniformType(decl.type)) {\n throw new Error(`ShaderMaterial: unsupported uniform type \"${String(decl.type)}\" for \"${decl.name}\".`);\n }\n return decl;\n}\n\nfunction isUniformType(type: string): type is ShaderUniformType {\n return type === \"f32\" || type === \"u32\" || type === \"i32\" || type === \"vec2<f32>\" || type === \"vec3<f32>\" || type === \"vec4<f32>\" || type === \"mat4x4<f32>\";\n}\n\nfunction assertUniqueName(usedNames: Set<string>, kind: string, name: string): void {\n if (usedNames.has(name)) {\n throw new Error(`ShaderMaterial: duplicate generated identifier \"${name}\" while adding ${kind}.`);\n }\n usedNames.add(name);\n}\n\nfunction elementCount(type: ShaderUniformType): number {\n switch (type) {\n case \"f32\":\n case \"u32\":\n case \"i32\":\n return 1;\n case \"vec2<f32>\":\n return 2;\n case \"vec3<f32>\":\n return 3;\n case \"vec4<f32>\":\n return 4;\n case \"mat4x4<f32>\":\n return 16;\n }\n}\n\nfunction defaultUniformValue(decl: ShaderUniformDecl): ShaderUniformValue {\n if (decl.name === \"alphaCutoff\") {\n return 0.4;\n }\n const count = elementCount(decl.type);\n return count === 1 ? 0 : new Array(count).fill(0);\n}\n\nfunction normalizeUniformValue(decl: ShaderUniformDecl, value: ShaderUniformValue): Float32Array {\n const count = elementCount(decl.type);\n const arr = typeof value === \"number\" ? new F32([value]) : value instanceof F32 ? new F32(value) : new F32(value);\n if (arr.length !== count) {\n throw new Error(`ShaderMaterial: uniform \"${decl.name}\" of type ${decl.type} expects ${count} value(s), got ${arr.length}.`);\n }\n return arr;\n}\n\n/** Set a declared uniform's value, validating its element count against the\n * declared type and bumping the material's UBO version.\n * @param material - Target material.\n * @param name - Declared uniform name.\n * @param value - New value (scalar, array, or `Float32Array`). */\nexport function setShaderUniform(material: ShaderMaterial, name: string, value: ShaderUniformValue): void {\n const slot = material._uniformValues.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: uniform \"${name}\" was not declared.`);\n }\n slot.value.set(normalizeUniformValue(slot.decl, value));\n material._uniformVersion++;\n material._uboVersion = material._uniformVersion;\n}\n\n/** Bind (or clear) the texture for a declared sampler, enforcing that depth and\n * non-depth samplers receive a matching `Texture2D`.\n * @param material - Target material.\n * @param name - Declared sampler name.\n * @param texture - Texture to bind, or `null` to clear. */\nexport function setShaderTexture(material: ShaderMaterial, name: string, texture: Texture2D | null): void {\n const slot = material._textureSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" was not declared.`);\n }\n if (texture) {\n const expectsDepth = slot.decl.comparison || slot.decl.sampleType === \"depth\";\n const isDepthTexture = texture._sampleType === \"depth\";\n if (expectsDepth && !isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" expects a depth Texture2D.`);\n }\n if (!expectsDepth && isDepthTexture) {\n throw new Error(`ShaderMaterial: sampler \"${name}\" cannot use a depth Texture2D.`);\n }\n }\n // Only invalidate the cached bind groups when the bound texture HANDLE actually changes. The bind group\n // references the texture's view + sampler (see createShaderBindGroup), so re-binding the SAME Texture2D (the\n // common \"keep my shadow map / scene-depth bound every frame\" pattern) leaves those identical. Bumping the\n // resource version unconditionally therefore forced a BRAND-NEW bind group every frame (per material, for every\n // packet using it), churning the D3D12 descriptor heap until it OOMed on content-heavy scenes (e.g. reloading\n // a big save). A texture's CONTENTS can change freely without a new bind group (the bound view is live), so\n // identity comparison is correct.\n if (slot.current !== texture) {\n slot.current = texture;\n material._resourceVersion++;\n }\n}\n\n/** Bind (or clear) a declared read-only storage buffer. */\nexport function setShaderStorageBuffer(material: ShaderMaterial, name: string, buffer: GPUBuffer | null): void {\n const slot = material._storageBufferSlots.get(name);\n if (!slot) {\n throw new Error(`ShaderMaterial: storage buffer \"${name}\" was not declared.`);\n }\n // See setShaderTexture: only invalidate the bind groups when the bound buffer HANDLE changes; re-binding the\n // same GPUBuffer is a no-op (contents update live), so an unconditional bump churned the descriptor heap.\n if (slot.current !== buffer) {\n slot.current = buffer;\n material._resourceVersion++;\n }\n}\n\n/** Set a declared `f32` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderFloat(material: ShaderMaterial, name: string, value: number): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `vec3<f32>` uniform. Convenience wrapper over `setShaderUniform()`. */\nexport function setShaderVector3(material: ShaderMaterial, name: string, value: readonly [number, number, number]): void {\n setShaderUniform(material, name, value);\n}\n\n/** Set a declared `mat4x4<f32>` uniform. Convenience wrapper over `setShaderUniform()`.\n * Accepts a raw `Float32Array` or the engine's branded `Mat4` (e.g. the result of\n * `getViewProjectionMatrix()` / `mat4Invert()`), so camera/math matrices can be fed\n * straight into a matrix uniform without laundering through a typed array. */\nexport function setShaderMatrix(material: ShaderMaterial, name: string, value: Float32Array | Mat4): void {\n setShaderUniform(material, name, value instanceof Float32Array ? value : Array.from(value));\n}\n"],"names":[],"mappings":"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"}
|