@motion-core/motion-gpu 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/dist/advanced.d.ts +1 -0
  2. package/dist/advanced.d.ts.map +1 -0
  3. package/dist/advanced.js +12 -6
  4. package/dist/core/advanced.d.ts +1 -0
  5. package/dist/core/advanced.d.ts.map +1 -0
  6. package/dist/core/advanced.js +12 -5
  7. package/dist/core/current-value.d.ts +1 -0
  8. package/dist/core/current-value.d.ts.map +1 -0
  9. package/dist/core/current-value.js +35 -34
  10. package/dist/core/current-value.js.map +1 -0
  11. package/dist/core/error-diagnostics.d.ts +1 -0
  12. package/dist/core/error-diagnostics.d.ts.map +1 -0
  13. package/dist/core/error-diagnostics.js +70 -137
  14. package/dist/core/error-diagnostics.js.map +1 -0
  15. package/dist/core/error-report.d.ts +1 -0
  16. package/dist/core/error-report.d.ts.map +1 -0
  17. package/dist/core/error-report.js +184 -233
  18. package/dist/core/error-report.js.map +1 -0
  19. package/dist/core/frame-registry.d.ts +1 -0
  20. package/dist/core/frame-registry.d.ts.map +1 -0
  21. package/dist/core/frame-registry.js +546 -662
  22. package/dist/core/frame-registry.js.map +1 -0
  23. package/dist/core/index.d.ts +1 -0
  24. package/dist/core/index.d.ts.map +1 -0
  25. package/dist/core/index.js +11 -12
  26. package/dist/core/material-preprocess.d.ts +1 -0
  27. package/dist/core/material-preprocess.d.ts.map +1 -0
  28. package/dist/core/material-preprocess.js +128 -151
  29. package/dist/core/material-preprocess.js.map +1 -0
  30. package/dist/core/material.d.ts +1 -0
  31. package/dist/core/material.d.ts.map +1 -0
  32. package/dist/core/material.js +263 -317
  33. package/dist/core/material.js.map +1 -0
  34. package/dist/core/recompile-policy.d.ts +1 -0
  35. package/dist/core/recompile-policy.d.ts.map +1 -0
  36. package/dist/core/recompile-policy.js +18 -13
  37. package/dist/core/recompile-policy.js.map +1 -0
  38. package/dist/core/render-graph.d.ts +1 -0
  39. package/dist/core/render-graph.d.ts.map +1 -0
  40. package/dist/core/render-graph.js +61 -68
  41. package/dist/core/render-graph.js.map +1 -0
  42. package/dist/core/render-targets.d.ts +2 -0
  43. package/dist/core/render-targets.d.ts.map +1 -0
  44. package/dist/core/render-targets.js +52 -53
  45. package/dist/core/render-targets.js.map +1 -0
  46. package/dist/core/renderer.d.ts +1 -0
  47. package/dist/core/renderer.d.ts.map +1 -0
  48. package/dist/core/renderer.js +942 -1081
  49. package/dist/core/renderer.js.map +1 -0
  50. package/dist/core/runtime-loop.d.ts +2 -0
  51. package/dist/core/runtime-loop.d.ts.map +1 -0
  52. package/dist/core/runtime-loop.js +305 -362
  53. package/dist/core/runtime-loop.js.map +1 -0
  54. package/dist/core/scheduler-helpers.d.ts +1 -0
  55. package/dist/core/scheduler-helpers.d.ts.map +1 -0
  56. package/dist/core/scheduler-helpers.js +52 -51
  57. package/dist/core/scheduler-helpers.js.map +1 -0
  58. package/dist/core/shader.d.ts +1 -0
  59. package/dist/core/shader.d.ts.map +1 -0
  60. package/dist/core/shader.js +92 -117
  61. package/dist/core/shader.js.map +1 -0
  62. package/dist/core/texture-loader.d.ts +1 -0
  63. package/dist/core/texture-loader.d.ts.map +1 -0
  64. package/dist/core/texture-loader.js +205 -273
  65. package/dist/core/texture-loader.js.map +1 -0
  66. package/dist/core/textures.d.ts +2 -0
  67. package/dist/core/textures.d.ts.map +1 -0
  68. package/dist/core/textures.js +106 -116
  69. package/dist/core/textures.js.map +1 -0
  70. package/dist/core/types.d.ts +2 -0
  71. package/dist/core/types.d.ts.map +1 -0
  72. package/dist/core/types.js +0 -4
  73. package/dist/core/uniforms.d.ts +1 -0
  74. package/dist/core/uniforms.d.ts.map +1 -0
  75. package/dist/core/uniforms.js +170 -191
  76. package/dist/core/uniforms.js.map +1 -0
  77. package/dist/index.d.ts +1 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +11 -6
  80. package/dist/passes/BlitPass.d.ts +1 -0
  81. package/dist/passes/BlitPass.d.ts.map +1 -0
  82. package/dist/passes/BlitPass.js +23 -18
  83. package/dist/passes/BlitPass.js.map +1 -0
  84. package/dist/passes/CopyPass.d.ts +2 -0
  85. package/dist/passes/CopyPass.d.ts.map +1 -0
  86. package/dist/passes/CopyPass.js +58 -52
  87. package/dist/passes/CopyPass.js.map +1 -0
  88. package/dist/passes/FullscreenPass.d.ts +2 -0
  89. package/dist/passes/FullscreenPass.d.ts.map +1 -0
  90. package/dist/passes/FullscreenPass.js +127 -130
  91. package/dist/passes/FullscreenPass.js.map +1 -0
  92. package/dist/passes/ShaderPass.d.ts +1 -0
  93. package/dist/passes/ShaderPass.d.ts.map +1 -0
  94. package/dist/passes/ShaderPass.js +40 -37
  95. package/dist/passes/ShaderPass.js.map +1 -0
  96. package/dist/passes/index.d.ts +1 -0
  97. package/dist/passes/index.d.ts.map +1 -0
  98. package/dist/passes/index.js +4 -3
  99. package/dist/react/FragCanvas.d.ts +2 -0
  100. package/dist/react/FragCanvas.d.ts.map +1 -0
  101. package/dist/react/FragCanvas.js +234 -211
  102. package/dist/react/FragCanvas.js.map +1 -0
  103. package/dist/react/MotionGPUErrorOverlay.d.ts +1 -0
  104. package/dist/react/MotionGPUErrorOverlay.d.ts.map +1 -0
  105. package/dist/react/MotionGPUErrorOverlay.js +384 -48
  106. package/dist/react/MotionGPUErrorOverlay.js.map +1 -0
  107. package/dist/react/Portal.d.ts +1 -0
  108. package/dist/react/Portal.d.ts.map +1 -0
  109. package/dist/react/Portal.js +18 -21
  110. package/dist/react/Portal.js.map +1 -0
  111. package/dist/react/advanced.d.ts +1 -0
  112. package/dist/react/advanced.d.ts.map +1 -0
  113. package/dist/react/advanced.js +12 -6
  114. package/dist/react/frame-context.d.ts +1 -0
  115. package/dist/react/frame-context.d.ts.map +1 -0
  116. package/dist/react/frame-context.js +88 -94
  117. package/dist/react/frame-context.js.map +1 -0
  118. package/dist/react/index.d.ts +1 -0
  119. package/dist/react/index.d.ts.map +1 -0
  120. package/dist/react/index.js +10 -9
  121. package/dist/react/motiongpu-context.d.ts +1 -0
  122. package/dist/react/motiongpu-context.d.ts.map +1 -0
  123. package/dist/react/motiongpu-context.js +18 -15
  124. package/dist/react/motiongpu-context.js.map +1 -0
  125. package/dist/react/use-motiongpu-user-context.d.ts +1 -0
  126. package/dist/react/use-motiongpu-user-context.d.ts.map +1 -0
  127. package/dist/react/use-motiongpu-user-context.js +83 -82
  128. package/dist/react/use-motiongpu-user-context.js.map +1 -0
  129. package/dist/react/use-texture.d.ts +1 -0
  130. package/dist/react/use-texture.d.ts.map +1 -0
  131. package/dist/react/use-texture.js +132 -152
  132. package/dist/react/use-texture.js.map +1 -0
  133. package/dist/svelte/FragCanvas.svelte.d.ts +2 -0
  134. package/dist/svelte/FragCanvas.svelte.d.ts.map +1 -0
  135. package/dist/svelte/MotionGPUErrorOverlay.svelte +17 -20
  136. package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts +1 -0
  137. package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts.map +1 -0
  138. package/dist/svelte/Portal.svelte.d.ts +1 -0
  139. package/dist/svelte/Portal.svelte.d.ts.map +1 -0
  140. package/dist/svelte/advanced.d.ts +1 -0
  141. package/dist/svelte/advanced.d.ts.map +1 -0
  142. package/dist/svelte/advanced.js +11 -6
  143. package/dist/svelte/frame-context.d.ts +1 -0
  144. package/dist/svelte/frame-context.d.ts.map +1 -0
  145. package/dist/svelte/frame-context.js +27 -27
  146. package/dist/svelte/frame-context.js.map +1 -0
  147. package/dist/svelte/index.d.ts +1 -0
  148. package/dist/svelte/index.d.ts.map +1 -0
  149. package/dist/svelte/index.js +10 -9
  150. package/dist/svelte/motiongpu-context.d.ts +1 -0
  151. package/dist/svelte/motiongpu-context.d.ts.map +1 -0
  152. package/dist/svelte/motiongpu-context.js +24 -21
  153. package/dist/svelte/motiongpu-context.js.map +1 -0
  154. package/dist/svelte/use-motiongpu-user-context.d.ts +1 -0
  155. package/dist/svelte/use-motiongpu-user-context.d.ts.map +1 -0
  156. package/dist/svelte/use-motiongpu-user-context.js +69 -70
  157. package/dist/svelte/use-motiongpu-user-context.js.map +1 -0
  158. package/dist/svelte/use-texture.d.ts +1 -0
  159. package/dist/svelte/use-texture.d.ts.map +1 -0
  160. package/dist/svelte/use-texture.js +125 -147
  161. package/dist/svelte/use-texture.js.map +1 -0
  162. package/package.json +15 -7
  163. package/src/lib/advanced.ts +6 -0
  164. package/src/lib/core/advanced.ts +12 -0
  165. package/src/lib/core/current-value.ts +64 -0
  166. package/src/lib/core/error-diagnostics.ts +236 -0
  167. package/src/lib/core/error-report.ts +406 -0
  168. package/src/lib/core/frame-registry.ts +1189 -0
  169. package/src/lib/core/index.ts +77 -0
  170. package/src/lib/core/material-preprocess.ts +284 -0
  171. package/src/lib/core/material.ts +667 -0
  172. package/src/lib/core/recompile-policy.ts +31 -0
  173. package/src/lib/core/render-graph.ts +143 -0
  174. package/src/lib/core/render-targets.ts +107 -0
  175. package/src/lib/core/renderer.ts +1547 -0
  176. package/src/lib/core/runtime-loop.ts +458 -0
  177. package/src/lib/core/scheduler-helpers.ts +136 -0
  178. package/src/lib/core/shader.ts +258 -0
  179. package/src/lib/core/texture-loader.ts +476 -0
  180. package/src/lib/core/textures.ts +235 -0
  181. package/src/lib/core/types.ts +582 -0
  182. package/src/lib/core/uniforms.ts +282 -0
  183. package/src/lib/index.ts +6 -0
  184. package/src/lib/passes/BlitPass.ts +54 -0
  185. package/src/lib/passes/CopyPass.ts +80 -0
  186. package/src/lib/passes/FullscreenPass.ts +173 -0
  187. package/src/lib/passes/ShaderPass.ts +88 -0
  188. package/src/lib/passes/index.ts +3 -0
  189. package/src/lib/react/MotionGPUErrorOverlay.tsx +392 -0
  190. package/src/lib/react/advanced.ts +36 -0
  191. package/src/lib/react/frame-context.ts +169 -0
  192. package/src/lib/react/index.ts +51 -0
  193. package/src/lib/react/motiongpu-context.ts +88 -0
  194. package/src/lib/react/use-motiongpu-user-context.ts +186 -0
  195. package/src/lib/react/use-texture.ts +233 -0
  196. package/src/lib/svelte/FragCanvas.svelte +249 -0
  197. package/src/lib/svelte/MotionGPUErrorOverlay.svelte +382 -0
  198. package/src/lib/svelte/Portal.svelte +31 -0
  199. package/src/lib/svelte/advanced.ts +32 -0
  200. package/src/lib/svelte/frame-context.ts +87 -0
  201. package/src/lib/svelte/index.ts +51 -0
  202. package/src/lib/svelte/motiongpu-context.ts +97 -0
  203. package/src/lib/svelte/use-motiongpu-user-context.ts +145 -0
  204. package/src/lib/svelte/use-texture.ts +232 -0
  205. package/dist/react/MotionGPUErrorOverlay.tsx +0 -129
  206. /package/{dist → src/lib}/react/FragCanvas.tsx +0 -0
  207. /package/{dist → src/lib}/react/Portal.tsx +0 -0
@@ -1,222 +1,201 @@
1
+ //#region src/lib/core/uniforms.ts
1
2
  /**
2
- * Valid WGSL identifier pattern used for uniform and texture keys.
3
- */
4
- const IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
3
+ * Valid WGSL identifier pattern used for uniform and texture keys.
4
+ */
5
+ var IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
5
6
  /**
6
- * Rounds a value up to the nearest multiple of `alignment`.
7
- */
7
+ * Rounds a value up to the nearest multiple of `alignment`.
8
+ */
8
9
  function roundUp(value, alignment) {
9
- return Math.ceil(value / alignment) * alignment;
10
+ return Math.ceil(value / alignment) * alignment;
10
11
  }
11
12
  /**
12
- * Returns WGSL std140-like alignment and size metadata for a uniform type.
13
- */
13
+ * Returns WGSL std140-like alignment and size metadata for a uniform type.
14
+ */
14
15
  function getTypeLayout(type) {
15
- switch (type) {
16
- case 'f32':
17
- return { alignment: 4, size: 4 };
18
- case 'vec2f':
19
- return { alignment: 8, size: 8 };
20
- case 'vec3f':
21
- return { alignment: 16, size: 12 };
22
- case 'vec4f':
23
- return { alignment: 16, size: 16 };
24
- case 'mat4x4f':
25
- return { alignment: 16, size: 64 };
26
- default:
27
- throw new Error(`Unsupported uniform type: ${type}`);
28
- }
16
+ switch (type) {
17
+ case "f32": return {
18
+ alignment: 4,
19
+ size: 4
20
+ };
21
+ case "vec2f": return {
22
+ alignment: 8,
23
+ size: 8
24
+ };
25
+ case "vec3f": return {
26
+ alignment: 16,
27
+ size: 12
28
+ };
29
+ case "vec4f": return {
30
+ alignment: 16,
31
+ size: 16
32
+ };
33
+ case "mat4x4f": return {
34
+ alignment: 16,
35
+ size: 64
36
+ };
37
+ default: throw new Error(`Unsupported uniform type: ${type}`);
38
+ }
29
39
  }
30
40
  /**
31
- * Type guard for explicitly typed uniform objects.
32
- */
41
+ * Type guard for explicitly typed uniform objects.
42
+ */
33
43
  function isTypedUniformValue(value) {
34
- return typeof value === 'object' && value !== null && 'type' in value && 'value' in value;
44
+ return typeof value === "object" && value !== null && "type" in value && "value" in value;
35
45
  }
36
46
  /**
37
- * Validates numeric tuple input with a fixed length.
38
- */
47
+ * Validates numeric tuple input with a fixed length.
48
+ */
39
49
  function isTuple(value, size) {
40
- return (Array.isArray(value) &&
41
- value.length === size &&
42
- value.every((entry) => typeof entry === 'number' && Number.isFinite(entry)));
50
+ return Array.isArray(value) && value.length === size && value.every((entry) => typeof entry === "number" && Number.isFinite(entry));
43
51
  }
44
52
  /**
45
- * Type guard for accepted 4x4 matrix uniform values.
46
- */
53
+ * Type guard for accepted 4x4 matrix uniform values.
54
+ */
47
55
  function isMat4Value(value) {
48
- if (value instanceof Float32Array) {
49
- return value.length === 16;
50
- }
51
- return (Array.isArray(value) &&
52
- value.length === 16 &&
53
- value.every((entry) => typeof entry === 'number' && Number.isFinite(entry)));
56
+ if (value instanceof Float32Array) return value.length === 16;
57
+ return Array.isArray(value) && value.length === 16 && value.every((entry) => typeof entry === "number" && Number.isFinite(entry));
54
58
  }
55
59
  /**
56
- * Asserts that a name can be safely used as a WGSL identifier.
57
- *
58
- * @param name - Candidate uniform/texture name.
59
- * @throws {Error} When the identifier is invalid.
60
- */
61
- export function assertUniformName(name) {
62
- if (!IDENTIFIER_PATTERN.test(name)) {
63
- throw new Error(`Invalid uniform name: ${name}`);
64
- }
60
+ * Asserts that a name can be safely used as a WGSL identifier.
61
+ *
62
+ * @param name - Candidate uniform/texture name.
63
+ * @throws {Error} When the identifier is invalid.
64
+ */
65
+ function assertUniformName(name) {
66
+ if (!IDENTIFIER_PATTERN.test(name)) throw new Error(`Invalid uniform name: ${name}`);
65
67
  }
66
68
  /**
67
- * Infers the WGSL type tag from a runtime uniform value.
68
- *
69
- * @param value - Uniform input value.
70
- * @returns Inferred uniform type.
71
- * @throws {Error} When the value does not match any supported shape.
72
- */
73
- export function inferUniformType(value) {
74
- if (isTypedUniformValue(value)) {
75
- return value.type;
76
- }
77
- if (typeof value === 'number') {
78
- return 'f32';
79
- }
80
- if (Array.isArray(value)) {
81
- if (value.length === 2) {
82
- return 'vec2f';
83
- }
84
- if (value.length === 3) {
85
- return 'vec3f';
86
- }
87
- if (value.length === 4) {
88
- return 'vec4f';
89
- }
90
- }
91
- throw new Error('Uniform value must resolve to f32, vec2f, vec3f, vec4f or mat4x4f');
69
+ * Infers the WGSL type tag from a runtime uniform value.
70
+ *
71
+ * @param value - Uniform input value.
72
+ * @returns Inferred uniform type.
73
+ * @throws {Error} When the value does not match any supported shape.
74
+ */
75
+ function inferUniformType(value) {
76
+ if (isTypedUniformValue(value)) return value.type;
77
+ if (typeof value === "number") return "f32";
78
+ if (Array.isArray(value)) {
79
+ if (value.length === 2) return "vec2f";
80
+ if (value.length === 3) return "vec3f";
81
+ if (value.length === 4) return "vec4f";
82
+ }
83
+ throw new Error("Uniform value must resolve to f32, vec2f, vec3f, vec4f or mat4x4f");
92
84
  }
93
85
  /**
94
- * Validates that a uniform value matches an explicit uniform type declaration.
95
- *
96
- * @param type - Declared WGSL type.
97
- * @param value - Runtime value to validate.
98
- * @throws {Error} When the value shape is incompatible with the declared type.
99
- */
100
- export function assertUniformValueForType(type, value) {
101
- const input = isTypedUniformValue(value) ? value.value : value;
102
- if (type === 'f32') {
103
- if (typeof input !== 'number' || !Number.isFinite(input)) {
104
- throw new Error('Uniform f32 value must be a finite number');
105
- }
106
- return;
107
- }
108
- if (type === 'vec2f') {
109
- if (!isTuple(input, 2)) {
110
- throw new Error('Uniform vec2f value must be a tuple with 2 numbers');
111
- }
112
- return;
113
- }
114
- if (type === 'vec3f') {
115
- if (!isTuple(input, 3)) {
116
- throw new Error('Uniform vec3f value must be a tuple with 3 numbers');
117
- }
118
- return;
119
- }
120
- if (type === 'vec4f') {
121
- if (!isTuple(input, 4)) {
122
- throw new Error('Uniform vec4f value must be a tuple with 4 numbers');
123
- }
124
- return;
125
- }
126
- if (!isMat4Value(input)) {
127
- throw new Error('Uniform mat4x4f value must contain 16 numbers');
128
- }
86
+ * Validates that a uniform value matches an explicit uniform type declaration.
87
+ *
88
+ * @param type - Declared WGSL type.
89
+ * @param value - Runtime value to validate.
90
+ * @throws {Error} When the value shape is incompatible with the declared type.
91
+ */
92
+ function assertUniformValueForType(type, value) {
93
+ const input = isTypedUniformValue(value) ? value.value : value;
94
+ if (type === "f32") {
95
+ if (typeof input !== "number" || !Number.isFinite(input)) throw new Error("Uniform f32 value must be a finite number");
96
+ return;
97
+ }
98
+ if (type === "vec2f") {
99
+ if (!isTuple(input, 2)) throw new Error("Uniform vec2f value must be a tuple with 2 numbers");
100
+ return;
101
+ }
102
+ if (type === "vec3f") {
103
+ if (!isTuple(input, 3)) throw new Error("Uniform vec3f value must be a tuple with 3 numbers");
104
+ return;
105
+ }
106
+ if (type === "vec4f") {
107
+ if (!isTuple(input, 4)) throw new Error("Uniform vec4f value must be a tuple with 4 numbers");
108
+ return;
109
+ }
110
+ if (!isMat4Value(input)) throw new Error("Uniform mat4x4f value must contain 16 numbers");
129
111
  }
130
112
  /**
131
- * Resolves a deterministic packed uniform buffer layout from a uniform map.
132
- *
133
- * @param uniforms - Input uniform definitions.
134
- * @returns Sorted layout with byte offsets and final buffer byte length.
135
- */
136
- export function resolveUniformLayout(uniforms) {
137
- const names = Object.keys(uniforms).sort();
138
- let offset = 0;
139
- const entries = [];
140
- const byName = {};
141
- for (const name of names) {
142
- assertUniformName(name);
143
- const type = inferUniformType(uniforms[name]);
144
- const { alignment, size } = getTypeLayout(type);
145
- offset = roundUp(offset, alignment);
146
- const entry = {
147
- name,
148
- type,
149
- offset,
150
- size
151
- };
152
- entries.push(entry);
153
- byName[name] = entry;
154
- offset += size;
155
- }
156
- const byteLength = Math.max(16, roundUp(offset, 16));
157
- return { entries, byName, byteLength };
113
+ * Resolves a deterministic packed uniform buffer layout from a uniform map.
114
+ *
115
+ * @param uniforms - Input uniform definitions.
116
+ * @returns Sorted layout with byte offsets and final buffer byte length.
117
+ */
118
+ function resolveUniformLayout(uniforms) {
119
+ const names = Object.keys(uniforms).sort();
120
+ let offset = 0;
121
+ const entries = [];
122
+ const byName = {};
123
+ for (const name of names) {
124
+ assertUniformName(name);
125
+ const type = inferUniformType(uniforms[name]);
126
+ const { alignment, size } = getTypeLayout(type);
127
+ offset = roundUp(offset, alignment);
128
+ const entry = {
129
+ name,
130
+ type,
131
+ offset,
132
+ size
133
+ };
134
+ entries.push(entry);
135
+ byName[name] = entry;
136
+ offset += size;
137
+ }
138
+ return {
139
+ entries,
140
+ byName,
141
+ byteLength: Math.max(16, roundUp(offset, 16))
142
+ };
158
143
  }
159
144
  /**
160
- * Writes one validated uniform value directly into the output float buffer.
161
- */
145
+ * Writes one validated uniform value directly into the output float buffer.
146
+ */
162
147
  function writeUniformValue(type, value, data, base) {
163
- const input = isTypedUniformValue(value) ? value.value : value;
164
- assertUniformValueForType(type, value);
165
- if (type === 'f32') {
166
- data[base] = input;
167
- return;
168
- }
169
- if (type === 'mat4x4f') {
170
- const matrix = input;
171
- if (matrix instanceof Float32Array) {
172
- for (let index = 0; index < 16; index += 1) {
173
- data[base + index] = matrix[index] ?? 0;
174
- }
175
- return;
176
- }
177
- for (let index = 0; index < 16; index += 1) {
178
- data[base + index] = matrix[index] ?? 0;
179
- }
180
- return;
181
- }
182
- const tuple = input;
183
- const length = type === 'vec2f' ? 2 : type === 'vec3f' ? 3 : 4;
184
- for (let index = 0; index < length; index += 1) {
185
- data[base + index] = tuple[index] ?? 0;
186
- }
148
+ const input = isTypedUniformValue(value) ? value.value : value;
149
+ assertUniformValueForType(type, value);
150
+ if (type === "f32") {
151
+ data[base] = input;
152
+ return;
153
+ }
154
+ if (type === "mat4x4f") {
155
+ const matrix = input;
156
+ if (matrix instanceof Float32Array) {
157
+ for (let index = 0; index < 16; index += 1) data[base + index] = matrix[index] ?? 0;
158
+ return;
159
+ }
160
+ for (let index = 0; index < 16; index += 1) data[base + index] = matrix[index] ?? 0;
161
+ return;
162
+ }
163
+ const tuple = input;
164
+ const length = type === "vec2f" ? 2 : type === "vec3f" ? 3 : 4;
165
+ for (let index = 0; index < length; index += 1) data[base + index] = tuple[index] ?? 0;
187
166
  }
188
167
  /**
189
- * Packs uniforms into a newly allocated `Float32Array`.
190
- *
191
- * @param uniforms - Uniform values to pack.
192
- * @param layout - Target layout definition.
193
- * @returns Packed float buffer sized to `layout.byteLength`.
194
- */
195
- export function packUniforms(uniforms, layout) {
196
- const data = new Float32Array(layout.byteLength / 4);
197
- packUniformsInto(uniforms, layout, data);
198
- return data;
168
+ * Packs uniforms into a newly allocated `Float32Array`.
169
+ *
170
+ * @param uniforms - Uniform values to pack.
171
+ * @param layout - Target layout definition.
172
+ * @returns Packed float buffer sized to `layout.byteLength`.
173
+ */
174
+ function packUniforms(uniforms, layout) {
175
+ const data = new Float32Array(layout.byteLength / 4);
176
+ packUniformsInto(uniforms, layout, data);
177
+ return data;
199
178
  }
200
179
  /**
201
- * Packs uniforms into an existing output buffer and zeroes missing values.
202
- *
203
- * @param uniforms - Uniform values to pack.
204
- * @param layout - Target layout metadata.
205
- * @param data - Destination float buffer.
206
- * @throws {Error} When `data` size does not match the required layout size.
207
- */
208
- export function packUniformsInto(uniforms, layout, data) {
209
- const requiredLength = layout.byteLength / 4;
210
- if (data.length !== requiredLength) {
211
- throw new Error(`Uniform output buffer size mismatch. Expected ${requiredLength}, got ${data.length}`);
212
- }
213
- data.fill(0);
214
- for (const entry of layout.entries) {
215
- const raw = uniforms[entry.name];
216
- if (raw === undefined) {
217
- continue;
218
- }
219
- const base = entry.offset / 4;
220
- writeUniformValue(entry.type, raw, data, base);
221
- }
180
+ * Packs uniforms into an existing output buffer and zeroes missing values.
181
+ *
182
+ * @param uniforms - Uniform values to pack.
183
+ * @param layout - Target layout metadata.
184
+ * @param data - Destination float buffer.
185
+ * @throws {Error} When `data` size does not match the required layout size.
186
+ */
187
+ function packUniformsInto(uniforms, layout, data) {
188
+ const requiredLength = layout.byteLength / 4;
189
+ if (data.length !== requiredLength) throw new Error(`Uniform output buffer size mismatch. Expected ${requiredLength}, got ${data.length}`);
190
+ data.fill(0);
191
+ for (const entry of layout.entries) {
192
+ const raw = uniforms[entry.name];
193
+ if (raw === void 0) continue;
194
+ const base = entry.offset / 4;
195
+ writeUniformValue(entry.type, raw, data, base);
196
+ }
222
197
  }
198
+ //#endregion
199
+ export { assertUniformName, assertUniformValueForType, inferUniformType, packUniforms, packUniformsInto, resolveUniformLayout };
200
+
201
+ //# sourceMappingURL=uniforms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uniforms.js","names":[],"sources":["../../src/lib/core/uniforms.ts"],"sourcesContent":["import type {\n\tUniformLayout,\n\tUniformLayoutEntry,\n\tUniformMap,\n\tUniformMat4Value,\n\tUniformType,\n\tUniformValue\n} from './types.js';\n\n/**\n * Internal representation of explicitly typed uniform input.\n */\ntype UniformTypedInput = Extract<UniformValue, { type: UniformType; value: unknown }>;\n\n/**\n * Valid WGSL identifier pattern used for uniform and texture keys.\n */\nconst IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/**\n * Rounds a value up to the nearest multiple of `alignment`.\n */\nfunction roundUp(value: number, alignment: number): number {\n\treturn Math.ceil(value / alignment) * alignment;\n}\n\n/**\n * Returns WGSL std140-like alignment and size metadata for a uniform type.\n */\nfunction getTypeLayout(type: UniformType): { alignment: number; size: number } {\n\tswitch (type) {\n\t\tcase 'f32':\n\t\t\treturn { alignment: 4, size: 4 };\n\t\tcase 'vec2f':\n\t\t\treturn { alignment: 8, size: 8 };\n\t\tcase 'vec3f':\n\t\t\treturn { alignment: 16, size: 12 };\n\t\tcase 'vec4f':\n\t\t\treturn { alignment: 16, size: 16 };\n\t\tcase 'mat4x4f':\n\t\t\treturn { alignment: 16, size: 64 };\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported uniform type: ${type satisfies never}`);\n\t}\n}\n\n/**\n * Type guard for explicitly typed uniform objects.\n */\nfunction isTypedUniformValue(value: UniformValue): value is UniformTypedInput {\n\treturn typeof value === 'object' && value !== null && 'type' in value && 'value' in value;\n}\n\n/**\n * Validates numeric tuple input with a fixed length.\n */\nfunction isTuple(value: unknown, size: number): value is number[] {\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.length === size &&\n\t\tvalue.every((entry) => typeof entry === 'number' && Number.isFinite(entry))\n\t);\n}\n\n/**\n * Type guard for accepted 4x4 matrix uniform values.\n */\nfunction isMat4Value(value: unknown): value is UniformMat4Value {\n\tif (value instanceof Float32Array) {\n\t\treturn value.length === 16;\n\t}\n\n\treturn (\n\t\tArray.isArray(value) &&\n\t\tvalue.length === 16 &&\n\t\tvalue.every((entry) => typeof entry === 'number' && Number.isFinite(entry))\n\t);\n}\n\n/**\n * Asserts that a name can be safely used as a WGSL identifier.\n *\n * @param name - Candidate uniform/texture name.\n * @throws {Error} When the identifier is invalid.\n */\nexport function assertUniformName(name: string): void {\n\tif (!IDENTIFIER_PATTERN.test(name)) {\n\t\tthrow new Error(`Invalid uniform name: ${name}`);\n\t}\n}\n\n/**\n * Infers the WGSL type tag from a runtime uniform value.\n *\n * @param value - Uniform input value.\n * @returns Inferred uniform type.\n * @throws {Error} When the value does not match any supported shape.\n */\nexport function inferUniformType(value: UniformValue): UniformType {\n\tif (isTypedUniformValue(value)) {\n\t\treturn value.type;\n\t}\n\n\tif (typeof value === 'number') {\n\t\treturn 'f32';\n\t}\n\n\tif (Array.isArray(value)) {\n\t\tif (value.length === 2) {\n\t\t\treturn 'vec2f';\n\t\t}\n\t\tif (value.length === 3) {\n\t\t\treturn 'vec3f';\n\t\t}\n\t\tif (value.length === 4) {\n\t\t\treturn 'vec4f';\n\t\t}\n\t}\n\n\tthrow new Error('Uniform value must resolve to f32, vec2f, vec3f, vec4f or mat4x4f');\n}\n\n/**\n * Validates that a uniform value matches an explicit uniform type declaration.\n *\n * @param type - Declared WGSL type.\n * @param value - Runtime value to validate.\n * @throws {Error} When the value shape is incompatible with the declared type.\n */\nexport function assertUniformValueForType(type: UniformType, value: UniformValue): void {\n\tconst input = isTypedUniformValue(value) ? value.value : value;\n\n\tif (type === 'f32') {\n\t\tif (typeof input !== 'number' || !Number.isFinite(input)) {\n\t\t\tthrow new Error('Uniform f32 value must be a finite number');\n\t\t}\n\t\treturn;\n\t}\n\n\tif (type === 'vec2f') {\n\t\tif (!isTuple(input, 2)) {\n\t\t\tthrow new Error('Uniform vec2f value must be a tuple with 2 numbers');\n\t\t}\n\t\treturn;\n\t}\n\n\tif (type === 'vec3f') {\n\t\tif (!isTuple(input, 3)) {\n\t\t\tthrow new Error('Uniform vec3f value must be a tuple with 3 numbers');\n\t\t}\n\t\treturn;\n\t}\n\n\tif (type === 'vec4f') {\n\t\tif (!isTuple(input, 4)) {\n\t\t\tthrow new Error('Uniform vec4f value must be a tuple with 4 numbers');\n\t\t}\n\t\treturn;\n\t}\n\n\tif (!isMat4Value(input)) {\n\t\tthrow new Error('Uniform mat4x4f value must contain 16 numbers');\n\t}\n}\n\n/**\n * Resolves a deterministic packed uniform buffer layout from a uniform map.\n *\n * @param uniforms - Input uniform definitions.\n * @returns Sorted layout with byte offsets and final buffer byte length.\n */\nexport function resolveUniformLayout(uniforms: UniformMap): UniformLayout {\n\tconst names = Object.keys(uniforms).sort();\n\tlet offset = 0;\n\tconst entries: UniformLayoutEntry[] = [];\n\tconst byName: Record<string, UniformLayoutEntry> = {};\n\n\tfor (const name of names) {\n\t\tassertUniformName(name);\n\t\tconst type = inferUniformType(uniforms[name] as UniformValue);\n\t\tconst { alignment, size } = getTypeLayout(type);\n\t\toffset = roundUp(offset, alignment);\n\n\t\tconst entry: UniformLayoutEntry = {\n\t\t\tname,\n\t\t\ttype,\n\t\t\toffset,\n\t\t\tsize\n\t\t};\n\n\t\tentries.push(entry);\n\t\tbyName[name] = entry;\n\t\toffset += size;\n\t}\n\n\tconst byteLength = Math.max(16, roundUp(offset, 16));\n\treturn { entries, byName, byteLength };\n}\n\n/**\n * Writes one validated uniform value directly into the output float buffer.\n */\nfunction writeUniformValue(\n\ttype: UniformType,\n\tvalue: UniformValue,\n\tdata: Float32Array,\n\tbase: number\n): void {\n\tconst input = isTypedUniformValue(value) ? value.value : value;\n\tassertUniformValueForType(type, value);\n\n\tif (type === 'f32') {\n\t\tdata[base] = input as number;\n\t\treturn;\n\t}\n\n\tif (type === 'mat4x4f') {\n\t\tconst matrix = input as UniformMat4Value;\n\t\tif (matrix instanceof Float32Array) {\n\t\t\tfor (let index = 0; index < 16; index += 1) {\n\t\t\t\tdata[base + index] = matrix[index] ?? 0;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let index = 0; index < 16; index += 1) {\n\t\t\tdata[base + index] = matrix[index] ?? 0;\n\t\t}\n\t\treturn;\n\t}\n\n\tconst tuple = input as number[];\n\tconst length = type === 'vec2f' ? 2 : type === 'vec3f' ? 3 : 4;\n\tfor (let index = 0; index < length; index += 1) {\n\t\tdata[base + index] = tuple[index] ?? 0;\n\t}\n}\n\n/**\n * Packs uniforms into a newly allocated `Float32Array`.\n *\n * @param uniforms - Uniform values to pack.\n * @param layout - Target layout definition.\n * @returns Packed float buffer sized to `layout.byteLength`.\n */\nexport function packUniforms(uniforms: UniformMap, layout: UniformLayout): Float32Array {\n\tconst data = new Float32Array(layout.byteLength / 4);\n\tpackUniformsInto(uniforms, layout, data);\n\treturn data;\n}\n\n/**\n * Packs uniforms into an existing output buffer and zeroes missing values.\n *\n * @param uniforms - Uniform values to pack.\n * @param layout - Target layout metadata.\n * @param data - Destination float buffer.\n * @throws {Error} When `data` size does not match the required layout size.\n */\nexport function packUniformsInto(\n\tuniforms: UniformMap,\n\tlayout: UniformLayout,\n\tdata: Float32Array\n): void {\n\tconst requiredLength = layout.byteLength / 4;\n\tif (data.length !== requiredLength) {\n\t\tthrow new Error(\n\t\t\t`Uniform output buffer size mismatch. Expected ${requiredLength}, got ${data.length}`\n\t\t);\n\t}\n\n\tdata.fill(0);\n\tfor (const entry of layout.entries) {\n\t\tconst raw = uniforms[entry.name];\n\t\tif (raw === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst base = entry.offset / 4;\n\t\twriteUniformValue(entry.type, raw, data, base);\n\t}\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,3 +4,4 @@
4
4
  * Framework-agnostic core entrypoint.
5
5
  */
6
6
  export * from './core/index.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,11 @@
1
- /**
2
- * Root package entrypoint.
3
- *
4
- * Framework-agnostic core entrypoint.
5
- */
6
- export * from './core/index.js';
1
+ import { defineMaterial, resolveMaterial } from "./core/material.js";
2
+ import { toMotionGPUErrorReport } from "./core/error-report.js";
3
+ import { createCurrentWritable } from "./core/current-value.js";
4
+ import { createFrameRegistry } from "./core/frame-registry.js";
5
+ import { createMotionGPURuntimeLoop } from "./core/runtime-loop.js";
6
+ import { loadTexturesFromUrls } from "./core/texture-loader.js";
7
+ import { BlitPass } from "./passes/BlitPass.js";
8
+ import { CopyPass } from "./passes/CopyPass.js";
9
+ import { ShaderPass } from "./passes/ShaderPass.js";
10
+ import "./core/index.js";
11
+ export { BlitPass, CopyPass, ShaderPass, createCurrentWritable, createFrameRegistry, createMotionGPURuntimeLoop, defineMaterial, loadTexturesFromUrls, resolveMaterial, toMotionGPUErrorReport };
@@ -9,3 +9,4 @@ export declare class BlitPass extends FullscreenPass {
9
9
  protected getVertexEntryPoint(): string;
10
10
  protected getFragmentEntryPoint(): string;
11
11
  }
12
+ //# sourceMappingURL=BlitPass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlitPass.d.ts","sourceRoot":"","sources":["../../src/lib/passes/BlitPass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAgCjF,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAEpD;;GAEG;AACH,qBAAa,QAAS,SAAQ,cAAc;IAC3C,SAAS,CAAC,UAAU,IAAI,MAAM;gBAIlB,OAAO,GAAE,eAAoB;IAIzC,SAAS,CAAC,mBAAmB,IAAI,MAAM;IAIvC,SAAS,CAAC,qBAAqB,IAAI,MAAM;CAGzC"}
@@ -1,5 +1,6 @@
1
- import { FullscreenPass } from './FullscreenPass.js';
2
- const FULLSCREEN_BLIT_SHADER = `
1
+ import { FullscreenPass } from "./FullscreenPass.js";
2
+ //#region src/lib/passes/BlitPass.ts
3
+ var FULLSCREEN_BLIT_SHADER = `
3
4
  struct MotionGPUVertexOut {
4
5
  @builtin(position) position: vec4f,
5
6
  @location(0) uv: vec2f,
@@ -29,19 +30,23 @@ fn motiongpuBlitFragment(in: MotionGPUVertexOut) -> @location(0) vec4f {
29
30
  }
30
31
  `;
31
32
  /**
32
- * Fullscreen texture blit pass.
33
- */
34
- export class BlitPass extends FullscreenPass {
35
- getProgram() {
36
- return FULLSCREEN_BLIT_SHADER;
37
- }
38
- constructor(options = {}) {
39
- super(options);
40
- }
41
- getVertexEntryPoint() {
42
- return 'motiongpuBlitVertex';
43
- }
44
- getFragmentEntryPoint() {
45
- return 'motiongpuBlitFragment';
46
- }
47
- }
33
+ * Fullscreen texture blit pass.
34
+ */
35
+ var BlitPass = class extends FullscreenPass {
36
+ getProgram() {
37
+ return FULLSCREEN_BLIT_SHADER;
38
+ }
39
+ constructor(options = {}) {
40
+ super(options);
41
+ }
42
+ getVertexEntryPoint() {
43
+ return "motiongpuBlitVertex";
44
+ }
45
+ getFragmentEntryPoint() {
46
+ return "motiongpuBlitFragment";
47
+ }
48
+ };
49
+ //#endregion
50
+ export { BlitPass };
51
+
52
+ //# sourceMappingURL=BlitPass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlitPass.js","names":[],"sources":["../../src/lib/passes/BlitPass.ts"],"sourcesContent":["import { FullscreenPass, type FullscreenPassOptions } from './FullscreenPass.js';\n\nconst FULLSCREEN_BLIT_SHADER = `\nstruct MotionGPUVertexOut {\n\t@builtin(position) position: vec4f,\n\t@location(0) uv: vec2f,\n};\n\n@group(0) @binding(0) var motiongpuBlitSampler: sampler;\n@group(0) @binding(1) var motiongpuBlitTexture: texture_2d<f32>;\n\n@vertex\nfn motiongpuBlitVertex(@builtin(vertex_index) index: u32) -> MotionGPUVertexOut {\n\tvar positions = array<vec2f, 3>(\n\t\tvec2f(-1.0, -3.0),\n\t\tvec2f(-1.0, 1.0),\n\t\tvec2f(3.0, 1.0)\n\t);\n\n\tlet position = positions[index];\n\tvar out: MotionGPUVertexOut;\n\tout.position = vec4f(position, 0.0, 1.0);\n\tout.uv = (position + vec2f(1.0, 1.0)) * 0.5;\n\treturn out;\n}\n\n@fragment\nfn motiongpuBlitFragment(in: MotionGPUVertexOut) -> @location(0) vec4f {\n\treturn textureSample(motiongpuBlitTexture, motiongpuBlitSampler, in.uv);\n}\n`;\n\nexport type BlitPassOptions = FullscreenPassOptions;\n\n/**\n * Fullscreen texture blit pass.\n */\nexport class BlitPass extends FullscreenPass {\n\tprotected getProgram(): string {\n\t\treturn FULLSCREEN_BLIT_SHADER;\n\t}\n\n\tconstructor(options: BlitPassOptions = {}) {\n\t\tsuper(options);\n\t}\n\n\tprotected getVertexEntryPoint(): string {\n\t\treturn 'motiongpuBlitVertex';\n\t}\n\n\tprotected getFragmentEntryPoint(): string {\n\t\treturn 'motiongpuBlitFragment';\n\t}\n}\n"],"mappings":";;AAEA,IAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmC/B,IAAa,WAAb,cAA8B,eAAe;CAC5C,aAA+B;AAC9B,SAAO;;CAGR,YAAY,UAA2B,EAAE,EAAE;AAC1C,QAAM,QAAQ;;CAGf,sBAAwC;AACvC,SAAO;;CAGR,wBAA0C;AACzC,SAAO"}
@@ -1,3 +1,4 @@
1
+ /// <reference types="@webgpu/types" />
1
2
  import type { RenderPass, RenderPassContext, RenderPassFlags, RenderPassInputSlot, RenderPassOutputSlot } from '../core/types.js';
2
3
  export interface CopyPassOptions extends RenderPassFlags {
3
4
  enabled?: boolean;
@@ -23,3 +24,4 @@ export declare class CopyPass implements RenderPass {
23
24
  render(context: RenderPassContext): void;
24
25
  dispose(): void;
25
26
  }
27
+ //# sourceMappingURL=CopyPass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CopyPass.d.ts","sourceRoot":"","sources":["../../src/lib/passes/CopyPass.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EACX,UAAU,EACV,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,MAAM,kBAAkB,CAAC;AAG1B,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACvD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,QAAS,YAAW,UAAU;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;gBAE5B,OAAO,GAAE,eAAoB;IAiBzC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAI5C,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAyBxC,OAAO,IAAI,IAAI;CAGf"}
@@ -1,53 +1,59 @@
1
- import { BlitPass } from './BlitPass.js';
1
+ import { BlitPass } from "./BlitPass.js";
2
+ //#region src/lib/passes/CopyPass.ts
2
3
  /**
3
- * Texture copy pass with fullscreen-blit fallback.
4
- */
5
- export class CopyPass {
6
- enabled;
7
- needsSwap;
8
- input;
9
- output;
10
- clear;
11
- clearColor;
12
- preserve;
13
- fallbackBlit;
14
- constructor(options = {}) {
15
- this.enabled = options.enabled ?? true;
16
- this.needsSwap = options.needsSwap ?? true;
17
- this.input = options.input ?? 'source';
18
- this.output = options.output ?? (this.needsSwap ? 'target' : 'source');
19
- this.clear = options.clear ?? false;
20
- this.clearColor = options.clearColor ?? [0, 0, 0, 1];
21
- this.preserve = options.preserve ?? true;
22
- this.fallbackBlit = new BlitPass({
23
- enabled: true,
24
- needsSwap: false,
25
- input: this.input,
26
- output: this.output,
27
- ...(options.filter !== undefined ? { filter: options.filter } : {})
28
- });
29
- }
30
- setSize(width, height) {
31
- this.fallbackBlit.setSize(width, height);
32
- }
33
- render(context) {
34
- const source = context.input;
35
- const target = context.output;
36
- const canDirectCopy = context.clear === false &&
37
- context.preserve === true &&
38
- source.texture !== target.texture &&
39
- source.texture !== context.canvas.texture &&
40
- target.texture !== context.canvas.texture &&
41
- source.width === target.width &&
42
- source.height === target.height &&
43
- source.format === target.format;
44
- if (canDirectCopy) {
45
- context.commandEncoder.copyTextureToTexture({ texture: source.texture }, { texture: target.texture }, { width: source.width, height: source.height, depthOrArrayLayers: 1 });
46
- return;
47
- }
48
- this.fallbackBlit.render(context);
49
- }
50
- dispose() {
51
- this.fallbackBlit.dispose();
52
- }
53
- }
4
+ * Texture copy pass with fullscreen-blit fallback.
5
+ */
6
+ var CopyPass = class {
7
+ enabled;
8
+ needsSwap;
9
+ input;
10
+ output;
11
+ clear;
12
+ clearColor;
13
+ preserve;
14
+ fallbackBlit;
15
+ constructor(options = {}) {
16
+ this.enabled = options.enabled ?? true;
17
+ this.needsSwap = options.needsSwap ?? true;
18
+ this.input = options.input ?? "source";
19
+ this.output = options.output ?? (this.needsSwap ? "target" : "source");
20
+ this.clear = options.clear ?? false;
21
+ this.clearColor = options.clearColor ?? [
22
+ 0,
23
+ 0,
24
+ 0,
25
+ 1
26
+ ];
27
+ this.preserve = options.preserve ?? true;
28
+ this.fallbackBlit = new BlitPass({
29
+ enabled: true,
30
+ needsSwap: false,
31
+ input: this.input,
32
+ output: this.output,
33
+ ...options.filter !== void 0 ? { filter: options.filter } : {}
34
+ });
35
+ }
36
+ setSize(width, height) {
37
+ this.fallbackBlit.setSize(width, height);
38
+ }
39
+ render(context) {
40
+ const source = context.input;
41
+ const target = context.output;
42
+ if (context.clear === false && context.preserve === true && source.texture !== target.texture && source.texture !== context.canvas.texture && target.texture !== context.canvas.texture && source.width === target.width && source.height === target.height && source.format === target.format) {
43
+ context.commandEncoder.copyTextureToTexture({ texture: source.texture }, { texture: target.texture }, {
44
+ width: source.width,
45
+ height: source.height,
46
+ depthOrArrayLayers: 1
47
+ });
48
+ return;
49
+ }
50
+ this.fallbackBlit.render(context);
51
+ }
52
+ dispose() {
53
+ this.fallbackBlit.dispose();
54
+ }
55
+ };
56
+ //#endregion
57
+ export { CopyPass };
58
+
59
+ //# sourceMappingURL=CopyPass.js.map