@motion-core/motion-gpu 0.4.1 → 0.5.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/README.md +99 -0
- package/dist/advanced.d.ts +1 -0
- package/dist/advanced.d.ts.map +1 -0
- package/dist/advanced.js +14 -6
- package/dist/core/advanced.d.ts +1 -0
- package/dist/core/advanced.d.ts.map +1 -0
- package/dist/core/advanced.js +14 -5
- package/dist/core/compute-shader.d.ts +87 -0
- package/dist/core/compute-shader.d.ts.map +1 -0
- package/dist/core/compute-shader.js +205 -0
- package/dist/core/compute-shader.js.map +1 -0
- package/dist/core/current-value.d.ts +1 -0
- package/dist/core/current-value.d.ts.map +1 -0
- package/dist/core/current-value.js +35 -34
- package/dist/core/current-value.js.map +1 -0
- package/dist/core/error-diagnostics.d.ts +1 -0
- package/dist/core/error-diagnostics.d.ts.map +1 -0
- package/dist/core/error-diagnostics.js +70 -137
- package/dist/core/error-diagnostics.js.map +1 -0
- package/dist/core/error-report.d.ts +2 -1
- package/dist/core/error-report.d.ts.map +1 -0
- package/dist/core/error-report.js +247 -233
- package/dist/core/error-report.js.map +1 -0
- package/dist/core/frame-registry.d.ts +1 -0
- package/dist/core/frame-registry.d.ts.map +1 -0
- package/dist/core/frame-registry.js +546 -662
- package/dist/core/frame-registry.js.map +1 -0
- package/dist/core/index.d.ts +6 -2
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -12
- package/dist/core/material-preprocess.d.ts +1 -0
- package/dist/core/material-preprocess.d.ts.map +1 -0
- package/dist/core/material-preprocess.js +131 -152
- package/dist/core/material-preprocess.js.map +1 -0
- package/dist/core/material.d.ts +23 -6
- package/dist/core/material.d.ts.map +1 -0
- package/dist/core/material.js +290 -317
- package/dist/core/material.js.map +1 -0
- package/dist/core/recompile-policy.d.ts +1 -0
- package/dist/core/recompile-policy.d.ts.map +1 -0
- package/dist/core/recompile-policy.js +18 -13
- package/dist/core/recompile-policy.js.map +1 -0
- package/dist/core/render-graph.d.ts +8 -3
- package/dist/core/render-graph.d.ts.map +1 -0
- package/dist/core/render-graph.js +77 -68
- package/dist/core/render-graph.js.map +1 -0
- package/dist/core/render-targets.d.ts +1 -0
- package/dist/core/render-targets.d.ts.map +1 -0
- package/dist/core/render-targets.js +52 -53
- package/dist/core/render-targets.js.map +1 -0
- package/dist/core/renderer.d.ts +1 -0
- package/dist/core/renderer.d.ts.map +1 -0
- package/dist/core/renderer.js +1337 -1081
- package/dist/core/renderer.js.map +1 -0
- package/dist/core/runtime-loop.d.ts +3 -2
- package/dist/core/runtime-loop.d.ts.map +1 -0
- package/dist/core/runtime-loop.js +353 -362
- package/dist/core/runtime-loop.js.map +1 -0
- package/dist/core/scheduler-helpers.d.ts +1 -0
- package/dist/core/scheduler-helpers.d.ts.map +1 -0
- package/dist/core/scheduler-helpers.js +52 -51
- package/dist/core/scheduler-helpers.js.map +1 -0
- package/dist/core/shader.d.ts +10 -1
- package/dist/core/shader.d.ts.map +1 -0
- package/dist/core/shader.js +109 -115
- package/dist/core/shader.js.map +1 -0
- package/dist/core/storage-buffers.d.ts +37 -0
- package/dist/core/storage-buffers.d.ts.map +1 -0
- package/dist/core/storage-buffers.js +95 -0
- package/dist/core/storage-buffers.js.map +1 -0
- package/dist/core/texture-loader.d.ts +1 -0
- package/dist/core/texture-loader.d.ts.map +1 -0
- package/dist/core/texture-loader.js +209 -273
- package/dist/core/texture-loader.js.map +1 -0
- package/dist/core/textures.d.ts +13 -0
- package/dist/core/textures.d.ts.map +1 -0
- package/dist/core/textures.js +111 -116
- package/dist/core/textures.js.map +1 -0
- package/dist/core/types.d.ts +147 -4
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +0 -4
- package/dist/core/uniforms.d.ts +1 -0
- package/dist/core/uniforms.d.ts.map +1 -0
- package/dist/core/uniforms.js +170 -191
- package/dist/core/uniforms.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -6
- package/dist/passes/BlitPass.d.ts +1 -0
- package/dist/passes/BlitPass.d.ts.map +1 -0
- package/dist/passes/BlitPass.js +23 -18
- package/dist/passes/BlitPass.js.map +1 -0
- package/dist/passes/ComputePass.d.ts +83 -0
- package/dist/passes/ComputePass.d.ts.map +1 -0
- package/dist/passes/ComputePass.js +92 -0
- package/dist/passes/ComputePass.js.map +1 -0
- package/dist/passes/CopyPass.d.ts +1 -0
- package/dist/passes/CopyPass.d.ts.map +1 -0
- package/dist/passes/CopyPass.js +58 -52
- package/dist/passes/CopyPass.js.map +1 -0
- package/dist/passes/FullscreenPass.d.ts +1 -0
- package/dist/passes/FullscreenPass.d.ts.map +1 -0
- package/dist/passes/FullscreenPass.js +127 -130
- package/dist/passes/FullscreenPass.js.map +1 -0
- package/dist/passes/PingPongComputePass.d.ts +104 -0
- package/dist/passes/PingPongComputePass.d.ts.map +1 -0
- package/dist/passes/PingPongComputePass.js +132 -0
- package/dist/passes/PingPongComputePass.js.map +1 -0
- package/dist/passes/ShaderPass.d.ts +1 -0
- package/dist/passes/ShaderPass.d.ts.map +1 -0
- package/dist/passes/ShaderPass.js +41 -37
- package/dist/passes/ShaderPass.js.map +1 -0
- package/dist/passes/index.d.ts +3 -0
- package/dist/passes/index.d.ts.map +1 -0
- package/dist/passes/index.js +6 -3
- package/dist/react/FragCanvas.d.ts +3 -2
- package/dist/react/FragCanvas.d.ts.map +1 -0
- package/dist/react/FragCanvas.js +234 -211
- package/dist/react/FragCanvas.js.map +1 -0
- package/dist/react/MotionGPUErrorOverlay.d.ts +1 -0
- package/dist/react/MotionGPUErrorOverlay.d.ts.map +1 -0
- package/dist/react/MotionGPUErrorOverlay.js +200 -14
- package/dist/react/MotionGPUErrorOverlay.js.map +1 -0
- package/dist/react/Portal.d.ts +1 -0
- package/dist/react/Portal.d.ts.map +1 -0
- package/dist/react/Portal.js +18 -21
- package/dist/react/Portal.js.map +1 -0
- package/dist/react/advanced.d.ts +1 -0
- package/dist/react/advanced.d.ts.map +1 -0
- package/dist/react/advanced.js +14 -6
- package/dist/react/frame-context.d.ts +1 -0
- package/dist/react/frame-context.d.ts.map +1 -0
- package/dist/react/frame-context.js +88 -94
- package/dist/react/frame-context.js.map +1 -0
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +12 -9
- package/dist/react/motiongpu-context.d.ts +1 -0
- package/dist/react/motiongpu-context.d.ts.map +1 -0
- package/dist/react/motiongpu-context.js +18 -15
- package/dist/react/motiongpu-context.js.map +1 -0
- package/dist/react/use-motiongpu-user-context.d.ts +1 -0
- package/dist/react/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/react/use-motiongpu-user-context.js +83 -82
- package/dist/react/use-motiongpu-user-context.js.map +1 -0
- package/dist/react/use-texture.d.ts +1 -0
- package/dist/react/use-texture.d.ts.map +1 -0
- package/dist/react/use-texture.js +132 -152
- package/dist/react/use-texture.js.map +1 -0
- package/dist/svelte/FragCanvas.svelte +2 -2
- package/dist/svelte/FragCanvas.svelte.d.ts +3 -2
- package/dist/svelte/FragCanvas.svelte.d.ts.map +1 -0
- package/dist/svelte/MotionGPUErrorOverlay.svelte +137 -7
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts +1 -0
- package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts.map +1 -0
- package/dist/svelte/Portal.svelte.d.ts +1 -0
- package/dist/svelte/Portal.svelte.d.ts.map +1 -0
- package/dist/svelte/advanced.d.ts +1 -0
- package/dist/svelte/advanced.d.ts.map +1 -0
- package/dist/svelte/advanced.js +13 -6
- package/dist/svelte/frame-context.d.ts +1 -0
- package/dist/svelte/frame-context.d.ts.map +1 -0
- package/dist/svelte/frame-context.js +27 -27
- package/dist/svelte/frame-context.js.map +1 -0
- package/dist/svelte/index.d.ts +6 -2
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +12 -9
- package/dist/svelte/motiongpu-context.d.ts +1 -0
- package/dist/svelte/motiongpu-context.d.ts.map +1 -0
- package/dist/svelte/motiongpu-context.js +24 -21
- package/dist/svelte/motiongpu-context.js.map +1 -0
- package/dist/svelte/use-motiongpu-user-context.d.ts +1 -0
- package/dist/svelte/use-motiongpu-user-context.d.ts.map +1 -0
- package/dist/svelte/use-motiongpu-user-context.js +69 -70
- package/dist/svelte/use-motiongpu-user-context.js.map +1 -0
- package/dist/svelte/use-texture.d.ts +1 -0
- package/dist/svelte/use-texture.d.ts.map +1 -0
- package/dist/svelte/use-texture.js +125 -147
- package/dist/svelte/use-texture.js.map +1 -0
- package/package.json +12 -7
- package/src/lib/advanced.ts +6 -0
- package/src/lib/core/advanced.ts +12 -0
- package/src/lib/core/compute-shader.ts +326 -0
- package/src/lib/core/current-value.ts +64 -0
- package/src/lib/core/error-diagnostics.ts +236 -0
- package/src/lib/core/error-report.ts +535 -0
- package/src/lib/core/frame-registry.ts +1190 -0
- package/src/lib/core/index.ts +94 -0
- package/src/lib/core/material-preprocess.ts +295 -0
- package/src/lib/core/material.ts +748 -0
- package/src/lib/core/recompile-policy.ts +31 -0
- package/src/lib/core/render-graph.ts +173 -0
- package/src/lib/core/render-targets.ts +107 -0
- package/src/lib/core/renderer.ts +2161 -0
- package/src/lib/core/runtime-loop.ts +537 -0
- package/src/lib/core/scheduler-helpers.ts +136 -0
- package/src/lib/core/shader.ts +301 -0
- package/src/lib/core/storage-buffers.ts +142 -0
- package/src/lib/core/texture-loader.ts +482 -0
- package/src/lib/core/textures.ts +257 -0
- package/src/lib/core/types.ts +743 -0
- package/src/lib/core/uniforms.ts +282 -0
- package/src/lib/index.ts +6 -0
- package/src/lib/passes/BlitPass.ts +54 -0
- package/src/lib/passes/ComputePass.ts +136 -0
- package/src/lib/passes/CopyPass.ts +80 -0
- package/src/lib/passes/FullscreenPass.ts +173 -0
- package/src/lib/passes/PingPongComputePass.ts +180 -0
- package/src/lib/passes/ShaderPass.ts +89 -0
- package/src/lib/passes/index.ts +9 -0
- package/src/lib/react/FragCanvas.tsx +345 -0
- package/src/lib/react/MotionGPUErrorOverlay.tsx +524 -0
- package/src/lib/react/Portal.tsx +34 -0
- package/src/lib/react/advanced.ts +36 -0
- package/src/lib/react/frame-context.ts +169 -0
- package/src/lib/react/index.ts +68 -0
- package/src/lib/react/motiongpu-context.ts +88 -0
- package/src/lib/react/use-motiongpu-user-context.ts +186 -0
- package/src/lib/react/use-texture.ts +233 -0
- package/src/lib/svelte/FragCanvas.svelte +249 -0
- package/src/lib/svelte/MotionGPUErrorOverlay.svelte +512 -0
- package/src/lib/svelte/Portal.svelte +31 -0
- package/src/lib/svelte/advanced.ts +32 -0
- package/src/lib/svelte/frame-context.ts +87 -0
- package/src/lib/svelte/index.ts +68 -0
- package/src/lib/svelte/motiongpu-context.ts +97 -0
- package/src/lib/svelte/use-motiongpu-user-context.ts +145 -0
- package/src/lib/svelte/use-texture.ts +232 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { OutputColorSpace } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Inputs that affect renderer pipeline compilation.
|
|
5
|
+
*/
|
|
6
|
+
export interface RendererPipelineSignatureInput {
|
|
7
|
+
/**
|
|
8
|
+
* Material pipeline signature (fragment preprocess + uniform/texture layout).
|
|
9
|
+
*/
|
|
10
|
+
materialSignature: string;
|
|
11
|
+
/**
|
|
12
|
+
* Output color-space transform mode.
|
|
13
|
+
*/
|
|
14
|
+
outputColorSpace: OutputColorSpace;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Returns deterministic renderer pipeline signature.
|
|
19
|
+
*
|
|
20
|
+
* Rebuild triggers:
|
|
21
|
+
* - material signature changes (shader/layout related)
|
|
22
|
+
* - output color space changes
|
|
23
|
+
*
|
|
24
|
+
* Non-triggers:
|
|
25
|
+
* - runtime uniform values
|
|
26
|
+
* - runtime texture sources
|
|
27
|
+
* - clear color changes
|
|
28
|
+
*/
|
|
29
|
+
export function buildRendererPipelineSignature(input: RendererPipelineSignatureInput): string {
|
|
30
|
+
return `${input.materialSignature}|${input.outputColorSpace}`;
|
|
31
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type { AnyPass, RenderPass, RenderPassInputSlot, RenderPassOutputSlot } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolved render-pass step with defaults applied.
|
|
5
|
+
*/
|
|
6
|
+
export interface RenderGraphStep {
|
|
7
|
+
/**
|
|
8
|
+
* Step kind. 'render' for existing passes, 'compute' for compute passes.
|
|
9
|
+
*/
|
|
10
|
+
kind: 'render' | 'compute';
|
|
11
|
+
/**
|
|
12
|
+
* User pass instance.
|
|
13
|
+
*/
|
|
14
|
+
pass: AnyPass;
|
|
15
|
+
/**
|
|
16
|
+
* Resolved input slot.
|
|
17
|
+
*/
|
|
18
|
+
input: RenderPassInputSlot;
|
|
19
|
+
/**
|
|
20
|
+
* Resolved output slot.
|
|
21
|
+
*/
|
|
22
|
+
output: RenderPassOutputSlot;
|
|
23
|
+
/**
|
|
24
|
+
* Whether ping-pong swap should be performed after render.
|
|
25
|
+
*/
|
|
26
|
+
needsSwap: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Whether pass should clear output before drawing.
|
|
29
|
+
*/
|
|
30
|
+
clear: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Effective clear color.
|
|
33
|
+
*/
|
|
34
|
+
clearColor: [number, number, number, number];
|
|
35
|
+
/**
|
|
36
|
+
* Whether output should be preserved after pass ends.
|
|
37
|
+
*/
|
|
38
|
+
preserve: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Immutable render-graph execution plan for one frame.
|
|
43
|
+
*/
|
|
44
|
+
export interface RenderGraphPlan {
|
|
45
|
+
/**
|
|
46
|
+
* Resolved enabled steps in execution order.
|
|
47
|
+
*/
|
|
48
|
+
steps: RenderGraphStep[];
|
|
49
|
+
/**
|
|
50
|
+
* Output slot holding final frame result before presentation.
|
|
51
|
+
*/
|
|
52
|
+
finalOutput: RenderPassOutputSlot;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Creates a copy of RGBA clear color.
|
|
57
|
+
*/
|
|
58
|
+
function cloneClearColor(
|
|
59
|
+
color: [number, number, number, number]
|
|
60
|
+
): [number, number, number, number] {
|
|
61
|
+
return [color[0], color[1], color[2], color[3]];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Builds validated render graph plan from runtime pass list.
|
|
66
|
+
*
|
|
67
|
+
* @param passes - Runtime passes.
|
|
68
|
+
* @param defaultClearColor - Global clear color fallback.
|
|
69
|
+
* @returns Resolved render graph plan.
|
|
70
|
+
*/
|
|
71
|
+
export function planRenderGraph(
|
|
72
|
+
passes: AnyPass[] | undefined,
|
|
73
|
+
defaultClearColor: [number, number, number, number],
|
|
74
|
+
renderTargetSlots?: Iterable<string>
|
|
75
|
+
): RenderGraphPlan {
|
|
76
|
+
const steps: RenderGraphStep[] = [];
|
|
77
|
+
const declaredTargets = new Set(renderTargetSlots ?? []);
|
|
78
|
+
const availableSlots = new Set<RenderPassInputSlot | RenderPassOutputSlot>(['source']);
|
|
79
|
+
let finalOutput: RenderPassOutputSlot = 'canvas';
|
|
80
|
+
let enabledIndex = 0;
|
|
81
|
+
|
|
82
|
+
for (const pass of passes ?? []) {
|
|
83
|
+
if (pass.enabled === false) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Compute passes don't participate in slot routing
|
|
88
|
+
const isCompute = 'isCompute' in pass && (pass as { isCompute?: boolean }).isCompute === true;
|
|
89
|
+
if (isCompute) {
|
|
90
|
+
steps.push({
|
|
91
|
+
kind: 'compute',
|
|
92
|
+
pass,
|
|
93
|
+
input: 'source',
|
|
94
|
+
output: 'source',
|
|
95
|
+
needsSwap: false,
|
|
96
|
+
clear: false,
|
|
97
|
+
clearColor: cloneClearColor(defaultClearColor),
|
|
98
|
+
preserve: true
|
|
99
|
+
});
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// After compute guard, pass is a render pass
|
|
104
|
+
const rp = pass as RenderPass;
|
|
105
|
+
const needsSwap = rp.needsSwap ?? true;
|
|
106
|
+
const input: RenderPassInputSlot = rp.input ?? 'source';
|
|
107
|
+
const output: RenderPassOutputSlot = rp.output ?? (needsSwap ? 'target' : 'source');
|
|
108
|
+
|
|
109
|
+
if (input === 'canvas') {
|
|
110
|
+
throw new Error(`Render pass #${enabledIndex} cannot read from "canvas".`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const inputIsNamed = input !== 'source' && input !== 'target';
|
|
114
|
+
if (inputIsNamed && !declaredTargets.has(input)) {
|
|
115
|
+
throw new Error(`Render pass #${enabledIndex} reads unknown target "${input}".`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const outputIsNamed = output !== 'source' && output !== 'target' && output !== 'canvas';
|
|
119
|
+
if (outputIsNamed && !declaredTargets.has(output)) {
|
|
120
|
+
throw new Error(`Render pass #${enabledIndex} writes unknown target "${output}".`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (needsSwap && (input !== 'source' || output !== 'target')) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Render pass #${enabledIndex} uses needsSwap=true but does not follow source->target flow.`
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!availableSlots.has(input)) {
|
|
130
|
+
throw new Error(`Render pass #${enabledIndex} reads "${input}" before it is written.`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const clear = rp.clear ?? false;
|
|
134
|
+
const clearColor = cloneClearColor(rp.clearColor ?? defaultClearColor);
|
|
135
|
+
const preserve = rp.preserve ?? true;
|
|
136
|
+
|
|
137
|
+
steps.push({
|
|
138
|
+
kind: 'render',
|
|
139
|
+
pass,
|
|
140
|
+
input,
|
|
141
|
+
output,
|
|
142
|
+
needsSwap,
|
|
143
|
+
clear,
|
|
144
|
+
clearColor,
|
|
145
|
+
preserve
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
if (needsSwap) {
|
|
149
|
+
availableSlots.add('target');
|
|
150
|
+
availableSlots.add('source');
|
|
151
|
+
finalOutput = 'source';
|
|
152
|
+
} else {
|
|
153
|
+
if (output !== 'canvas') {
|
|
154
|
+
availableSlots.add(output);
|
|
155
|
+
}
|
|
156
|
+
finalOutput = output;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
enabledIndex += 1;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// When steps exist (even compute-only) but no render pass changed
|
|
163
|
+
// finalOutput from 'canvas', the scene was drawn to 'source' and
|
|
164
|
+
// needs blitting to the canvas surface.
|
|
165
|
+
if (steps.length > 0 && enabledIndex === 0) {
|
|
166
|
+
finalOutput = 'source';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
steps,
|
|
171
|
+
finalOutput
|
|
172
|
+
};
|
|
173
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { assertUniformName } from './uniforms.js';
|
|
2
|
+
import type { RenderTargetDefinitionMap } from './types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Concrete render target configuration resolved for current canvas size.
|
|
6
|
+
*/
|
|
7
|
+
export interface ResolvedRenderTargetDefinition {
|
|
8
|
+
/**
|
|
9
|
+
* Render target key.
|
|
10
|
+
*/
|
|
11
|
+
key: string;
|
|
12
|
+
/**
|
|
13
|
+
* Resolved width in pixels.
|
|
14
|
+
*/
|
|
15
|
+
width: number;
|
|
16
|
+
/**
|
|
17
|
+
* Resolved height in pixels.
|
|
18
|
+
*/
|
|
19
|
+
height: number;
|
|
20
|
+
/**
|
|
21
|
+
* Resolved format.
|
|
22
|
+
*/
|
|
23
|
+
format: GPUTextureFormat;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Asserts positive finite numeric input for render target options.
|
|
28
|
+
*/
|
|
29
|
+
function assertPositiveFinite(name: string, value: number): void {
|
|
30
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
31
|
+
throw new Error(`${name} must be a finite number greater than 0`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resolves a render target dimension from explicit value or scaled canvas size.
|
|
37
|
+
*/
|
|
38
|
+
function resolveDimension(
|
|
39
|
+
explicitValue: number | undefined,
|
|
40
|
+
canvasDimension: number,
|
|
41
|
+
scale: number
|
|
42
|
+
): number {
|
|
43
|
+
if (explicitValue !== undefined) {
|
|
44
|
+
assertPositiveFinite('RenderTarget dimension', explicitValue);
|
|
45
|
+
return Math.max(1, Math.floor(explicitValue));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return Math.max(1, Math.floor(canvasDimension * scale));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Resolves all render target definitions for a specific canvas size.
|
|
53
|
+
*
|
|
54
|
+
* @param definitions - Declarative definitions.
|
|
55
|
+
* @param canvasWidth - Current canvas width in pixels.
|
|
56
|
+
* @param canvasHeight - Current canvas height in pixels.
|
|
57
|
+
* @param defaultFormat - Fallback texture format.
|
|
58
|
+
* @returns Sorted concrete render target definitions.
|
|
59
|
+
*/
|
|
60
|
+
export function resolveRenderTargetDefinitions(
|
|
61
|
+
definitions: RenderTargetDefinitionMap | undefined,
|
|
62
|
+
canvasWidth: number,
|
|
63
|
+
canvasHeight: number,
|
|
64
|
+
defaultFormat: GPUTextureFormat
|
|
65
|
+
): ResolvedRenderTargetDefinition[] {
|
|
66
|
+
if (!definitions) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const keys = Object.keys(definitions).sort();
|
|
71
|
+
const resolved: ResolvedRenderTargetDefinition[] = [];
|
|
72
|
+
|
|
73
|
+
for (const key of keys) {
|
|
74
|
+
assertUniformName(key);
|
|
75
|
+
const definition = definitions[key];
|
|
76
|
+
const scale = definition?.scale ?? 1;
|
|
77
|
+
assertPositiveFinite('RenderTarget scale', scale);
|
|
78
|
+
|
|
79
|
+
const width = resolveDimension(definition?.width, canvasWidth, scale);
|
|
80
|
+
const height = resolveDimension(definition?.height, canvasHeight, scale);
|
|
81
|
+
|
|
82
|
+
resolved.push({
|
|
83
|
+
key,
|
|
84
|
+
width,
|
|
85
|
+
height,
|
|
86
|
+
format: definition?.format ?? defaultFormat
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return resolved;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Builds a deterministic signature used to detect render target topology changes.
|
|
95
|
+
*
|
|
96
|
+
* @param resolvedDefinitions - Concrete target definitions.
|
|
97
|
+
* @returns Stable signature string.
|
|
98
|
+
*/
|
|
99
|
+
export function buildRenderTargetSignature(
|
|
100
|
+
resolvedDefinitions: ResolvedRenderTargetDefinition[]
|
|
101
|
+
): string {
|
|
102
|
+
return resolvedDefinitions
|
|
103
|
+
.map((definition) => {
|
|
104
|
+
return `${definition.key}:${definition.format}:${definition.width}x${definition.height}`;
|
|
105
|
+
})
|
|
106
|
+
.join('|');
|
|
107
|
+
}
|