@flighthq/scene2d-wgpu 0.2.1-next.840.857425c

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/enableWgpuColorAdjustmentGuards.d.ts +4 -0
  2. package/dist/enableWgpuColorAdjustmentGuards.d.ts.map +1 -0
  3. package/dist/enableWgpuColorAdjustmentGuards.js +21 -0
  4. package/dist/enableWgpuColorAdjustmentGuards.js.map +1 -0
  5. package/dist/index.d.ts +29 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +29 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/moduleMockTestHelper.d.ts +15 -0
  10. package/dist/moduleMockTestHelper.d.ts.map +1 -0
  11. package/dist/moduleMockTestHelper.js +25 -0
  12. package/dist/moduleMockTestHelper.js.map +1 -0
  13. package/dist/wgpuBitmap.d.ts +4 -0
  14. package/dist/wgpuBitmap.d.ts.map +1 -0
  15. package/dist/wgpuBitmap.js +84 -0
  16. package/dist/wgpuBitmap.js.map +1 -0
  17. package/dist/wgpuCache.d.ts +31 -0
  18. package/dist/wgpuCache.d.ts.map +1 -0
  19. package/dist/wgpuCache.js +244 -0
  20. package/dist/wgpuCache.js.map +1 -0
  21. package/dist/wgpuClip.d.ts +3 -0
  22. package/dist/wgpuClip.d.ts.map +1 -0
  23. package/dist/wgpuClip.js +44 -0
  24. package/dist/wgpuClip.js.map +1 -0
  25. package/dist/wgpuClipContours.d.ts +4 -0
  26. package/dist/wgpuClipContours.d.ts.map +1 -0
  27. package/dist/wgpuClipContours.js +174 -0
  28. package/dist/wgpuClipContours.js.map +1 -0
  29. package/dist/wgpuClipRectangle.d.ts +4 -0
  30. package/dist/wgpuClipRectangle.d.ts.map +1 -0
  31. package/dist/wgpuClipRectangle.js +80 -0
  32. package/dist/wgpuClipRectangle.js.map +1 -0
  33. package/dist/wgpuColorAdjustment.d.ts +3 -0
  34. package/dist/wgpuColorAdjustment.d.ts.map +1 -0
  35. package/dist/wgpuColorAdjustment.js +201 -0
  36. package/dist/wgpuColorAdjustment.js.map +1 -0
  37. package/dist/wgpuDefaultMaterial.d.ts +4 -0
  38. package/dist/wgpuDefaultMaterial.d.ts.map +1 -0
  39. package/dist/wgpuDefaultMaterial.js +49 -0
  40. package/dist/wgpuDefaultMaterial.js.map +1 -0
  41. package/dist/wgpuNode2D.d.ts +5 -0
  42. package/dist/wgpuNode2D.d.ts.map +1 -0
  43. package/dist/wgpuNode2D.js +41 -0
  44. package/dist/wgpuNode2D.js.map +1 -0
  45. package/dist/wgpuParticleEmitter2D.d.ts +4 -0
  46. package/dist/wgpuParticleEmitter2D.d.ts.map +1 -0
  47. package/dist/wgpuParticleEmitter2D.js +293 -0
  48. package/dist/wgpuParticleEmitter2D.js.map +1 -0
  49. package/dist/wgpuQuadBatch.d.ts +5 -0
  50. package/dist/wgpuQuadBatch.d.ts.map +1 -0
  51. package/dist/wgpuQuadBatch.js +90 -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 +8 -0
  66. package/dist/wgpuRichText.d.ts.map +1 -0
  67. package/dist/wgpuRichText.js +175 -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 +164 -0
  80. package/dist/wgpuShape.js.map +1 -0
  81. package/dist/wgpuShapeMesh.d.ts +3 -0
  82. package/dist/wgpuShapeMesh.d.ts.map +1 -0
  83. package/dist/wgpuShapeMesh.js +224 -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 +12 -0
  90. package/dist/wgpuSpriteBatch.d.ts.map +1 -0
  91. package/dist/wgpuSpriteBatch.js +341 -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 +55 -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 +149 -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 +81 -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 +60 -0
  118. package/src/enableWgpuColorAdjustmentGuards.test.ts +82 -0
  119. package/src/wgpuBitmap.test.ts +40 -0
  120. package/src/wgpuCache.test.ts +272 -0
  121. package/src/wgpuClip.test.ts +15 -0
  122. package/src/wgpuClipContours.test.ts +101 -0
  123. package/src/wgpuClipRectangle.test.ts +45 -0
  124. package/src/wgpuColorAdjustment.test.ts +120 -0
  125. package/src/wgpuDefaultMaterial.test.ts +21 -0
  126. package/src/wgpuNode2D.test.ts +36 -0
  127. package/src/wgpuParticleEmitter2D.test.ts +85 -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 +96 -0
  136. package/src/wgpuShapeMesh.test.ts +164 -0
  137. package/src/wgpuSprite.test.ts +19 -0
  138. package/src/wgpuSpriteBatch.test.ts +272 -0
  139. package/src/wgpuSpriteRenderer.test.ts +63 -0
  140. package/src/wgpuTextInput.test.ts +37 -0
  141. package/src/wgpuTextLabel.test.ts +124 -0
  142. package/src/wgpuTilemap.test.ts +47 -0
  143. package/src/wgpuVelocity.test.ts +148 -0
  144. package/src/wgpuVideo.test.ts +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuClipContours.d.ts","sourceRoot":"","sources":["../src/wgpuClipContours.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAA4B,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAsCtG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAsBhE;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EACxC,OAAO,EAAE,WAAW,EACpB,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC/B,IAAI,CA+BN"}
@@ -0,0 +1,174 @@
1
+ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
2
+ import { flushWgpuSpriteBatch } from './wgpuSpriteBatch';
3
+ // Wgpu contour clip via stencil nesting — the Wgpu counterpart to webglClipContours. A path
4
+ // ClipRegion is realized by stamping its covered pixels into the stencil buffer, then content draws in
5
+ // the existing 'masked' stencil mode (compare equal, reference = currentMaskDepth). Crisp at any zoom:
6
+ // the contours are transformed by the node world transform in the vertex shader, never cached as a
7
+ // texture.
8
+ //
9
+ // NESTING MODEL — Wgpu cannot clear the stencil mid render pass (the pass clears it once at start,
10
+ // stencilLoadOp:'clear'), so the webgl clear-per-sibling trick is unavailable. Instead each clip
11
+ // INCREMENTS the stencil from its parent depth d to d+1 inside the polygon (compare 'equal' d, passOp
12
+ // 'increment-clamp'); pop redraws the same geometry to DECREMENT back to d (compare 'equal' d+1, passOp
13
+ // 'decrement-clamp'). This is sibling-safe (each pop restores its own region) and nests cleanly. Scissor
14
+ // (rect) clips compose independently via setScissorRect, exactly as before.
15
+ //
16
+ // LIMITATION: increment-clamp counts coverage, not winding, so a single simple/convex contour clips
17
+ // exactly (circles, rounded rects, convex polygons) but holes / self-intersecting even-odd fills are not
18
+ // yet honored — `winding` is accepted but not applied. The webgl backend has the same single-level
19
+ // coverage behavior. A true winding pass (separate front/back ops + a cover stamp) is a follow-up.
20
+ //
21
+ // Cannot be visually captured headless (no GPU adapter); the unit test asserts the pipeline/stencil call
22
+ // shape against the mock device. Mirror this against the verified webgl result when a GPU is available.
23
+ const CLIP_WGSL = /* wgsl */ `
24
+ struct ClipUniforms { matrix : mat3x3f }
25
+ @group(0) @binding(0) var<uniform> u : ClipUniforms;
26
+ @vertex fn vs_main(@location(0) position : vec2f) -> @builtin(position) vec4f {
27
+ let p = u.matrix * vec3f(position, 1.0);
28
+ return vec4f(p.x, p.y, 0.0, 1.0);
29
+ }
30
+ @fragment fn fs_main() -> @location(0) vec4f { return vec4f(0.0); }
31
+ `;
32
+ // mat3x3f in a uniform buffer has a 16-byte column stride (each column is a vec3 padded to vec4): 48 bytes.
33
+ const CLIP_UNIFORM_BYTES = 48;
34
+ export function popWgpuClipContours(state) {
35
+ const runtime = getWgpuRenderStateRuntime(state);
36
+ flushWgpuSpriteBatch(state);
37
+ const entry = runtime.clipContourStack.pop();
38
+ runtime.currentMaskDepth = Math.max(0, runtime.currentMaskDepth - 1);
39
+ const pass = runtime.renderPass;
40
+ if (pass !== null && entry !== undefined) {
41
+ const pipelines = ensureClipContourPipelines(state);
42
+ // Decrement this clip's covered pixels from (entry.depth + 1) back to entry.depth, restoring the
43
+ // parent's stencil so sibling clips and the parent's own content test correctly.
44
+ pass.setPipeline(pipelines.erase);
45
+ pass.setBindGroup(0, entry.bindGroup);
46
+ pass.setVertexBuffer(0, entry.vertexBuffer);
47
+ pass.setStencilReference(entry.depth + 1);
48
+ if (entry.vertexCount > 0)
49
+ pass.draw(entry.vertexCount);
50
+ }
51
+ if (entry !== undefined) {
52
+ // The erase draw just recorded references these buffers; the frame's submit is deferred to
53
+ // submitWgpuRenderPass, so defer their destruction until after that submit.
54
+ (runtime.retiredBuffers ?? (runtime.retiredBuffers = [])).push(entry.vertexBuffer, entry.uniformBuffer);
55
+ }
56
+ }
57
+ export function pushWgpuClipContours(state, contours, winding, worldTransform) {
58
+ const runtime = getWgpuRenderStateRuntime(state);
59
+ flushWgpuSpriteBatch(state);
60
+ // Coverage-based; winding (even-odd vs non-zero, holes) is not yet applied — see file header.
61
+ void winding;
62
+ const device = state.device;
63
+ const depth = runtime.currentMaskDepth;
64
+ const pipelines = ensureClipContourPipelines(state);
65
+ const { vertexBuffer, vertexCount } = createClipContourVertexBuffer(state, contours);
66
+ const uniformBuffer = createClipContourUniformBuffer(state, worldTransform);
67
+ const bindGroup = device.createBindGroup({
68
+ layout: pipelines.bindGroupLayout,
69
+ entries: [{ binding: 0, resource: { buffer: uniformBuffer } }],
70
+ });
71
+ const pass = runtime.renderPass;
72
+ if (pass !== null) {
73
+ // Increment the polygon's covered pixels from the parent depth to depth + 1. The 'equal' compare on
74
+ // the parent depth keeps the increment confined to the parent clip's interior (or the whole cleared
75
+ // buffer at depth 0) and makes overlapping fan triangles idempotent (only the first pass increments).
76
+ pass.setPipeline(pipelines.write);
77
+ pass.setBindGroup(0, bindGroup);
78
+ pass.setVertexBuffer(0, vertexBuffer);
79
+ pass.setStencilReference(depth);
80
+ if (vertexCount > 0)
81
+ pass.draw(vertexCount);
82
+ }
83
+ runtime.clipContourStack.push({ vertexBuffer, vertexCount, uniformBuffer, bindGroup, depth });
84
+ // Content drawn now tests stencil == currentMaskDepth (webgpuDraw/webgpuShader select 'masked' mode).
85
+ runtime.currentMaskDepth = depth + 1;
86
+ }
87
+ function createClipContourUniformBuffer(state, t) {
88
+ const runtime = getWgpuRenderStateRuntime(state);
89
+ const viewport = runtime.renderTargetViewport ?? state.canvas;
90
+ const iw = 2 / viewport.width;
91
+ const ih = 2 / viewport.height;
92
+ // Column-major mat3x3f = projection · worldTransform, mapping clip-local points to clip space exactly
93
+ // as webgpuDraw builds the content matrix (so clip and content land in identical clip space). Each
94
+ // column is padded to 4 floats (vec3 -> vec4 std140-style layout).
95
+ const m = new Float32Array(12);
96
+ m[0] = t.a * iw;
97
+ m[1] = -t.b * ih;
98
+ m[2] = 0;
99
+ m[4] = t.c * iw;
100
+ m[5] = -t.d * ih;
101
+ m[6] = 0;
102
+ m[8] = t.tx * iw - 1;
103
+ m[9] = -t.ty * ih + 1;
104
+ m[10] = 1;
105
+ const buffer = state.device.createBuffer({
106
+ size: CLIP_UNIFORM_BYTES,
107
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
108
+ });
109
+ state.device.queue.writeBuffer(buffer, 0, m);
110
+ return buffer;
111
+ }
112
+ // Expands each contour's triangle fan (origin, i, i+1) into a triangle-list vertex buffer — Wgpu has
113
+ // no TRIANGLE_FAN topology. Color writes are masked off in the pipeline, so only the stencil moves.
114
+ function createClipContourVertexBuffer(state, contours) {
115
+ const tris = [];
116
+ for (let c = 0; c < contours.length; c++) {
117
+ const contour = contours[c];
118
+ const pointCount = contour.length >> 1;
119
+ if (pointCount < 3)
120
+ continue;
121
+ for (let i = 1; i < pointCount - 1; i++) {
122
+ tris.push(contour[0], contour[1], contour[i * 2], contour[i * 2 + 1], contour[(i + 1) * 2], contour[(i + 1) * 2 + 1]);
123
+ }
124
+ }
125
+ const data = new Float32Array(tris);
126
+ const vertexCount = data.length >> 1;
127
+ const vertexBuffer = state.device.createBuffer({
128
+ size: Math.max(4, data.byteLength),
129
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
130
+ });
131
+ if (data.byteLength > 0)
132
+ state.device.queue.writeBuffer(vertexBuffer, 0, data);
133
+ return { vertexBuffer, vertexCount };
134
+ }
135
+ function ensureClipContourPipelines(state) {
136
+ const runtime = getWgpuRenderStateRuntime(state);
137
+ const format = runtime.currentColorFormat ?? state.format;
138
+ const cache = runtime.clipContourPipelines ?? (runtime.clipContourPipelines = new Map());
139
+ const existing = cache.get(format);
140
+ if (existing !== undefined)
141
+ return existing;
142
+ const device = state.device;
143
+ const module = device.createShaderModule({ code: CLIP_WGSL });
144
+ const bindGroupLayout = device.createBindGroupLayout({
145
+ entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: 'uniform' } }],
146
+ });
147
+ const layout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
148
+ const vertexBuffers = [
149
+ { arrayStride: 8, attributes: [{ shaderLocation: 0, offset: 0, format: 'float32x2' }] },
150
+ ];
151
+ const make = (passOp) => device.createRenderPipeline({
152
+ layout,
153
+ vertex: { module, entryPoint: 'vs_main', buffers: vertexBuffers },
154
+ fragment: { module, entryPoint: 'fs_main', targets: [{ format, writeMask: 0 }] },
155
+ primitive: { topology: 'triangle-list', cullMode: 'none' },
156
+ depthStencil: {
157
+ format: 'depth24plus-stencil8',
158
+ depthWriteEnabled: false,
159
+ depthCompare: 'always',
160
+ stencilFront: { compare: 'equal', passOp, failOp: 'keep', depthFailOp: 'keep' },
161
+ stencilBack: { compare: 'equal', passOp, failOp: 'keep', depthFailOp: 'keep' },
162
+ stencilReadMask: 0xff,
163
+ stencilWriteMask: 0xff,
164
+ },
165
+ });
166
+ const pipelines = {
167
+ write: make('increment-clamp'),
168
+ erase: make('decrement-clamp'),
169
+ bindGroupLayout,
170
+ };
171
+ cache.set(format, pipelines);
172
+ return pipelines;
173
+ }
174
+ //# sourceMappingURL=wgpuClipContours.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuClipContours.js","sourceRoot":"","sources":["../src/wgpuClipContours.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { MatrixLike, RectangleLike, WgpuRenderState } from '@flighthq/types';
2
+ export declare function popWgpuClipRectangle(state: WgpuRenderState): void;
3
+ export declare function pushWgpuClipRectangle(state: WgpuRenderState, rect: Readonly<RectangleLike>, transform: Readonly<MatrixLike>): void;
4
+ //# sourceMappingURL=wgpuClipRectangle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuClipRectangle.d.ts","sourceRoot":"","sources":["../src/wgpuClipRectangle.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAmB,MAAM,iBAAiB,CAAC;AAInG,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAoBjE;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,GAC9B,IAAI,CAmBN"}
@@ -0,0 +1,80 @@
1
+ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
2
+ import { flushWgpuSpriteBatch } from './wgpuSpriteBatch';
3
+ export function popWgpuClipRectangle(state) {
4
+ const runtime = getWgpuRenderStateRuntime(state);
5
+ flushWgpuSpriteBatch(state);
6
+ const stack = runtime.scissorStack;
7
+ stack.pop();
8
+ const previous = stack.length > 0 ? stack[stack.length - 1] : null;
9
+ runtime.currentScissorRect = previous;
10
+ const pass = runtime.renderPass;
11
+ if (pass === null)
12
+ return;
13
+ if (previous === null) {
14
+ const viewport = runtime.renderTargetViewport ?? state.canvas;
15
+ pass.setScissorRect(0, 0, viewport.width, viewport.height);
16
+ }
17
+ else if (previous.width <= 0 || previous.height <= 0) {
18
+ // Empty intersection stored during push — maintain degenerate scissor until fully popped.
19
+ pass.setScissorRect(0, 0, 1, 1);
20
+ }
21
+ else {
22
+ pass.setScissorRect(previous.x, previous.y, previous.width, previous.height);
23
+ }
24
+ }
25
+ export function pushWgpuClipRectangle(state, rect, transform) {
26
+ const runtime = getWgpuRenderStateRuntime(state);
27
+ flushWgpuSpriteBatch(state);
28
+ const next = intersectWgpuScissorRect(runtime.currentScissorRect ?? null, computeWgpuScissorRect(state, rect, transform));
29
+ runtime.currentScissorRect = next;
30
+ runtime.scissorStack.push(next);
31
+ const pass = runtime.renderPass;
32
+ if (pass === null)
33
+ return;
34
+ if (next.width <= 0 || next.height <= 0) {
35
+ // Clip rect projects entirely outside the viewport — use a 1×1 degenerate scissor at
36
+ // the origin so the node is effectively invisible while the rect remains Wgpu-valid.
37
+ pass.setScissorRect(0, 0, 1, 1);
38
+ }
39
+ else {
40
+ pass.setScissorRect(next.x, next.y, next.width, next.height);
41
+ }
42
+ }
43
+ function computeWgpuScissorRect(state, rect, transform) {
44
+ const runtime = getWgpuRenderStateRuntime(state);
45
+ const x0 = transform.a * rect.x + transform.c * rect.y + transform.tx;
46
+ const y0 = transform.b * rect.x + transform.d * rect.y + transform.ty;
47
+ const x1 = transform.a * (rect.x + rect.width) + transform.c * rect.y + transform.tx;
48
+ const y1 = transform.b * (rect.x + rect.width) + transform.d * rect.y + transform.ty;
49
+ const x2 = transform.a * rect.x + transform.c * (rect.y + rect.height) + transform.tx;
50
+ const y2 = transform.b * rect.x + transform.d * (rect.y + rect.height) + transform.ty;
51
+ const x3 = transform.a * (rect.x + rect.width) + transform.c * (rect.y + rect.height) + transform.tx;
52
+ const y3 = transform.b * (rect.x + rect.width) + transform.d * (rect.y + rect.height) + transform.ty;
53
+ const viewport = runtime.renderTargetViewport ?? state.canvas;
54
+ const minX = Math.max(0, Math.floor(Math.min(x0, x1, x2, x3)));
55
+ const maxX = Math.min(viewport.width, Math.ceil(Math.max(x0, x1, x2, x3)));
56
+ const minY = Math.max(0, Math.floor(Math.min(y0, y1, y2, y3)));
57
+ const maxY = Math.min(viewport.height, Math.ceil(Math.max(y0, y1, y2, y3)));
58
+ // Wgpu uses top-left origin for scissor, same as the canvas coordinate system
59
+ return {
60
+ height: Math.max(0, maxY - minY),
61
+ width: Math.max(0, maxX - minX),
62
+ x: minX,
63
+ y: minY,
64
+ };
65
+ }
66
+ function intersectWgpuScissorRect(a, b) {
67
+ if (a === null)
68
+ return { height: b.height, width: b.width, x: b.x, y: b.y };
69
+ const x = Math.max(a.x, b.x);
70
+ const y = Math.max(a.y, b.y);
71
+ const right = Math.min(a.x + a.width, b.x + b.width);
72
+ const bottom = Math.min(a.y + a.height, b.y + b.height);
73
+ return {
74
+ height: Math.max(0, bottom - y),
75
+ width: Math.max(0, right - x),
76
+ x,
77
+ y,
78
+ };
79
+ }
80
+ //# sourceMappingURL=wgpuClipRectangle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuClipRectangle.js","sourceRoot":"","sources":["../src/wgpuClipRectangle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { WgpuRenderState } from '@flighthq/types';
2
+ export declare function enableWgpuColorAdjustment(state: WgpuRenderState): void;
3
+ //# sourceMappingURL=wgpuColorAdjustment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuColorAdjustment.d.ts","sourceRoot":"","sources":["../src/wgpuColorAdjustment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAIV,eAAe,EAEhB,MAAM,iBAAiB,CAAC;AAUzB,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAOtE"}
@@ -0,0 +1,201 @@
1
+ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
2
+ import { getWgpuQuadBatchPreludeWGSL } from './wgpuSpriteBatch';
3
+ // Enables the opt-in inline color-adjustment fold on a WebGPU render state: the fused-color-matrix
4
+ // scene2d the sprite/quad batch draws through so a color transform (and, later, other pointwise
5
+ // adjustments) folds into the batch as per-instance storage data at @group(3) — replicated across the
6
+ // batch for a whole-batch tint, or varied per instance — without ever splitting the batch. Until a
7
+ // state calls this, its batch renderer carries none of this module's WGSL (it tree-shakes out) and
8
+ // recordWgpuSpriteBatchColorTransform silently skips every tint. Idempotent; safe to call per state.
9
+ export function enableWgpuColorAdjustment(state) {
10
+ const runtime = getWgpuRenderStateRuntime(state);
11
+ runtime.wgpuColorAdjustmentFold = wgpuColorAdjustmentFold;
12
+ if (runtime.spriteBatchColorTransformMode === undefined)
13
+ runtime.spriteBatchColorTransformMode = CT_MODE_NONE;
14
+ if (runtime.spriteBatchColorTransformData === undefined) {
15
+ runtime.spriteBatchColorTransformData = new Float32Array(COLOR_TRANSFORM_FLOATS * 256);
16
+ }
17
+ }
18
+ // Per-instance color-transform data (8 floats = 4 multiplier + 4 offset). Wgpu carries every tint
19
+ // through the per-instance storage buffer, so a whole-batch (uniform) tint is the same value on each
20
+ // instance — there is no separate hardware-uniform path.
21
+ const COLOR_TRANSFORM_FLOATS = 8;
22
+ // Color-adjustment fold modes for the active sprite batch. NONE keeps the base module; UNIFORM defers
23
+ // per-instance fill while one tint covers the whole batch; PER_INSTANCE packs a tint per instance.
24
+ const CT_MODE_NONE = 0;
25
+ const CT_MODE_UNIFORM = 1;
26
+ const CT_MODE_PER_INSTANCE = 2;
27
+ // Folds instance `instanceIndex`'s effective color transform into the active batch. See the fold-mode
28
+ // constants for the promotion rules. `colorTransform` is null for an untinted instance.
29
+ function recordWgpuColorAdjustment(runtime, colorTransform, instanceIndex) {
30
+ if (runtime.spriteBatchColorTransformData === undefined) {
31
+ runtime.spriteBatchColorTransformData = new Float32Array(COLOR_TRANSFORM_FLOATS * 256);
32
+ }
33
+ const mode = runtime.spriteBatchColorTransformMode ?? CT_MODE_NONE;
34
+ const tint = colorTransform ?? null;
35
+ if (mode === CT_MODE_NONE) {
36
+ if (tint === null)
37
+ return;
38
+ if (instanceIndex === 0) {
39
+ runtime.spriteBatchColorTransformMode = CT_MODE_UNIFORM;
40
+ runtime.spriteBatchUniformColorTransform = tint;
41
+ return;
42
+ }
43
+ promoteWgpuSpriteBatchColorTransformToPerInstance(runtime, instanceIndex, null);
44
+ writeWgpuColorTransformInstance(runtime, tint, instanceIndex);
45
+ return;
46
+ }
47
+ if (mode === CT_MODE_UNIFORM) {
48
+ const uniform = runtime.spriteBatchUniformColorTransform ?? null;
49
+ if (equalsRecordedColorTransform(tint, uniform))
50
+ return;
51
+ promoteWgpuSpriteBatchColorTransformToPerInstance(runtime, instanceIndex, uniform);
52
+ writeWgpuColorTransformInstance(runtime, tint, instanceIndex);
53
+ return;
54
+ }
55
+ writeWgpuColorTransformInstance(runtime, tint, instanceIndex);
56
+ }
57
+ // Resolves the active batch's folded realization: replicates a whole-batch uniform tint across the
58
+ // batch, then returns the per-instance storage data + the folded shader module. Returns null when the
59
+ // batch carried no tint, so flushWgpuSpriteBatch runs the lean material path. Resets the fold mode for
60
+ // the next batch.
61
+ function resolveWgpuColorAdjustmentFlush(state, count) {
62
+ const runtime = getWgpuRenderStateRuntime(state);
63
+ const ctMode = runtime.spriteBatchColorTransformMode ?? CT_MODE_NONE;
64
+ if (ctMode === CT_MODE_NONE)
65
+ return null;
66
+ if (ctMode === CT_MODE_UNIFORM) {
67
+ fillWgpuSpriteBatchUniformColorTransform(runtime, runtime.spriteBatchUniformColorTransform, count);
68
+ }
69
+ runtime.spriteBatchColorTransformMode = CT_MODE_NONE;
70
+ runtime.spriteBatchUniformColorTransform = null;
71
+ return {
72
+ data: runtime.spriteBatchColorTransformData,
73
+ floats: COLOR_TRANSFORM_FLOATS,
74
+ module: getWgpuSpriteBatchColorTransformModule(state),
75
+ };
76
+ }
77
+ // Value equality for the whole-batch uniform check: reference-equal short-circuits (every glyph of a
78
+ // bitmap-text node shares one node-level tint), else compares all eight fields.
79
+ function equalsRecordedColorTransform(a, b) {
80
+ if (a === b)
81
+ return true;
82
+ if (a === null || b === null)
83
+ return false;
84
+ return (a.redMultiplier === b.redMultiplier &&
85
+ a.greenMultiplier === b.greenMultiplier &&
86
+ a.blueMultiplier === b.blueMultiplier &&
87
+ a.alphaMultiplier === b.alphaMultiplier &&
88
+ a.redOffset === b.redOffset &&
89
+ a.greenOffset === b.greenOffset &&
90
+ a.blueOffset === b.blueOffset &&
91
+ a.alphaOffset === b.alphaOffset);
92
+ }
93
+ // Grows the color-transform data array to hold `floatsNeeded` floats, preserving already-recorded
94
+ // per-instance data.
95
+ function ensureWgpuColorTransformCapacity(runtime, floatsNeeded) {
96
+ const existing = runtime.spriteBatchColorTransformData;
97
+ if (existing !== undefined && floatsNeeded <= existing.length)
98
+ return;
99
+ const newSize = Math.max(floatsNeeded, (existing?.length ?? 0) * 2, COLOR_TRANSFORM_FLOATS * 256);
100
+ const grown = new Float32Array(newSize);
101
+ if (existing !== undefined)
102
+ grown.set(existing);
103
+ runtime.spriteBatchColorTransformData = grown;
104
+ }
105
+ // Replicates a whole-batch uniform tint across `count` instances at flush time — Wgpu has no separate
106
+ // hardware-uniform tint path, so a uniform is the same value on every instance of the storage buffer.
107
+ function fillWgpuSpriteBatchUniformColorTransform(runtime, colorTransform, count) {
108
+ ensureWgpuColorTransformCapacity(runtime, count * COLOR_TRANSFORM_FLOATS);
109
+ for (let i = 0; i < count; i++)
110
+ writeWgpuColorTransformInstance(runtime, colorTransform, i);
111
+ }
112
+ // The folded per-instance color-transform shader module (cached per device): the base sprite-batch
113
+ // prelude plus a scene2d that reads 8 per-instance floats from the material storage buffer (@group(3))
114
+ // and applies `color * mult + offset` in unpremultiplied space. Reused verbatim from the former
115
+ // color-transform material so premultiplied-alpha handling is unchanged.
116
+ function getWgpuSpriteBatchColorTransformModule(state) {
117
+ const cached = _colorTransformModules.get(state.device);
118
+ if (cached !== undefined)
119
+ return cached;
120
+ const module = state.device.createShaderModule({
121
+ code: getWgpuQuadBatchPreludeWGSL() + COLOR_TRANSFORM_WGSL,
122
+ });
123
+ _colorTransformModules.set(state.device, module);
124
+ return module;
125
+ }
126
+ // Switches the batch to per-instance mode and back-fills every already-recorded instance
127
+ // [0, instanceCount) with `fill` (a prior uniform value, or null → identity).
128
+ function promoteWgpuSpriteBatchColorTransformToPerInstance(runtime, instanceCount, fill) {
129
+ runtime.spriteBatchColorTransformMode = CT_MODE_PER_INSTANCE;
130
+ for (let i = 0; i < instanceCount; i++)
131
+ writeWgpuColorTransformInstance(runtime, fill, i);
132
+ }
133
+ // Writes one instance's eight color-transform floats (multiplier rgba, then offset rgba normalized by
134
+ // 255) at its slot, growing the array as needed. A null transform writes the identity.
135
+ function writeWgpuColorTransformInstance(runtime, colorTransform, instanceIndex) {
136
+ const offset = instanceIndex * COLOR_TRANSFORM_FLOATS;
137
+ ensureWgpuColorTransformCapacity(runtime, offset + COLOR_TRANSFORM_FLOATS);
138
+ const out = runtime.spriteBatchColorTransformData;
139
+ if (colorTransform !== null) {
140
+ out[offset] = colorTransform.redMultiplier;
141
+ out[offset + 1] = colorTransform.greenMultiplier;
142
+ out[offset + 2] = colorTransform.blueMultiplier;
143
+ out[offset + 3] = colorTransform.alphaMultiplier;
144
+ out[offset + 4] = colorTransform.redOffset / 255;
145
+ out[offset + 5] = colorTransform.greenOffset / 255;
146
+ out[offset + 6] = colorTransform.blueOffset / 255;
147
+ out[offset + 7] = colorTransform.alphaOffset / 255;
148
+ }
149
+ else {
150
+ out[offset] = 1;
151
+ out[offset + 1] = 1;
152
+ out[offset + 2] = 1;
153
+ out[offset + 3] = 1;
154
+ out[offset + 4] = 0;
155
+ out[offset + 5] = 0;
156
+ out[offset + 6] = 0;
157
+ out[offset + 7] = 0;
158
+ }
159
+ }
160
+ const COLOR_TRANSFORM_WGSL = /* wgsl */ `
161
+ @group(3) @binding(0) var<storage, read> ctData : array<f32>;
162
+
163
+ struct VertexOut {
164
+ @builtin(position) position : vec4f,
165
+ @location(0) uv : vec2f,
166
+ @location(1) alpha : f32,
167
+ @location(2) ctMult : vec4f,
168
+ @location(3) ctOff : vec4f,
169
+ }
170
+
171
+ @vertex
172
+ fn vs_main(@builtin(vertex_index) vi : u32, @builtin(instance_index) ii : u32) -> VertexOut {
173
+ let bv = quadBaseVertex(vi, ii);
174
+ let b = ii * 8u;
175
+ let ctMult = vec4f(ctData[b + 0u], ctData[b + 1u], ctData[b + 2u], ctData[b + 3u]);
176
+ let ctOff = vec4f(ctData[b + 4u], ctData[b + 5u], ctData[b + 6u], ctData[b + 7u]);
177
+ return VertexOut(bv.position, bv.uv, bv.alpha, ctMult, ctOff);
178
+ }
179
+
180
+ @fragment
181
+ fn fs_main(in : VertexOut) -> @location(0) vec4f {
182
+ var color = textureSample(tex, smp, in.uv);
183
+ if (color.a <= 0.0) { discard; }
184
+ if (uni.straightTextureAlpha != 0u) {
185
+ color = vec4f(color.rgb * color.a, color.a);
186
+ }
187
+ color = color * clamp(in.alpha, 0.0, 1.0);
188
+ if (color.a > 0.0) {
189
+ color = vec4f(color.rgb / color.a, color.a);
190
+ color = clamp(color * in.ctMult + in.ctOff, vec4f(0.0), vec4f(1.0));
191
+ color = vec4f(color.rgb * color.a, color.a);
192
+ }
193
+ return color;
194
+ }
195
+ `;
196
+ const _colorTransformModules = new WeakMap();
197
+ const wgpuColorAdjustmentFold = {
198
+ record: recordWgpuColorAdjustment,
199
+ resolveFlush: resolveWgpuColorAdjustmentFlush,
200
+ };
201
+ //# sourceMappingURL=wgpuColorAdjustment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuColorAdjustment.js","sourceRoot":"","sources":["../src/wgpuColorAdjustment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { WgpuMaterialRenderer, WgpuRenderState } from '@flighthq/types';
2
+ export declare function registerDefaultWgpuMaterial(state: WgpuRenderState): void;
3
+ export declare const defaultWgpuMaterialRenderer: WgpuMaterialRenderer;
4
+ //# sourceMappingURL=wgpuDefaultMaterial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuDefaultMaterial.d.ts","sourceRoot":"","sources":["../src/wgpuDefaultMaterial.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAQ7E,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAExE;AAID,eAAO,MAAM,2BAA2B,EAAE,oBAWzC,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { registerWgpuMaterialRenderer } from '@flighthq/render-wgpu';
2
+ import { DefaultMaterialKind } from '@flighthq/types';
3
+ import { getWgpuQuadBatchPreludeWGSL } from './wgpuSpriteBatch';
4
+ // Registers the bundled default material under DefaultMaterialKind. It is a bundled material like any
5
+ // other — no privileged status in the render path; a node with no material renders only if a renderer
6
+ // is registered for DefaultMaterialKind. A user can copy this file and register their own default.
7
+ export function registerDefaultWgpuMaterial(state) {
8
+ registerWgpuMaterialRenderer(state, DefaultMaterialKind, defaultWgpuMaterialRenderer);
9
+ }
10
+ // Textured quad with per-instance alpha and no other effect. The batch holds no shader of its own, so
11
+ // even the plain path is just a registered material — this module IS the base sprite-batch shader.
12
+ export const defaultWgpuMaterialRenderer = {
13
+ instanceFloatCount: 0,
14
+ getShaderModule(state) {
15
+ const cached = _modules.get(state.device);
16
+ if (cached !== undefined)
17
+ return cached;
18
+ const module = state.device.createShaderModule({
19
+ code: getWgpuQuadBatchPreludeWGSL() + DEFAULT_MATERIAL_WGSL,
20
+ });
21
+ _modules.set(state.device, module);
22
+ return module;
23
+ },
24
+ };
25
+ const DEFAULT_MATERIAL_WGSL = /* wgsl */ `
26
+ struct VertexOut {
27
+ @builtin(position) position : vec4f,
28
+ @location(0) uv : vec2f,
29
+ @location(1) alpha : f32,
30
+ }
31
+
32
+ @vertex
33
+ fn vs_main(@builtin(vertex_index) vi : u32, @builtin(instance_index) ii : u32) -> VertexOut {
34
+ let bv = quadBaseVertex(vi, ii);
35
+ return VertexOut(bv.position, bv.uv, bv.alpha);
36
+ }
37
+
38
+ @fragment
39
+ fn fs_main(in : VertexOut) -> @location(0) vec4f {
40
+ var color = textureSample(tex, smp, in.uv);
41
+ if (color.a <= 0.0) { discard; }
42
+ if (uni.straightTextureAlpha != 0u) {
43
+ color = vec4f(color.rgb * color.a, color.a);
44
+ }
45
+ return color * clamp(in.alpha, 0.0, 1.0);
46
+ }
47
+ `;
48
+ const _modules = new WeakMap();
49
+ //# sourceMappingURL=wgpuDefaultMaterial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuDefaultMaterial.js","sourceRoot":"","sources":["../src/wgpuDefaultMaterial.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEhE,sGAAsG;AACtG,sGAAsG;AACtG,mGAAmG;AACnG,MAAM,UAAU,2BAA2B,CAAC,KAAsB;IAChE,4BAA4B,CAAC,KAAK,EAAE,mBAAmB,EAAE,2BAA2B,CAAC,CAAC;AACxF,CAAC;AAED,sGAAsG;AACtG,mGAAmG;AACnG,MAAM,CAAC,MAAM,2BAA2B,GAAyB;IAC/D,kBAAkB,EAAE,CAAC;IACrB,eAAe,CAAC,KAAsB;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACxC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAC7C,IAAI,EAAE,2BAA2B,EAAE,GAAG,qBAAqB;SAC5D,CAAC,CAAC;QACH,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAC;AAEF,MAAM,qBAAqB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;CAsBxC,CAAC;AAEF,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA8B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Node2D, Scene2DRenderer, RenderProxy2D, WgpuRenderState } from '@flighthq/types';
2
+ export declare function drawWgpuScene2D(_state: WgpuRenderState, _renderProxy: RenderProxy2D): void;
3
+ export declare function renderWgpuScene2D(state: WgpuRenderState, source: Node2D): void;
4
+ export declare const defaultWgpuScene2DRenderer: Scene2DRenderer;
5
+ //# sourceMappingURL=wgpuNode2D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuNode2D.d.ts","sourceRoot":"","sources":["../src/wgpuNode2D.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAI/F,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,GAAG,IAAI,CAE1F;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAiC9E;AAED,eAAO,MAAM,0BAA0B,EAAE,eAGxC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { getRenderProxy2D, isRenderProxyVisible, noopRendererData } from '@flighthq/render';
2
+ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu';
3
+ import { getNode2DRuntime } from '@flighthq/scene2d';
4
+ import { flushWgpuSpriteBatch } from './wgpuSpriteBatch';
5
+ export function drawWgpuScene2D(_state, _renderProxy) {
6
+ // Plain display objects have no visual geometry of their own.
7
+ }
8
+ export function renderWgpuScene2D(state, source) {
9
+ const tempStack = getWgpuRenderStateRuntime(state).tempStack;
10
+ const clipHooks = state.displayObjectClipHooks;
11
+ let stackLength = 1;
12
+ tempStack[0] = source;
13
+ while (stackLength > 0) {
14
+ const current = tempStack[--stackLength];
15
+ if (!current.enabled)
16
+ continue;
17
+ const data = getRenderProxy2D(state, current);
18
+ if (data === undefined)
19
+ continue;
20
+ clipHooks?.popClip(state, data, current);
21
+ if (!isRenderProxyVisible(data))
22
+ continue;
23
+ clipHooks?.pushClip(state, data, current);
24
+ data.renderer?.submit(state, data);
25
+ if (data.traverseChildren) {
26
+ const children = getNode2DRuntime(current).children;
27
+ if (children !== null) {
28
+ for (let i = children.length - 1; i >= 0; i--) {
29
+ tempStack[stackLength++] = children[i];
30
+ }
31
+ }
32
+ }
33
+ }
34
+ flushWgpuSpriteBatch(state);
35
+ clipHooks?.finalize(state);
36
+ }
37
+ export const defaultWgpuScene2DRenderer = {
38
+ createData: noopRendererData,
39
+ submit: drawWgpuScene2D,
40
+ };
41
+ //# sourceMappingURL=wgpuNode2D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuNode2D.js","sourceRoot":"","sources":["../src/wgpuNode2D.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,UAAU,eAAe,CAAC,MAAuB,EAAE,YAA2B;IAClF,8DAA8D;AAChE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAsB,EAAE,MAAc;IACtE,MAAM,SAAS,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC;IAC7D,MAAM,SAAS,GAAG,KAAK,CAAC,sBAAsB,CAAC;IAE/C,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAEtB,OAAO,WAAW,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,WAAW,CAAW,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,SAAS;QAE/B,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QAEjC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAEzC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;YAAE,SAAS;QAE1C,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAE1C,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;YACpD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC9C,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAW,CAAC;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC5B,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAoB;IACzD,UAAU,EAAE,gBAAgB;IAC5B,MAAM,EAAE,eAAe;CACxB,CAAC"}