@flighthq/displayobject-wgpu 0.1.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 (144) hide show
  1. package/dist/index.d.ts +29 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +29 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/moduleMockTestHelper.d.ts +15 -0
  6. package/dist/moduleMockTestHelper.d.ts.map +1 -0
  7. package/dist/moduleMockTestHelper.js +25 -0
  8. package/dist/moduleMockTestHelper.js.map +1 -0
  9. package/dist/wgpuBitmap.d.ts +4 -0
  10. package/dist/wgpuBitmap.d.ts.map +1 -0
  11. package/dist/wgpuBitmap.js +80 -0
  12. package/dist/wgpuBitmap.js.map +1 -0
  13. package/dist/wgpuCache.d.ts +31 -0
  14. package/dist/wgpuCache.d.ts.map +1 -0
  15. package/dist/wgpuCache.js +232 -0
  16. package/dist/wgpuCache.js.map +1 -0
  17. package/dist/wgpuClip.d.ts +3 -0
  18. package/dist/wgpuClip.d.ts.map +1 -0
  19. package/dist/wgpuClip.js +44 -0
  20. package/dist/wgpuClip.js.map +1 -0
  21. package/dist/wgpuClipContours.d.ts +4 -0
  22. package/dist/wgpuClipContours.d.ts.map +1 -0
  23. package/dist/wgpuClipContours.js +174 -0
  24. package/dist/wgpuClipContours.js.map +1 -0
  25. package/dist/wgpuClipRectangle.d.ts +4 -0
  26. package/dist/wgpuClipRectangle.d.ts.map +1 -0
  27. package/dist/wgpuClipRectangle.js +80 -0
  28. package/dist/wgpuClipRectangle.js.map +1 -0
  29. package/dist/wgpuColorTransformMaterial.d.ts +5 -0
  30. package/dist/wgpuColorTransformMaterial.d.ts.map +1 -0
  31. package/dist/wgpuColorTransformMaterial.js +97 -0
  32. package/dist/wgpuColorTransformMaterial.js.map +1 -0
  33. package/dist/wgpuDefaultMaterial.d.ts +4 -0
  34. package/dist/wgpuDefaultMaterial.d.ts.map +1 -0
  35. package/dist/wgpuDefaultMaterial.js +46 -0
  36. package/dist/wgpuDefaultMaterial.js.map +1 -0
  37. package/dist/wgpuDisplayObject.d.ts +5 -0
  38. package/dist/wgpuDisplayObject.d.ts.map +1 -0
  39. package/dist/wgpuDisplayObject.js +41 -0
  40. package/dist/wgpuDisplayObject.js.map +1 -0
  41. package/dist/wgpuMaterials.d.ts +15 -0
  42. package/dist/wgpuMaterials.d.ts.map +1 -0
  43. package/dist/wgpuMaterials.js +34 -0
  44. package/dist/wgpuMaterials.js.map +1 -0
  45. package/dist/wgpuParticleEmitter.d.ts +4 -0
  46. package/dist/wgpuParticleEmitter.d.ts.map +1 -0
  47. package/dist/wgpuParticleEmitter.js +288 -0
  48. package/dist/wgpuParticleEmitter.js.map +1 -0
  49. package/dist/wgpuQuadBatch.d.ts +7 -0
  50. package/dist/wgpuQuadBatch.d.ts.map +1 -0
  51. package/dist/wgpuQuadBatch.js +85 -0
  52. package/dist/wgpuQuadBatch.js.map +1 -0
  53. package/dist/wgpuRegistration.d.ts +19 -0
  54. package/dist/wgpuRegistration.d.ts.map +1 -0
  55. package/dist/wgpuRegistration.js +53 -0
  56. package/dist/wgpuRegistration.js.map +1 -0
  57. package/dist/wgpuRenderStats.d.ts +20 -0
  58. package/dist/wgpuRenderStats.d.ts.map +1 -0
  59. package/dist/wgpuRenderStats.js +50 -0
  60. package/dist/wgpuRenderStats.js.map +1 -0
  61. package/dist/wgpuRendererData.d.ts +26 -0
  62. package/dist/wgpuRendererData.d.ts.map +1 -0
  63. package/dist/wgpuRendererData.js +29 -0
  64. package/dist/wgpuRendererData.js.map +1 -0
  65. package/dist/wgpuRichText.d.ts +9 -0
  66. package/dist/wgpuRichText.d.ts.map +1 -0
  67. package/dist/wgpuRichText.js +163 -0
  68. package/dist/wgpuRichText.js.map +1 -0
  69. package/dist/wgpuScale9Mapper.d.ts +3 -0
  70. package/dist/wgpuScale9Mapper.d.ts.map +1 -0
  71. package/dist/wgpuScale9Mapper.js +42 -0
  72. package/dist/wgpuScale9Mapper.js.map +1 -0
  73. package/dist/wgpuScale9Shape.d.ts +9 -0
  74. package/dist/wgpuScale9Shape.d.ts.map +1 -0
  75. package/dist/wgpuScale9Shape.js +123 -0
  76. package/dist/wgpuScale9Shape.js.map +1 -0
  77. package/dist/wgpuShape.d.ts +4 -0
  78. package/dist/wgpuShape.d.ts.map +1 -0
  79. package/dist/wgpuShape.js +157 -0
  80. package/dist/wgpuShape.js.map +1 -0
  81. package/dist/wgpuShapeMesh.d.ts +9 -0
  82. package/dist/wgpuShapeMesh.d.ts.map +1 -0
  83. package/dist/wgpuShapeMesh.js +204 -0
  84. package/dist/wgpuShapeMesh.js.map +1 -0
  85. package/dist/wgpuSprite.d.ts +3 -0
  86. package/dist/wgpuSprite.d.ts.map +1 -0
  87. package/dist/wgpuSprite.js +28 -0
  88. package/dist/wgpuSprite.js.map +1 -0
  89. package/dist/wgpuSpriteBatch.d.ts +18 -0
  90. package/dist/wgpuSpriteBatch.d.ts.map +1 -0
  91. package/dist/wgpuSpriteBatch.js +320 -0
  92. package/dist/wgpuSpriteBatch.js.map +1 -0
  93. package/dist/wgpuSpriteRenderer.d.ts +3 -0
  94. package/dist/wgpuSpriteRenderer.d.ts.map +1 -0
  95. package/dist/wgpuSpriteRenderer.js +51 -0
  96. package/dist/wgpuSpriteRenderer.js.map +1 -0
  97. package/dist/wgpuTextInput.d.ts +4 -0
  98. package/dist/wgpuTextInput.d.ts.map +1 -0
  99. package/dist/wgpuTextInput.js +44 -0
  100. package/dist/wgpuTextInput.js.map +1 -0
  101. package/dist/wgpuTextLabel.d.ts +4 -0
  102. package/dist/wgpuTextLabel.d.ts.map +1 -0
  103. package/dist/wgpuTextLabel.js +157 -0
  104. package/dist/wgpuTextLabel.js.map +1 -0
  105. package/dist/wgpuTilemap.d.ts +3 -0
  106. package/dist/wgpuTilemap.d.ts.map +1 -0
  107. package/dist/wgpuTilemap.js +76 -0
  108. package/dist/wgpuTilemap.js.map +1 -0
  109. package/dist/wgpuVelocity.d.ts +23 -0
  110. package/dist/wgpuVelocity.d.ts.map +1 -0
  111. package/dist/wgpuVelocity.js +365 -0
  112. package/dist/wgpuVelocity.js.map +1 -0
  113. package/dist/wgpuVideo.d.ts +6 -0
  114. package/dist/wgpuVideo.d.ts.map +1 -0
  115. package/dist/wgpuVideo.js +63 -0
  116. package/dist/wgpuVideo.js.map +1 -0
  117. package/package.json +52 -0
  118. package/src/wgpuBitmap.test.ts +40 -0
  119. package/src/wgpuCache.test.ts +230 -0
  120. package/src/wgpuClip.test.ts +15 -0
  121. package/src/wgpuClipContours.test.ts +101 -0
  122. package/src/wgpuClipRectangle.test.ts +45 -0
  123. package/src/wgpuColorTransformMaterial.test.ts +62 -0
  124. package/src/wgpuDefaultMaterial.test.ts +21 -0
  125. package/src/wgpuDisplayObject.test.ts +36 -0
  126. package/src/wgpuMaterials.test.ts +44 -0
  127. package/src/wgpuParticleEmitter.test.ts +34 -0
  128. package/src/wgpuQuadBatch.test.ts +69 -0
  129. package/src/wgpuRegistration.test.ts +115 -0
  130. package/src/wgpuRenderStats.test.ts +89 -0
  131. package/src/wgpuRendererData.test.ts +29 -0
  132. package/src/wgpuRichText.test.ts +100 -0
  133. package/src/wgpuScale9Mapper.test.ts +20 -0
  134. package/src/wgpuScale9Shape.test.ts +97 -0
  135. package/src/wgpuShape.test.ts +95 -0
  136. package/src/wgpuShapeMesh.test.ts +124 -0
  137. package/src/wgpuSprite.test.ts +19 -0
  138. package/src/wgpuSpriteBatch.test.ts +180 -0
  139. package/src/wgpuSpriteRenderer.test.ts +38 -0
  140. package/src/wgpuTextInput.test.ts +37 -0
  141. package/src/wgpuTextLabel.test.ts +113 -0
  142. package/src/wgpuTilemap.test.ts +47 -0
  143. package/src/wgpuVelocity.test.ts +147 -0
  144. package/src/wgpuVideo.test.ts +59 -0
@@ -0,0 +1,365 @@
1
+ import { ensureNodeWorldBoundsRectangle, ensureNodeWorldTransformMatrix, getNodeChildAt, getNodeChildCount, getNodeWorldBoundsRectangle, getNodeWorldTransformMatrix, } from '@flighthq/node';
2
+ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
3
+ import { createWgpuRenderTarget } from '@flighthq/render-wgpu';
4
+ import { EntityRuntimeKey } from '@flighthq/types';
5
+ import { getVelocity } from '@flighthq/velocity';
6
+ // Wgpu velocity-buffer production, the mirror of displayobject-gl's webglVelocity. Velocity is tied to the
7
+ // draw, so production is per-kind: the velocity pass walks the scene and dispatches a registered
8
+ // WgpuVelocityWriter for each node's kind, which draws that kind's velocity into the bound rgba16float
9
+ // target. The DisplayObject writer covers a node's world bounds with its (single) velocity; batched kinds
10
+ // register their own writer to emit per-instance velocity. The generic velocity DATA comes from a
11
+ // render-agnostic VelocityField (@flighthq/velocity); this module is only the render-side hook.
12
+ //
13
+ // ENCODING: velocity is written in device pixels per frame (node-unit velocity × pixelRatio), y-down, into
14
+ // R/G of an rgba16float target (signed, sub-pixel). B is reserved; A=1 marks a covered texel so consumers
15
+ // distinguish it from the cleared (0,0,0,0) zero-velocity background. World bounds are device-pixel,
16
+ // top-left origin, y-down; drawWgpuVelocityQuad maps a rect into clip space, flipping y.
17
+ /** Allocates an rgba16float render target sized to hold a signed, sub-pixel screen-space velocity buffer. */
18
+ export function createWgpuVelocityTarget(state, width, height) {
19
+ return createWgpuRenderTarget(state, width, height, 'rgba16float');
20
+ }
21
+ // The default writer for plain display-object nodes: cover the node's world bounds with its velocity.
22
+ // Batched/instanced kinds (QuadBatch, particles) register a writer that emits per-instance velocity.
23
+ export const defaultWgpuDisplayObjectVelocityWriter = (ctx, node) => {
24
+ getVelocity(ctx.field, node, _scratchVelocity);
25
+ if (_scratchVelocity.x === 0 && _scratchVelocity.y === 0)
26
+ return;
27
+ const spatial = node;
28
+ ensureNodeWorldBoundsRectangle(spatial);
29
+ const bounds = getNodeWorldBoundsRectangle(spatial);
30
+ drawWgpuVelocityQuad(ctx, bounds.x, bounds.y, bounds.width, bounds.height, _scratchVelocity.x, _scratchVelocity.y);
31
+ };
32
+ // The ParticleEmitter writer emits PER-PARTICLE velocity: each particle moves on its own vector (a
33
+ // fountain fans outward), so one emitter-wide vector would be wrong — a user who wants the whole emitter
34
+ // to share a velocity attaches it to a parent node, which the DisplayObject writer covers. The per-particle
35
+ // world rect is reconstructed exactly as the particle renderer composes its quad: a [0,1] corner scaled by
36
+ // the atlas region, rotated/scaled by the particle's (cos,sin)·scale and offset by its position, then
37
+ // mapped by the emitter world transform (skipped when worldSpace puts particles in world space already).
38
+ // Velocity stays in node units; drawWgpuVelocityQuad applies pixelRatio (matching the other writers).
39
+ // Skips particles with zero velocity and emitters without a populated velocities array. Mirrors
40
+ // defaultGlParticleEmitterVelocityWriter.
41
+ export const defaultWgpuParticleEmitterVelocityWriter = (ctx, node) => {
42
+ const emitter = node;
43
+ const { atlas, ids, particleCount, transforms, velocities, worldSpace } = emitter.data;
44
+ if (atlas === null || particleCount === 0 || velocities.length < particleCount * 2)
45
+ return;
46
+ const regions = atlas.regions;
47
+ const numRegions = regions.length;
48
+ let wa = 1;
49
+ let wb = 0;
50
+ let wc = 0;
51
+ let wd = 1;
52
+ let wtx = 0;
53
+ let wty = 0;
54
+ if (!worldSpace) {
55
+ ensureNodeWorldTransformMatrix(node);
56
+ const transform = getNodeWorldTransformMatrix(node);
57
+ wa = transform.a;
58
+ wb = transform.b;
59
+ wc = transform.c;
60
+ wd = transform.d;
61
+ wtx = transform.tx;
62
+ wty = transform.ty;
63
+ }
64
+ for (let i = 0; i < particleCount; i++) {
65
+ const velocityX = velocities[i * 2];
66
+ const velocityY = velocities[i * 2 + 1];
67
+ if (velocityX === 0 && velocityY === 0)
68
+ continue;
69
+ const id = ids[i];
70
+ if (id < 0 || id >= numRegions)
71
+ continue;
72
+ const region = regions[id];
73
+ const rw = region.width;
74
+ const rh = region.height;
75
+ if (rw <= 0 || rh <= 0)
76
+ continue;
77
+ const tt = i * 4;
78
+ const px = transforms[tt];
79
+ const py = transforms[tt + 1];
80
+ const rotation = transforms[tt + 2];
81
+ const scale = transforms[tt + 3];
82
+ const cosScale = Math.cos(rotation) * scale;
83
+ const sinScale = Math.sin(rotation) * scale;
84
+ let minX = Infinity;
85
+ let minY = Infinity;
86
+ let maxX = -Infinity;
87
+ let maxY = -Infinity;
88
+ for (let c = 0; c < 4; c++) {
89
+ const lx = (c & 1) * rw;
90
+ const ly = (c >> 1) * rh;
91
+ const rx = cosScale * lx - sinScale * ly + px;
92
+ const ry = sinScale * lx + cosScale * ly + py;
93
+ const wx = worldSpace ? rx : wa * rx + wc * ry + wtx;
94
+ const wy = worldSpace ? ry : wb * rx + wd * ry + wty;
95
+ if (wx < minX)
96
+ minX = wx;
97
+ if (wx > maxX)
98
+ maxX = wx;
99
+ if (wy < minY)
100
+ minY = wy;
101
+ if (wy > maxY)
102
+ maxY = wy;
103
+ }
104
+ drawWgpuVelocityQuad(ctx, minX, minY, maxX - minX, maxY - minY, velocityX, velocityY);
105
+ }
106
+ };
107
+ // The QuadBatch writer emits PER-INSTANCE velocity: a batch's quads move independently and are not nodes,
108
+ // so a single node-level velocity over the whole batch would smear every quad with the same motion vector.
109
+ // When the batch carries a per-instance velocity array (QuadBatchRuntime.instanceVelocities) we draw one
110
+ // velocity quad per instance over that instance's own world-space region, reconstructed exactly as the
111
+ // batch renderer composes it (batch world transform ∘ per-instance local transform, then axis-aligned
112
+ // bounds). Velocity stays in node units; drawWgpuVelocityQuad applies pixelRatio. Fallback: when no
113
+ // per-instance array is present, cover the batch's world bounds with one coarse field velocity, like the
114
+ // DisplayObject writer. Identical math to defaultGlQuadBatchVelocityWriter.
115
+ export const defaultWgpuQuadBatchVelocityWriter = (ctx, node) => {
116
+ const batch = node;
117
+ const data = batch.data;
118
+ const runtime = node[EntityRuntimeKey];
119
+ const instanceVelocities = runtime.instanceVelocities;
120
+ const { atlas, ids, instanceCount, transforms, transformType } = data;
121
+ if (instanceVelocities !== null && atlas !== null && instanceCount > 0) {
122
+ const regions = atlas.regions;
123
+ const numRegions = regions.length;
124
+ ensureNodeWorldTransformMatrix(node);
125
+ const transform = getNodeWorldTransformMatrix(node);
126
+ const pa = transform.a;
127
+ const pb = transform.b;
128
+ const pc = transform.c;
129
+ const pd = transform.d;
130
+ const ptx = transform.tx;
131
+ const pty = transform.ty;
132
+ const isVector2 = transformType === 'vector2';
133
+ for (let i = 0; i < instanceCount; i++) {
134
+ const velocityX = instanceVelocities[i * 2];
135
+ const velocityY = instanceVelocities[i * 2 + 1];
136
+ if (velocityX === 0 && velocityY === 0)
137
+ continue;
138
+ const id = ids[i];
139
+ if (id < 0 || id >= numRegions)
140
+ continue;
141
+ const region = regions[id];
142
+ const w = region.width;
143
+ const h = region.height;
144
+ if (w <= 0 || h <= 0)
145
+ continue;
146
+ let wa;
147
+ let wb;
148
+ let wc;
149
+ let wd;
150
+ let wtx;
151
+ let wty;
152
+ if (isVector2) {
153
+ const dx = transforms[i * 2];
154
+ const dy = transforms[i * 2 + 1];
155
+ wa = pa;
156
+ wb = pb;
157
+ wc = pc;
158
+ wd = pd;
159
+ wtx = pa * dx + pc * dy + ptx;
160
+ wty = pb * dx + pd * dy + pty;
161
+ }
162
+ else {
163
+ const o = i * 6;
164
+ const la = transforms[o];
165
+ const lb = transforms[o + 1];
166
+ const lc = transforms[o + 2];
167
+ const ld = transforms[o + 3];
168
+ const ltx = transforms[o + 4];
169
+ const lty = transforms[o + 5];
170
+ wa = pa * la + pc * lb;
171
+ wb = pb * la + pd * lb;
172
+ wc = pa * lc + pc * ld;
173
+ wd = pb * lc + pd * ld;
174
+ wtx = pa * ltx + pc * lty + ptx;
175
+ wty = pb * ltx + pd * lty + pty;
176
+ }
177
+ const x0 = wtx;
178
+ const y0 = wty;
179
+ const x1 = wa * w + wtx;
180
+ const y1 = wb * w + wty;
181
+ const x2 = wc * h + wtx;
182
+ const y2 = wd * h + wty;
183
+ const x3 = wa * w + wc * h + wtx;
184
+ const y3 = wb * w + wd * h + wty;
185
+ const minX = Math.min(x0, x1, x2, x3);
186
+ const minY = Math.min(y0, y1, y2, y3);
187
+ const maxX = Math.max(x0, x1, x2, x3);
188
+ const maxY = Math.max(y0, y1, y2, y3);
189
+ drawWgpuVelocityQuad(ctx, minX, minY, maxX - minX, maxY - minY, velocityX, velocityY);
190
+ }
191
+ return;
192
+ }
193
+ getVelocity(ctx.field, node, _scratchVelocity);
194
+ if (_scratchVelocity.x === 0 && _scratchVelocity.y === 0)
195
+ return;
196
+ const spatial = node;
197
+ ensureNodeWorldBoundsRectangle(spatial);
198
+ const bounds = getNodeWorldBoundsRectangle(spatial);
199
+ drawWgpuVelocityQuad(ctx, bounds.x, bounds.y, bounds.width, bounds.height, _scratchVelocity.x, _scratchVelocity.y);
200
+ };
201
+ /**
202
+ * Draws one velocity quad: a device-pixel rect (x, y, width, height) filled with (velocityX, velocityY) in
203
+ * node units (scaled by pixelRatio here). The velocity pass must be active — renderWgpuVelocity sets it
204
+ * up before dispatching writers; outside a velocity pass this is a no-op. Each draw consumes one uniform
205
+ * ring slot (clipRect + velocity) addressed by dynamic offset, mirroring the filter-pass ring.
206
+ */
207
+ export function drawWgpuVelocityQuad(ctx, x, y, width, height, velocityX, velocityY) {
208
+ const active = _activeVelocityPasses.get(ctx.state);
209
+ if (active === undefined)
210
+ return;
211
+ const pipeline = active.pipeline;
212
+ const clipX0 = (x / ctx.width) * 2 - 1;
213
+ const clipY0 = 1 - (y / ctx.height) * 2;
214
+ const clipWidth = (width / ctx.width) * 2;
215
+ const clipHeight = -((height / ctx.height) * 2);
216
+ const slot = pipeline.cursor;
217
+ pipeline.cursor = (slot + UNIFORM_STRIDE) % (UNIFORM_SLOTS * UNIFORM_STRIDE);
218
+ const scratch = pipeline.scratch;
219
+ scratch[0] = clipX0;
220
+ scratch[1] = clipY0;
221
+ scratch[2] = clipWidth;
222
+ scratch[3] = clipHeight;
223
+ scratch[4] = velocityX * ctx.pixelRatio;
224
+ scratch[5] = velocityY * ctx.pixelRatio;
225
+ ctx.state.device.queue.writeBuffer(pipeline.uniformBuffer, slot, scratch.buffer, 0, UNIFORM_BYTES);
226
+ active.pass.setBindGroup(0, pipeline.bindGroup, [slot]);
227
+ active.pass.draw(6);
228
+ }
229
+ export function getWgpuVelocityWriter(state, kind) {
230
+ return _velocityWriters.get(state)?.get(kind) ?? null;
231
+ }
232
+ export function registerWgpuVelocityWriter(state, kind, writer) {
233
+ let writers = _velocityWriters.get(state);
234
+ if (writers === undefined) {
235
+ writers = new Map();
236
+ _velocityWriters.set(state, writers);
237
+ }
238
+ writers.set(kind, writer);
239
+ }
240
+ /**
241
+ * Walks `root`'s subtree and writes every moving renderable's velocity into `target`, dispatching the
242
+ * registered WgpuVelocityWriter for each node's kind. Nodes whose kind has no writer are skipped; the
243
+ * cleared (0,0,0,0) background means zero velocity. Runs inside the frame's command encoder (open one with
244
+ * renderWgpuBackground first), as its own render pass; ends any pass currently open and leaves none open.
245
+ */
246
+ export function renderWgpuVelocity(state, root, field, target) {
247
+ const runtime = getWgpuRenderStateRuntime(state);
248
+ if (runtime.commandEncoder === null) {
249
+ throw new Error('No active command encoder — call renderWgpuBackground before renderWgpuVelocity.');
250
+ }
251
+ if (runtime.renderPass !== null) {
252
+ runtime.renderPass.end();
253
+ runtime.renderPass = null;
254
+ }
255
+ const pipeline = ensureWgpuVelocityPipeline(state);
256
+ pipeline.cursor = 0;
257
+ const pass = runtime.commandEncoder.beginRenderPass({
258
+ colorAttachments: [
259
+ { view: target.view, loadOp: 'clear', storeOp: 'store', clearValue: { r: 0, g: 0, b: 0, a: 0 } },
260
+ ],
261
+ });
262
+ pass.setViewport(0, 0, target.width, target.height, 0, 1);
263
+ pass.setPipeline(pipeline.pipeline);
264
+ _activeVelocityPasses.set(state, { pass, pipeline });
265
+ const ctx = {
266
+ state,
267
+ field,
268
+ width: target.width,
269
+ height: target.height,
270
+ pixelRatio: state.pixelRatio,
271
+ };
272
+ visitWgpuVelocity(ctx, root);
273
+ pass.end();
274
+ _activeVelocityPasses.delete(state);
275
+ }
276
+ function ensureWgpuVelocityPipeline(state) {
277
+ const existing = _velocityPipelines.get(state);
278
+ if (existing !== undefined)
279
+ return existing;
280
+ const device = state.device;
281
+ const module = device.createShaderModule({ code: VELOCITY_WGSL });
282
+ const bindGroupLayout = device.createBindGroupLayout({
283
+ entries: [
284
+ {
285
+ binding: 0,
286
+ visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
287
+ buffer: { type: 'uniform', hasDynamicOffset: true },
288
+ },
289
+ ],
290
+ });
291
+ const layout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
292
+ const pipeline = device.createRenderPipeline({
293
+ layout,
294
+ vertex: { module, entryPoint: 'vs_main' },
295
+ // Velocity is written, not blended — the cleared background is zero velocity and quads overwrite it.
296
+ fragment: { module, entryPoint: 'fs_main', targets: [{ format: 'rgba16float' }] },
297
+ primitive: { topology: 'triangle-list' },
298
+ });
299
+ const uniformBuffer = device.createBuffer({
300
+ size: UNIFORM_SLOTS * UNIFORM_STRIDE,
301
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
302
+ });
303
+ const bindGroup = device.createBindGroup({
304
+ layout: bindGroupLayout,
305
+ entries: [{ binding: 0, resource: { buffer: uniformBuffer, size: UNIFORM_BYTES } }],
306
+ });
307
+ const entry = {
308
+ pipeline,
309
+ uniformBuffer,
310
+ bindGroup,
311
+ cursor: 0,
312
+ scratch: new Float32Array(UNIFORM_BYTES / 4),
313
+ };
314
+ _velocityPipelines.set(state, entry);
315
+ return entry;
316
+ }
317
+ function visitWgpuVelocity(ctx, node) {
318
+ const writer = getWgpuVelocityWriter(ctx.state, node.kind);
319
+ if (writer !== null)
320
+ writer(ctx, node);
321
+ const count = getNodeChildCount(node);
322
+ for (let i = 0; i < count; i++) {
323
+ const child = getNodeChildAt(node, i);
324
+ if (child !== null)
325
+ visitWgpuVelocity(ctx, child);
326
+ }
327
+ }
328
+ // clipRect (vec4) + velocity (vec2), padded to vec4 alignment. The unit-quad corner is derived from
329
+ // vertex_index so no vertex buffer is needed; the covered rect is reconstructed per vertex.
330
+ const VELOCITY_WGSL = /* wgsl */ `
331
+ struct Uniforms {
332
+ clipRect : vec4f,
333
+ velocity : vec2f,
334
+ _pad : vec2f,
335
+ }
336
+ @group(0) @binding(0) var<uniform> uni : Uniforms;
337
+
338
+ @vertex
339
+ fn vs_main(@builtin(vertex_index) vi : u32) -> @builtin(position) vec4f {
340
+ var corners = array<vec2f, 6>(
341
+ vec2f(0.0, 0.0), vec2f(1.0, 0.0), vec2f(0.0, 1.0),
342
+ vec2f(0.0, 1.0), vec2f(1.0, 0.0), vec2f(1.0, 1.0),
343
+ );
344
+ let clip = uni.clipRect.xy + corners[vi] * uni.clipRect.zw;
345
+ return vec4f(clip, 0.0, 1.0);
346
+ }
347
+
348
+ @fragment
349
+ fn fs_main() -> @location(0) vec4f {
350
+ return vec4f(uni.velocity, 0.0, 1.0);
351
+ }`;
352
+ // 32-byte uniform payload, but each ring slot is 256-byte aligned for dynamic-offset binding. 1024 slots
353
+ // caps a single velocity pass at 1024 quads before the ring wraps (rare; a batch with more instances would
354
+ // reuse slots) — generous headroom matching the per-frame draw scale.
355
+ const UNIFORM_BYTES = 32;
356
+ const UNIFORM_STRIDE = 256;
357
+ const UNIFORM_SLOTS = 1024;
358
+ const _scratchVelocity = { x: 0, y: 0 };
359
+ // Lazily compiled velocity pipeline per render state, the per-kind writer registry, and the currently open
360
+ // velocity pass (set for the duration of renderWgpuVelocity so drawWgpuVelocityQuad can reach it from
361
+ // just the public context). WeakMaps so all release when the state is GC'd.
362
+ const _velocityPipelines = new WeakMap();
363
+ const _velocityWriters = new WeakMap();
364
+ const _activeVelocityPasses = new WeakMap();
365
+ //# sourceMappingURL=wgpuVelocity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuVelocity.js","sourceRoot":"","sources":["../src/wgpuVelocity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { DisplayObjectRenderer, Renderable, RendererData, RenderProxy2D, RenderState, WgpuRenderState } from '@flighthq/types';
2
+ export declare function createWgpuVideoData(_state: RenderState, _source: Renderable): RendererData;
3
+ export declare function destroyWgpuVideoData(_state: RenderState, data: RendererData): void;
4
+ export declare function drawWgpuVideo(state: WgpuRenderState, renderProxy: RenderProxy2D): void;
5
+ export declare const defaultWgpuVideoRenderer: DisplayObjectRenderer;
6
+ //# sourceMappingURL=wgpuVideo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuVideo.d.ts","sourceRoot":"","sources":["../src/wgpuVideo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,qBAAqB,EACrB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,WAAW,EAEX,eAAe,EAEhB,MAAM,iBAAiB,CAAC;AAazB,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,GAAG,YAAY,CAE1F;AAGD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAIlF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAgDtF;AAED,eAAO,MAAM,wBAAwB,EAAE,qBAItC,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { drawWgpuQuad } from '@flighthq/render-wgpu';
2
+ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
3
+ import { createWgpuRendererData, getWgpuRendererData } from './wgpuRendererData';
4
+ import { flushWgpuSpriteBatch } from './wgpuSpriteBatch';
5
+ export function createWgpuVideoData(_state, _source) {
6
+ return createWgpuRendererData({ entry: null, h: 0, w: 0 });
7
+ }
8
+ // Destroys the GPU texture this video node owns when it is torn down via disposeDisplayObjectRender.
9
+ export function destroyWgpuVideoData(_state, data) {
10
+ const videoData = getWgpuRendererData(data);
11
+ if (videoData === null)
12
+ return;
13
+ videoData.entry?.texture.destroy();
14
+ }
15
+ export function drawWgpuVideo(state, renderProxy) {
16
+ const runtime = getWgpuRenderStateRuntime(state);
17
+ if (runtime.renderPass === null)
18
+ return;
19
+ flushWgpuSpriteBatch(state);
20
+ const source = renderProxy.source;
21
+ const element = source.data.source?.element;
22
+ if (element === undefined || element === null || element.readyState < 2)
23
+ return;
24
+ const vw = element.videoWidth;
25
+ const vh = element.videoHeight;
26
+ if (vw === 0 || vh === 0)
27
+ return;
28
+ state.applyBlendMode?.(state, renderProxy.blendMode);
29
+ const videoData = getWgpuRendererData(renderProxy.rendererData);
30
+ if (videoData === null)
31
+ return;
32
+ let entry = videoData.entry;
33
+ if (entry === null || videoData.w !== vw || videoData.h !== vh) {
34
+ entry?.texture.destroy();
35
+ const device = state.device;
36
+ const { textureBindGroupLayout, linearSampler } = runtime;
37
+ const texture = device.createTexture({
38
+ format: 'rgba8unorm',
39
+ size: [vw, vh, 1],
40
+ usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
41
+ });
42
+ const view = texture.createView();
43
+ const bindGroup = device.createBindGroup({
44
+ entries: [
45
+ { binding: 0, resource: view },
46
+ { binding: 1, resource: linearSampler },
47
+ ],
48
+ layout: textureBindGroupLayout,
49
+ });
50
+ entry = { bindGroup, texture, view };
51
+ videoData.entry = entry;
52
+ videoData.w = vw;
53
+ videoData.h = vh;
54
+ }
55
+ state.device.queue.copyExternalImageToTexture({ source: element, flipY: false }, { premultipliedAlpha: false, texture: entry.texture }, [vw, vh]);
56
+ drawWgpuQuad(state, renderProxy, entry, 0, 0, vw, vh, 0, 0, 1, 1);
57
+ }
58
+ export const defaultWgpuVideoRenderer = {
59
+ createData: createWgpuVideoData,
60
+ destroyData: destroyWgpuVideoData,
61
+ submit: drawWgpuVideo,
62
+ };
63
+ //# sourceMappingURL=wgpuVideo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuVideo.js","sourceRoot":"","sources":["../src/wgpuVideo.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@flighthq/displayobject-wgpu",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "src/**/*.test.ts",
16
+ "!dist/**/*.test.js",
17
+ "!dist/**/*.test.d.ts",
18
+ "!dist/**/*.test.js.map",
19
+ "!dist/**/*.test.d.ts.map"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -b",
23
+ "clean": "tsc -b --clean",
24
+ "test": "vitest run --config vitest.config.ts",
25
+ "test:watch": "vitest --watch --config vitest.config.ts",
26
+ "prepack": "npm run clean && npm run clean:dist && npm run build",
27
+ "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
28
+ },
29
+ "dependencies": {
30
+ "@flighthq/displayobject": "0.1.0",
31
+ "@flighthq/displayobject-canvas": "0.1.0",
32
+ "@flighthq/geometry": "0.1.0",
33
+ "@flighthq/materials": "0.1.0",
34
+ "@flighthq/node": "0.1.0",
35
+ "@flighthq/path": "0.1.0",
36
+ "@flighthq/render": "0.1.0",
37
+ "@flighthq/render-wgpu": "0.1.0",
38
+ "@flighthq/shape": "0.1.0",
39
+ "@flighthq/text": "0.1.0",
40
+ "@flighthq/textinput": "0.1.0",
41
+ "@flighthq/textlayout": "0.1.0",
42
+ "@flighthq/types": "0.1.0",
43
+ "@flighthq/velocity": "0.1.0"
44
+ },
45
+ "devDependencies": {
46
+ "@flighthq/sprite": "*",
47
+ "@webgpu/types": "*",
48
+ "typescript": "^5.3.0"
49
+ },
50
+ "description": "WebGPU display-object renderers (bitmap, shape, sprite, text, tilemap, particles)",
51
+ "sideEffects": false
52
+ }
@@ -0,0 +1,40 @@
1
+ import { createBitmap } from '@flighthq/displayobject';
2
+ import { getOrCreateRenderProxy2D, prepareDisplayObjectRender } from '@flighthq/render';
3
+ import { renderWgpuBackground, submitWgpuRenderPass } from '@flighthq/render-wgpu';
4
+ import { createWgpuRenderStateForTest, installWgpuMock } from '@flighthq/render-wgpu';
5
+
6
+ import { defaultWgpuBitmapRenderer, drawWgpuBitmap } from './wgpuBitmap';
7
+
8
+ beforeAll(() => {
9
+ installWgpuMock();
10
+ });
11
+
12
+ describe('defaultWgpuBitmapRenderer', () => {
13
+ it('has createData and draw functions', () => {
14
+ expect(typeof defaultWgpuBitmapRenderer.createData).toBe('function');
15
+ expect(typeof defaultWgpuBitmapRenderer.submit).toBe('function');
16
+ });
17
+ });
18
+
19
+ describe('drawWgpuBitmap', () => {
20
+ it('does not throw when image source is null', async () => {
21
+ const state = await createWgpuRenderStateForTest();
22
+ renderWgpuBackground(state);
23
+
24
+ const bitmap = createBitmap();
25
+ prepareDisplayObjectRender(state, bitmap);
26
+ const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
27
+
28
+ expect(() => drawWgpuBitmap(state, renderProxy)).not.toThrow();
29
+ submitWgpuRenderPass(state);
30
+ });
31
+
32
+ it('does not throw when renderPass is null', async () => {
33
+ const state = await createWgpuRenderStateForTest();
34
+ const bitmap = createBitmap();
35
+ prepareDisplayObjectRender(state, bitmap);
36
+ const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
37
+
38
+ expect(() => drawWgpuBitmap(state, renderProxy)).not.toThrow();
39
+ });
40
+ });