@motion-core/motion-gpu 0.4.2 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +99 -0
  2. package/dist/advanced.js +3 -1
  3. package/dist/core/advanced.js +3 -1
  4. package/dist/core/compute-bindgroup-cache.d.ts +13 -0
  5. package/dist/core/compute-bindgroup-cache.d.ts.map +1 -0
  6. package/dist/core/compute-bindgroup-cache.js +45 -0
  7. package/dist/core/compute-bindgroup-cache.js.map +1 -0
  8. package/dist/core/compute-shader.d.ts +135 -0
  9. package/dist/core/compute-shader.d.ts.map +1 -0
  10. package/dist/core/compute-shader.js +238 -0
  11. package/dist/core/compute-shader.js.map +1 -0
  12. package/dist/core/error-diagnostics.d.ts +8 -1
  13. package/dist/core/error-diagnostics.d.ts.map +1 -1
  14. package/dist/core/error-diagnostics.js +7 -3
  15. package/dist/core/error-diagnostics.js.map +1 -1
  16. package/dist/core/error-report.d.ts +1 -1
  17. package/dist/core/error-report.d.ts.map +1 -1
  18. package/dist/core/error-report.js +82 -1
  19. package/dist/core/error-report.js.map +1 -1
  20. package/dist/core/frame-registry.d.ts.map +1 -1
  21. package/dist/core/frame-registry.js +1 -1
  22. package/dist/core/frame-registry.js.map +1 -1
  23. package/dist/core/index.d.ts +5 -2
  24. package/dist/core/index.d.ts.map +1 -1
  25. package/dist/core/index.js +3 -1
  26. package/dist/core/material-preprocess.d.ts.map +1 -1
  27. package/dist/core/material-preprocess.js +5 -3
  28. package/dist/core/material-preprocess.js.map +1 -1
  29. package/dist/core/material.d.ts +22 -6
  30. package/dist/core/material.d.ts.map +1 -1
  31. package/dist/core/material.js +32 -4
  32. package/dist/core/material.js.map +1 -1
  33. package/dist/core/render-graph.d.ts +7 -3
  34. package/dist/core/render-graph.d.ts.map +1 -1
  35. package/dist/core/render-graph.js +22 -6
  36. package/dist/core/render-graph.js.map +1 -1
  37. package/dist/core/renderer.d.ts.map +1 -1
  38. package/dist/core/renderer.js +489 -29
  39. package/dist/core/renderer.js.map +1 -1
  40. package/dist/core/runtime-loop.d.ts +2 -2
  41. package/dist/core/runtime-loop.d.ts.map +1 -1
  42. package/dist/core/runtime-loop.js +74 -14
  43. package/dist/core/runtime-loop.js.map +1 -1
  44. package/dist/core/shader.d.ts +16 -3
  45. package/dist/core/shader.d.ts.map +1 -1
  46. package/dist/core/shader.js +22 -2
  47. package/dist/core/shader.js.map +1 -1
  48. package/dist/core/storage-buffers.d.ts +37 -0
  49. package/dist/core/storage-buffers.d.ts.map +1 -0
  50. package/dist/core/storage-buffers.js +95 -0
  51. package/dist/core/storage-buffers.js.map +1 -0
  52. package/dist/core/texture-loader.d.ts.map +1 -1
  53. package/dist/core/texture-loader.js +4 -0
  54. package/dist/core/texture-loader.js.map +1 -1
  55. package/dist/core/textures.d.ts +16 -0
  56. package/dist/core/textures.d.ts.map +1 -1
  57. package/dist/core/textures.js +8 -2
  58. package/dist/core/textures.js.map +1 -1
  59. package/dist/core/types.d.ts +146 -4
  60. package/dist/core/types.d.ts.map +1 -1
  61. package/dist/index.js +3 -1
  62. package/dist/passes/ComputePass.d.ts +83 -0
  63. package/dist/passes/ComputePass.d.ts.map +1 -0
  64. package/dist/passes/ComputePass.js +92 -0
  65. package/dist/passes/ComputePass.js.map +1 -0
  66. package/dist/passes/PingPongComputePass.d.ts +104 -0
  67. package/dist/passes/PingPongComputePass.d.ts.map +1 -0
  68. package/dist/passes/PingPongComputePass.js +132 -0
  69. package/dist/passes/PingPongComputePass.js.map +1 -0
  70. package/dist/passes/ShaderPass.d.ts.map +1 -1
  71. package/dist/passes/ShaderPass.js +2 -1
  72. package/dist/passes/ShaderPass.js.map +1 -1
  73. package/dist/passes/index.d.ts +2 -0
  74. package/dist/passes/index.d.ts.map +1 -1
  75. package/dist/passes/index.js +3 -1
  76. package/dist/react/FragCanvas.d.ts +2 -2
  77. package/dist/react/FragCanvas.d.ts.map +1 -1
  78. package/dist/react/FragCanvas.js.map +1 -1
  79. package/dist/react/MotionGPUErrorOverlay.d.ts.map +1 -1
  80. package/dist/react/MotionGPUErrorOverlay.js +123 -20
  81. package/dist/react/MotionGPUErrorOverlay.js.map +1 -1
  82. package/dist/react/advanced.js +3 -1
  83. package/dist/react/index.d.ts +5 -2
  84. package/dist/react/index.d.ts.map +1 -1
  85. package/dist/react/index.js +3 -1
  86. package/dist/svelte/FragCanvas.svelte +2 -2
  87. package/dist/svelte/FragCanvas.svelte.d.ts +2 -2
  88. package/dist/svelte/FragCanvas.svelte.d.ts.map +1 -1
  89. package/dist/svelte/MotionGPUErrorOverlay.svelte +137 -7
  90. package/dist/svelte/MotionGPUErrorOverlay.svelte.d.ts.map +1 -1
  91. package/dist/svelte/advanced.js +3 -1
  92. package/dist/svelte/index.d.ts +5 -2
  93. package/dist/svelte/index.d.ts.map +1 -1
  94. package/dist/svelte/index.js +3 -1
  95. package/package.json +1 -1
  96. package/src/lib/core/compute-bindgroup-cache.ts +73 -0
  97. package/src/lib/core/compute-shader.ts +412 -0
  98. package/src/lib/core/error-diagnostics.ts +29 -4
  99. package/src/lib/core/error-report.ts +155 -1
  100. package/src/lib/core/frame-registry.ts +2 -1
  101. package/src/lib/core/index.ts +18 -1
  102. package/src/lib/core/material-preprocess.ts +17 -6
  103. package/src/lib/core/material.ts +103 -21
  104. package/src/lib/core/render-graph.ts +39 -9
  105. package/src/lib/core/renderer.ts +768 -48
  106. package/src/lib/core/runtime-loop.ts +116 -16
  107. package/src/lib/core/shader.ts +58 -4
  108. package/src/lib/core/storage-buffers.ts +142 -0
  109. package/src/lib/core/texture-loader.ts +6 -0
  110. package/src/lib/core/textures.ts +29 -2
  111. package/src/lib/core/types.ts +165 -4
  112. package/src/lib/passes/ComputePass.ts +136 -0
  113. package/src/lib/passes/PingPongComputePass.ts +180 -0
  114. package/src/lib/passes/ShaderPass.ts +2 -1
  115. package/src/lib/passes/index.ts +6 -0
  116. package/src/lib/react/FragCanvas.tsx +3 -3
  117. package/src/lib/react/MotionGPUErrorOverlay.tsx +137 -5
  118. package/src/lib/react/index.ts +18 -1
  119. package/src/lib/svelte/FragCanvas.svelte +2 -2
  120. package/src/lib/svelte/MotionGPUErrorOverlay.svelte +137 -7
  121. package/src/lib/svelte/index.ts +18 -1
@@ -75,6 +75,19 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
75
75
  border-bottom: 1px solid var(--motiongpu-color-border);
76
76
  }
77
77
 
78
+ .motiongpu-error-header-top {
79
+ display: flex;
80
+ align-items: flex-start;
81
+ gap: 0.75rem;
82
+ }
83
+
84
+ .motiongpu-error-badges {
85
+ display: inline-flex;
86
+ align-items: center;
87
+ gap: 0.4rem;
88
+ flex-wrap: wrap;
89
+ }
90
+
78
91
  .motiongpu-error-badge-wrap {
79
92
  display: inline-flex;
80
93
  align-items: center;
@@ -86,7 +99,7 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
86
99
  background: var(--motiongpu-color-background-muted);
87
100
  }
88
101
 
89
- .motiongpu-error-phase {
102
+ .motiongpu-error-badge {
90
103
  display: inline-flex;
91
104
  align-items: center;
92
105
  margin: 0;
@@ -106,6 +119,20 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
106
119
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24);
107
120
  }
108
121
 
122
+ .motiongpu-error-recoverable {
123
+ margin: 0;
124
+ font-size: 0.67rem;
125
+ line-height: 1.2;
126
+ letter-spacing: 0.06em;
127
+ text-transform: uppercase;
128
+ color: var(--motiongpu-color-foreground-muted);
129
+ }
130
+
131
+ .motiongpu-error-recoverable span {
132
+ font-family: var(--motiongpu-font-mono);
133
+ color: var(--motiongpu-color-foreground);
134
+ }
135
+
109
136
  .motiongpu-error-title {
110
137
  margin: 0;
111
138
  font-size: clamp(1.02rem, 1vw + 0.72rem, 1.32rem);
@@ -285,6 +312,11 @@ const MOTIONGPU_ERROR_OVERLAY_STYLES = `
285
312
  .motiongpu-error-title {
286
313
  font-size: 1.02rem;
287
314
  }
315
+
316
+ .motiongpu-error-header-top {
317
+ flex-direction: column;
318
+ align-items: flex-start;
319
+ }
288
320
  }
289
321
 
290
322
  @media (prefers-reduced-motion: reduce) {
@@ -302,7 +334,87 @@ function normalizeErrorText(value: string): string {
302
334
  }
303
335
 
304
336
  function shouldShowErrorMessage(value: MotionGPUErrorReport): boolean {
305
- return normalizeErrorText(value.message) !== normalizeErrorText(value.title);
337
+ return resolveDisplayMessage(value).length > 0;
338
+ }
339
+
340
+ function resolveDisplayMessage(value: MotionGPUErrorReport): string {
341
+ const rawMessage = value.message.trim();
342
+ if (rawMessage.length === 0) {
343
+ return '';
344
+ }
345
+
346
+ const normalizedMessage = normalizeErrorText(rawMessage);
347
+ const normalizedTitle = normalizeErrorText(value.title);
348
+ if (normalizedMessage === normalizedTitle) {
349
+ return '';
350
+ }
351
+
352
+ const escapedTitle = value.title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
353
+ const prefixPattern = new RegExp(`^${escapedTitle}\\s*[:\\-|]\\s*`, 'i');
354
+ const stripped = rawMessage.replace(prefixPattern, '').trim();
355
+ return stripped.length > 0 ? stripped : rawMessage;
356
+ }
357
+
358
+ function formatRuntimeContext(context: MotionGPUErrorReport['context']): string {
359
+ if (!context) {
360
+ return '';
361
+ }
362
+
363
+ const indentBlock = (value: string, spaces = 2): string => {
364
+ const prefix = ' '.repeat(spaces);
365
+ return value
366
+ .split('\n')
367
+ .map((line) => `${prefix}${line}`)
368
+ .join('\n');
369
+ };
370
+
371
+ const formatMaterialSignature = (value: string): string => {
372
+ const trimmed = value.trim();
373
+ if (trimmed.length === 0) {
374
+ return '<empty>';
375
+ }
376
+ try {
377
+ return JSON.stringify(JSON.parse(trimmed), null, 2);
378
+ } catch {
379
+ return trimmed;
380
+ }
381
+ };
382
+
383
+ const lines: string[] = [];
384
+ if (context.materialSignature) {
385
+ lines.push('materialSignature:');
386
+ lines.push(indentBlock(formatMaterialSignature(context.materialSignature)));
387
+ }
388
+ if (context.passGraph) {
389
+ lines.push('passGraph:');
390
+ lines.push(` passCount: ${context.passGraph.passCount}`);
391
+ lines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);
392
+ lines.push(' inputs:');
393
+ if (context.passGraph.inputs.length === 0) {
394
+ lines.push(' - <none>');
395
+ } else {
396
+ for (const input of context.passGraph.inputs) {
397
+ lines.push(` - ${input}`);
398
+ }
399
+ }
400
+ lines.push(' outputs:');
401
+ if (context.passGraph.outputs.length === 0) {
402
+ lines.push(' - <none>');
403
+ } else {
404
+ for (const output of context.passGraph.outputs) {
405
+ lines.push(` - ${output}`);
406
+ }
407
+ }
408
+ }
409
+ lines.push('activeRenderTargets:');
410
+ if (context.activeRenderTargets.length === 0) {
411
+ lines.push(' - <none>');
412
+ } else {
413
+ for (const target of context.activeRenderTargets) {
414
+ lines.push(` - ${target}`);
415
+ }
416
+ }
417
+ return lines.join('\n');
306
418
  }
307
419
 
308
420
  export function MotionGPUErrorOverlay({ report }: MotionGPUErrorOverlayProps) {
@@ -320,14 +432,28 @@ export function MotionGPUErrorOverlay({ report }: MotionGPUErrorOverlayProps) {
320
432
  data-testid="motiongpu-error"
321
433
  >
322
434
  <header className="motiongpu-error-header">
323
- <div className="motiongpu-error-badge-wrap">
324
- <p className="motiongpu-error-phase">{report.phase}</p>
435
+ <div className="motiongpu-error-header-top">
436
+ <div className="motiongpu-error-badges">
437
+ <div className="motiongpu-error-badge-wrap">
438
+ <p className="motiongpu-error-badge motiongpu-error-badge-phase">
439
+ {report.phase}
440
+ </p>
441
+ </div>
442
+ <div className="motiongpu-error-badge-wrap">
443
+ <p className="motiongpu-error-badge motiongpu-error-badge-severity">
444
+ {report.severity}
445
+ </p>
446
+ </div>
447
+ </div>
325
448
  </div>
326
449
  <h2 className="motiongpu-error-title">{report.title}</h2>
450
+ <p className="motiongpu-error-recoverable">
451
+ Recoverable: <span>{report.recoverable ? 'yes' : 'no'}</span>
452
+ </p>
327
453
  </header>
328
454
  <div className="motiongpu-error-body">
329
455
  {shouldShowErrorMessage(report) ? (
330
- <p className="motiongpu-error-message">{report.message}</p>
456
+ <p className="motiongpu-error-message">{resolveDisplayMessage(report)}</p>
331
457
  ) : null}
332
458
  <p className="motiongpu-error-hint">{report.hint}</p>
333
459
  </div>
@@ -384,6 +510,12 @@ export function MotionGPUErrorOverlay({ report }: MotionGPUErrorOverlayProps) {
384
510
  <pre>{report.stack.join('\n')}</pre>
385
511
  </details>
386
512
  ) : null}
513
+ {report.context ? (
514
+ <details className="motiongpu-error-details">
515
+ <summary>Runtime context</summary>
516
+ <pre>{formatRuntimeContext(report.context)}</pre>
517
+ </details>
518
+ ) : null}
387
519
  </div>
388
520
  </section>
389
521
  </div>
@@ -3,7 +3,13 @@
3
3
  */
4
4
  export { FragCanvas } from './FragCanvas.js';
5
5
  export { defineMaterial } from '../core/material.js';
6
- export { BlitPass, CopyPass, ShaderPass } from '../passes/index.js';
6
+ export {
7
+ BlitPass,
8
+ CopyPass,
9
+ ShaderPass,
10
+ ComputePass,
11
+ PingPongComputePass
12
+ } from '../passes/index.js';
7
13
  export { useMotionGPU } from './motiongpu-context.js';
8
14
  export { useFrame } from './frame-context.js';
9
15
  export { useTexture } from './use-texture.js';
@@ -11,6 +17,8 @@ export type {
11
17
  FrameInvalidationToken,
12
18
  FrameState,
13
19
  OutputColorSpace,
20
+ AnyPass,
21
+ ComputePassLike,
14
22
  RenderPass,
15
23
  RenderPassContext,
16
24
  RenderPassFlags,
@@ -49,3 +57,12 @@ export type {
49
57
  export type { MotionGPUContext } from './motiongpu-context.js';
50
58
  export type { UseFrameOptions, UseFrameResult } from './frame-context.js';
51
59
  export type { TextureUrlInput, UseTextureResult } from './use-texture.js';
60
+ export type {
61
+ StorageBufferAccess,
62
+ StorageBufferDefinition,
63
+ StorageBufferDefinitionMap,
64
+ StorageBufferType,
65
+ ComputePassContext
66
+ } from '../core/types.js';
67
+ export type { ComputePassOptions, ComputeDispatchContext } from '../passes/ComputePass.js';
68
+ export type { PingPongComputePassOptions } from '../passes/PingPongComputePass.js';
@@ -7,9 +7,9 @@
7
7
  import MotionGPUErrorOverlay from './MotionGPUErrorOverlay.svelte';
8
8
  import { createMotionGPURuntimeLoop } from '../core/runtime-loop';
9
9
  import type {
10
+ AnyPass,
10
11
  FrameInvalidationToken,
11
12
  OutputColorSpace,
12
- RenderPass,
13
13
  RenderMode,
14
14
  RenderTargetDefinitionMap
15
15
  } from '../core/types';
@@ -19,7 +19,7 @@
19
19
  interface Props {
20
20
  material: FragMaterial;
21
21
  renderTargets?: RenderTargetDefinitionMap;
22
- passes?: RenderPass[];
22
+ passes?: AnyPass[];
23
23
  clearColor?: [number, number, number, number];
24
24
  outputColorSpace?: OutputColorSpace;
25
25
  renderMode?: RenderMode;
@@ -16,7 +16,87 @@
16
16
  };
17
17
 
18
18
  const shouldShowErrorMessage = (value: MotionGPUErrorReport): boolean => {
19
- return normalizeErrorText(value.message) !== normalizeErrorText(value.title);
19
+ return resolveDisplayMessage(value).length > 0;
20
+ };
21
+
22
+ const resolveDisplayMessage = (value: MotionGPUErrorReport): string => {
23
+ const rawMessage = value.message.trim();
24
+ if (rawMessage.length === 0) {
25
+ return '';
26
+ }
27
+
28
+ const normalizedMessage = normalizeErrorText(rawMessage);
29
+ const normalizedTitle = normalizeErrorText(value.title);
30
+ if (normalizedMessage === normalizedTitle) {
31
+ return '';
32
+ }
33
+
34
+ const escapedTitle = value.title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
35
+ const prefixPattern = new RegExp(`^${escapedTitle}\\s*[:\\-|]\\s*`, 'i');
36
+ const stripped = rawMessage.replace(prefixPattern, '').trim();
37
+ return stripped.length > 0 ? stripped : rawMessage;
38
+ };
39
+
40
+ const formatRuntimeContext = (context: MotionGPUErrorReport['context']): string => {
41
+ if (!context) {
42
+ return '';
43
+ }
44
+
45
+ const indentBlock = (value: string, spaces = 2): string => {
46
+ const prefix = ' '.repeat(spaces);
47
+ return value
48
+ .split('\n')
49
+ .map((line) => `${prefix}${line}`)
50
+ .join('\n');
51
+ };
52
+
53
+ const formatMaterialSignature = (value: string): string => {
54
+ const trimmed = value.trim();
55
+ if (trimmed.length === 0) {
56
+ return '<empty>';
57
+ }
58
+ try {
59
+ return JSON.stringify(JSON.parse(trimmed), null, 2);
60
+ } catch {
61
+ return trimmed;
62
+ }
63
+ };
64
+
65
+ const lines: string[] = [];
66
+ if (context.materialSignature) {
67
+ lines.push('materialSignature:');
68
+ lines.push(indentBlock(formatMaterialSignature(context.materialSignature)));
69
+ }
70
+ if (context.passGraph) {
71
+ lines.push('passGraph:');
72
+ lines.push(` passCount: ${context.passGraph.passCount}`);
73
+ lines.push(` enabledPassCount: ${context.passGraph.enabledPassCount}`);
74
+ lines.push(' inputs:');
75
+ if (context.passGraph.inputs.length === 0) {
76
+ lines.push(' - <none>');
77
+ } else {
78
+ for (const input of context.passGraph.inputs) {
79
+ lines.push(` - ${input}`);
80
+ }
81
+ }
82
+ lines.push(' outputs:');
83
+ if (context.passGraph.outputs.length === 0) {
84
+ lines.push(' - <none>');
85
+ } else {
86
+ for (const output of context.passGraph.outputs) {
87
+ lines.push(` - ${output}`);
88
+ }
89
+ }
90
+ }
91
+ lines.push('activeRenderTargets:');
92
+ if (context.activeRenderTargets.length === 0) {
93
+ lines.push(' - <none>');
94
+ } else {
95
+ for (const target of context.activeRenderTargets) {
96
+ lines.push(` - ${target}`);
97
+ }
98
+ }
99
+ return lines.join('\n');
20
100
  };
21
101
  </script>
22
102
 
@@ -30,16 +110,28 @@
30
110
  data-testid="motiongpu-error"
31
111
  >
32
112
  <header class="motiongpu-error-header">
33
- <div class="motiongpu-error-badge-wrap">
34
- <p class="motiongpu-error-phase">
35
- {report.phase}
36
- </p>
113
+ <div class="motiongpu-error-header-top">
114
+ <div class="motiongpu-error-badges">
115
+ <div class="motiongpu-error-badge-wrap">
116
+ <p class="motiongpu-error-badge motiongpu-error-badge-phase">
117
+ {report.phase}
118
+ </p>
119
+ </div>
120
+ <div class="motiongpu-error-badge-wrap">
121
+ <p class="motiongpu-error-badge motiongpu-error-badge-severity">
122
+ {report.severity}
123
+ </p>
124
+ </div>
125
+ </div>
37
126
  </div>
38
127
  <h2 class="motiongpu-error-title">{report.title}</h2>
128
+ <p class="motiongpu-error-recoverable">
129
+ Recoverable: <span>{report.recoverable ? 'yes' : 'no'}</span>
130
+ </p>
39
131
  </header>
40
132
  <div class="motiongpu-error-body">
41
133
  {#if shouldShowErrorMessage(report)}
42
- <p class="motiongpu-error-message">{report.message}</p>
134
+ <p class="motiongpu-error-message">{resolveDisplayMessage(report)}</p>
43
135
  {/if}
44
136
  <p class="motiongpu-error-hint">{report.hint}</p>
45
137
  </div>
@@ -87,6 +179,12 @@
87
179
  <pre>{report.stack.join('\n')}</pre>
88
180
  </details>
89
181
  {/if}
182
+ {#if report.context}
183
+ <details class="motiongpu-error-details">
184
+ <summary>Runtime context</summary>
185
+ <pre>{formatRuntimeContext(report.context)}</pre>
186
+ </details>
187
+ {/if}
90
188
  </div>
91
189
  </section>
92
190
  </div>
@@ -162,6 +260,19 @@
162
260
  border-bottom: 1px solid var(--motiongpu-color-border);
163
261
  }
164
262
 
263
+ .motiongpu-error-header-top {
264
+ display: flex;
265
+ align-items: flex-start;
266
+ gap: 0.75rem;
267
+ }
268
+
269
+ .motiongpu-error-badges {
270
+ display: inline-flex;
271
+ align-items: center;
272
+ gap: 0.4rem;
273
+ flex-wrap: wrap;
274
+ }
275
+
165
276
  .motiongpu-error-badge-wrap {
166
277
  display: inline-flex;
167
278
  align-items: center;
@@ -173,7 +284,7 @@
173
284
  background: var(--motiongpu-color-background-muted);
174
285
  }
175
286
 
176
- .motiongpu-error-phase {
287
+ .motiongpu-error-badge {
177
288
  display: inline-flex;
178
289
  align-items: center;
179
290
  margin: 0;
@@ -193,6 +304,20 @@
193
304
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.24);
194
305
  }
195
306
 
307
+ .motiongpu-error-recoverable {
308
+ margin: 0;
309
+ font-size: 0.67rem;
310
+ line-height: 1.2;
311
+ letter-spacing: 0.06em;
312
+ text-transform: uppercase;
313
+ color: var(--motiongpu-color-foreground-muted);
314
+ }
315
+
316
+ .motiongpu-error-recoverable span {
317
+ font-family: var(--motiongpu-font-mono);
318
+ color: var(--motiongpu-color-foreground);
319
+ }
320
+
196
321
  .motiongpu-error-title {
197
322
  margin: 0;
198
323
  font-size: clamp(1.02rem, 1vw + 0.72rem, 1.32rem);
@@ -372,6 +497,11 @@
372
497
  .motiongpu-error-title {
373
498
  font-size: 1.02rem;
374
499
  }
500
+
501
+ .motiongpu-error-header-top {
502
+ flex-direction: column;
503
+ align-items: flex-start;
504
+ }
375
505
  }
376
506
 
377
507
  @media (prefers-reduced-motion: reduce) {
@@ -3,7 +3,13 @@
3
3
  */
4
4
  export { default as FragCanvas } from './FragCanvas.svelte';
5
5
  export { defineMaterial } from '../core/material.js';
6
- export { BlitPass, CopyPass, ShaderPass } from '../passes/index.js';
6
+ export {
7
+ BlitPass,
8
+ CopyPass,
9
+ ShaderPass,
10
+ ComputePass,
11
+ PingPongComputePass
12
+ } from '../passes/index.js';
7
13
  export { useMotionGPU } from './motiongpu-context.js';
8
14
  export { useFrame } from './frame-context.js';
9
15
  export { useTexture } from './use-texture.js';
@@ -11,6 +17,8 @@ export type {
11
17
  FrameInvalidationToken,
12
18
  FrameState,
13
19
  OutputColorSpace,
20
+ AnyPass,
21
+ ComputePassLike,
14
22
  RenderPass,
15
23
  RenderPassContext,
16
24
  RenderPassFlags,
@@ -49,3 +57,12 @@ export type {
49
57
  export type { MotionGPUContext } from './motiongpu-context.js';
50
58
  export type { UseFrameOptions, UseFrameResult } from './frame-context.js';
51
59
  export type { TextureUrlInput, UseTextureResult } from './use-texture.js';
60
+ export type {
61
+ StorageBufferAccess,
62
+ StorageBufferDefinition,
63
+ StorageBufferDefinitionMap,
64
+ StorageBufferType,
65
+ ComputePassContext
66
+ } from '../core/types.js';
67
+ export type { ComputePassOptions, ComputeDispatchContext } from '../passes/ComputePass.js';
68
+ export type { PingPongComputePassOptions } from '../passes/PingPongComputePass.js';