@multiplekex/shallot 0.1.12 → 0.2.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 (62) hide show
  1. package/package.json +3 -4
  2. package/src/core/builder.ts +71 -32
  3. package/src/core/component.ts +25 -11
  4. package/src/core/index.ts +14 -13
  5. package/src/core/math.ts +135 -0
  6. package/src/core/runtime.ts +0 -1
  7. package/src/core/state.ts +9 -68
  8. package/src/core/xml.ts +381 -265
  9. package/src/editor/format.ts +5 -0
  10. package/src/editor/index.ts +101 -0
  11. package/src/extras/arrows/index.ts +28 -69
  12. package/src/extras/gradient/index.ts +36 -52
  13. package/src/extras/lines/index.ts +51 -122
  14. package/src/extras/orbit/index.ts +40 -15
  15. package/src/extras/text/font.ts +546 -0
  16. package/src/extras/text/index.ts +158 -204
  17. package/src/extras/text/sdf.ts +429 -0
  18. package/src/standard/activity/index.ts +172 -0
  19. package/src/standard/compute/graph.ts +23 -23
  20. package/src/standard/compute/index.ts +76 -61
  21. package/src/standard/defaults.ts +8 -5
  22. package/src/standard/index.ts +1 -0
  23. package/src/standard/input/index.ts +30 -19
  24. package/src/standard/loading/index.ts +18 -13
  25. package/src/standard/render/bvh/blas.ts +752 -0
  26. package/src/standard/render/bvh/radix.ts +476 -0
  27. package/src/standard/render/bvh/structs.ts +167 -0
  28. package/src/standard/render/bvh/tlas.ts +886 -0
  29. package/src/standard/render/bvh/traverse.ts +467 -0
  30. package/src/standard/render/camera.ts +302 -27
  31. package/src/standard/render/data.ts +93 -0
  32. package/src/standard/render/depth.ts +117 -0
  33. package/src/standard/render/forward/index.ts +259 -0
  34. package/src/standard/render/forward/raster.ts +228 -0
  35. package/src/standard/render/index.ts +443 -70
  36. package/src/standard/render/indirect.ts +40 -0
  37. package/src/standard/render/instance.ts +214 -0
  38. package/src/standard/render/intersection.ts +72 -0
  39. package/src/standard/render/light.ts +16 -16
  40. package/src/standard/render/mesh/index.ts +67 -75
  41. package/src/standard/render/mesh/unified.ts +96 -0
  42. package/src/standard/render/{transparent.ts → overlay.ts} +14 -15
  43. package/src/standard/render/pass.ts +10 -4
  44. package/src/standard/render/postprocess.ts +142 -64
  45. package/src/standard/render/ray.ts +61 -0
  46. package/src/standard/render/scene.ts +38 -164
  47. package/src/standard/render/shaders.ts +484 -0
  48. package/src/standard/render/surface/compile.ts +3 -10
  49. package/src/standard/render/surface/index.ts +60 -30
  50. package/src/standard/render/surface/noise.ts +45 -0
  51. package/src/standard/render/surface/structs.ts +60 -19
  52. package/src/standard/render/surface/wgsl.ts +573 -0
  53. package/src/standard/render/triangle.ts +84 -0
  54. package/src/standard/transforms/index.ts +4 -6
  55. package/src/standard/tween/index.ts +10 -1
  56. package/src/standard/tween/sequence.ts +24 -16
  57. package/src/standard/tween/tween.ts +67 -16
  58. package/src/core/types.ts +0 -37
  59. package/src/standard/compute/inspect.ts +0 -201
  60. package/src/standard/compute/pass.ts +0 -23
  61. package/src/standard/compute/timing.ts +0 -139
  62. package/src/standard/render/forward.ts +0 -273
@@ -0,0 +1,5 @@
1
+ import { parse, serialize } from "../core";
2
+
3
+ export function format(xml: string): string {
4
+ return serialize(parse(xml));
5
+ }
@@ -0,0 +1,101 @@
1
+ import type { Node } from "../core";
2
+
3
+ export { format } from "./format";
4
+
5
+ type Add = { type: "add"; parent: Node | null; node: Node; index: number };
6
+ type Remove = { type: "remove"; parent: Node | null; node: Node; index: number };
7
+ type SetAttr = { type: "setAttr"; node: Node; name: string; prev: string | null; next: string };
8
+
9
+ export type Command = Add | Remove | SetAttr;
10
+
11
+ export type History = { undo: Command[]; redo: Command[] };
12
+
13
+ export type Selection = Set<Node>;
14
+
15
+ function getChildren(parent: Node | null, nodes: Node[]): Node[] {
16
+ return parent ? parent.children : nodes;
17
+ }
18
+
19
+ export function apply(nodes: Node[], cmd: Command): void {
20
+ switch (cmd.type) {
21
+ case "add": {
22
+ const children = getChildren(cmd.parent, nodes);
23
+ children.splice(cmd.index, 0, cmd.node);
24
+ break;
25
+ }
26
+ case "remove": {
27
+ const children = getChildren(cmd.parent, nodes);
28
+ children.splice(cmd.index, 1);
29
+ break;
30
+ }
31
+ case "setAttr": {
32
+ const idx = cmd.node.attrs.findIndex((a) => a.name === cmd.name);
33
+ if (idx >= 0) {
34
+ cmd.node.attrs[idx].value = cmd.next;
35
+ } else {
36
+ cmd.node.attrs.push({ name: cmd.name, value: cmd.next });
37
+ }
38
+ break;
39
+ }
40
+ }
41
+ }
42
+
43
+ export function reverse(nodes: Node[], cmd: Command): void {
44
+ switch (cmd.type) {
45
+ case "add": {
46
+ const children = getChildren(cmd.parent, nodes);
47
+ children.splice(cmd.index, 1);
48
+ break;
49
+ }
50
+ case "remove": {
51
+ const children = getChildren(cmd.parent, nodes);
52
+ children.splice(cmd.index, 0, cmd.node);
53
+ break;
54
+ }
55
+ case "setAttr": {
56
+ const idx = cmd.node.attrs.findIndex((a) => a.name === cmd.name);
57
+ if (cmd.prev === null) {
58
+ if (idx >= 0) cmd.node.attrs.splice(idx, 1);
59
+ } else if (idx >= 0) {
60
+ cmd.node.attrs[idx].value = cmd.prev;
61
+ }
62
+ break;
63
+ }
64
+ }
65
+ }
66
+
67
+ export function execute(history: History, nodes: Node[], cmd: Command): void {
68
+ apply(nodes, cmd);
69
+ history.undo.push(cmd);
70
+ history.redo.length = 0;
71
+ }
72
+
73
+ export function undo(history: History, nodes: Node[]): void {
74
+ const cmd = history.undo.pop();
75
+ if (!cmd) return;
76
+ reverse(nodes, cmd);
77
+ history.redo.push(cmd);
78
+ }
79
+
80
+ export function redo(history: History, nodes: Node[]): void {
81
+ const cmd = history.redo.pop();
82
+ if (!cmd) return;
83
+ apply(nodes, cmd);
84
+ history.undo.push(cmd);
85
+ }
86
+
87
+ export function select(selection: Selection, ...nodesToSelect: Node[]): void {
88
+ for (const node of nodesToSelect) {
89
+ selection.add(node);
90
+ }
91
+ }
92
+
93
+ export function deselect(selection: Selection, ...nodesToDeselect: Node[]): void {
94
+ for (const node of nodesToDeselect) {
95
+ selection.delete(node);
96
+ }
97
+ }
98
+
99
+ export function clear(selection: Selection): void {
100
+ selection.clear();
101
+ }
@@ -1,15 +1,24 @@
1
- import { MAX_ENTITIES, resource, type Plugin, type State, type System } from "../../core";
2
- import { setTraits, type FieldAccessor } from "../../core/component";
1
+ import {
2
+ MAX_ENTITIES,
3
+ resource,
4
+ createFieldProxy,
5
+ type Plugin,
6
+ type State,
7
+ type System,
8
+ type FieldProxy,
9
+ } from "../../core";
10
+ import { setTraits } from "../../core/component";
3
11
  import { Compute, ComputePlugin, createEntityIdBuffer } from "../../standard/compute";
4
12
  import {
5
13
  Render,
6
14
  RenderPlugin,
7
- DEPTH_FORMAT,
8
15
  Pass,
9
16
  registerDraw,
10
17
  type Draw,
11
18
  type SharedPassContext,
12
19
  } from "../../standard/render";
20
+ import { DEPTH_FORMAT } from "../../standard/render/scene";
21
+ import { SCENE_STRUCT_WGSL } from "../../standard/render/shaders";
13
22
  import { Transform } from "../../standard/transforms";
14
23
  import { Line, Lines, LinesPlugin } from "../lines";
15
24
 
@@ -17,44 +26,16 @@ export const ArrowData = {
17
26
  data: new Float32Array(MAX_ENTITIES * 4),
18
27
  };
19
28
 
20
- interface ArrowProxy extends Array<number>, FieldAccessor {}
21
-
22
- function arrowProxy(offset: number): ArrowProxy {
23
- const data = ArrowData.data;
24
-
25
- function getValue(eid: number): number {
26
- return data[eid * 4 + offset];
27
- }
28
-
29
- function setValue(eid: number, value: number): void {
30
- data[eid * 4 + offset] = value;
31
- }
32
-
33
- return new Proxy([] as unknown as ArrowProxy, {
34
- get(_, prop) {
35
- if (prop === "get") return getValue;
36
- if (prop === "set") return setValue;
37
- const eid = Number(prop);
38
- if (Number.isNaN(eid)) return undefined;
39
- return getValue(eid);
40
- },
41
- set(_, prop, value) {
42
- const eid = Number(prop);
43
- if (Number.isNaN(eid)) return false;
44
- setValue(eid, value);
45
- return true;
46
- },
47
- });
48
- }
29
+ const data = ArrowData.data;
49
30
 
50
31
  export const Arrow: {
51
- start: ArrowProxy;
52
- end: ArrowProxy;
53
- size: ArrowProxy;
32
+ start: FieldProxy;
33
+ end: FieldProxy;
34
+ size: FieldProxy;
54
35
  } = {
55
- start: arrowProxy(0),
56
- end: arrowProxy(1),
57
- size: arrowProxy(2),
36
+ start: createFieldProxy(data, 4, 0),
37
+ end: createFieldProxy(data, 4, 1),
38
+ size: createFieldProxy(data, 4, 2),
58
39
  };
59
40
 
60
41
  setTraits(Arrow, {
@@ -63,11 +44,6 @@ setTraits(Arrow, {
63
44
  end: 1,
64
45
  size: 1,
65
46
  }),
66
- accessors: {
67
- start: Arrow.start,
68
- end: Arrow.end,
69
- size: Arrow.size,
70
- },
71
47
  });
72
48
 
73
49
  export interface ArrowsConfig {
@@ -87,16 +63,7 @@ struct VertexOutput {
87
63
  @location(0) color: vec4<f32>,
88
64
  }
89
65
 
90
- struct Scene {
91
- viewProj: mat4x4<f32>,
92
- cameraWorld: mat4x4<f32>,
93
- ambientColor: vec4<f32>,
94
- sunDirection: vec4<f32>,
95
- sunColor: vec4<f32>,
96
- cameraMode: f32,
97
- cameraSize: f32,
98
- viewport: vec2<f32>,
99
- }
66
+ ${SCENE_STRUCT_WGSL}
100
67
 
101
68
  struct ArrowData {
102
69
  start: f32,
@@ -133,48 +100,40 @@ fn vs(@builtin(vertex_index) vid: u32, @builtin(instance_index) iid: u32) -> Ver
133
100
  let line = lines[eid];
134
101
  let transform = matrices[eid];
135
102
 
136
- // Extract scale from transform matrix (use X axis scale)
137
103
  let scale = length(transform[0].xyz);
138
104
 
139
105
  let start = transform[3].xyz;
140
106
  let rotation = mat3x3<f32>(transform[0].xyz, transform[1].xyz, transform[2].xyz);
141
107
  let end = start + rotation * line.offset;
142
108
 
143
- // Project start and end to clip space
144
109
  let startClip = scene.viewProj * vec4(start, 1.0);
145
110
  let endClip = scene.viewProj * vec4(end, 1.0);
146
111
 
147
- // Convert to screen space (pixels from center)
148
112
  let startScreen = (startClip.xy / startClip.w) * scene.viewport * 0.5;
149
113
  let endScreen = (endClip.xy / endClip.w) * scene.viewport * 0.5;
150
114
 
151
- // Anchor point in screen space
152
115
  let anchorScreen = select(startScreen, endScreen, isEnd);
153
116
  let anchorDepth = select(startClip.z / startClip.w, endClip.z / endClip.w, isEnd);
154
117
 
155
- // Line direction in screen space (correct for aspect ratio)
156
118
  let dir = endScreen - startScreen;
157
119
  let len = length(dir);
158
120
  let normDir = select(vec2(1.0, 0.0), dir / len, len > 0.0001);
159
121
  let perp = vec2(-normDir.y, normDir.x);
160
122
 
161
- // Arrow direction (pointing away from line)
162
123
  let arrowDir = select(-normDir, normDir, isEnd);
163
124
 
164
- // Arrow dimensions in pixels
165
- let arrowLengthPx = arrow.size * line.thickness * 4.0 * scale;
166
- let arrowWidthPx = arrow.size * line.thickness * 2.0 * scale;
125
+ let viewportScale = scene.viewport.y / 1080.0;
126
+ let arrowLengthPx = arrow.size * line.thickness * 4.0 * scale * viewportScale;
127
+ let arrowWidthPx = arrow.size * line.thickness * 2.0 * scale * viewportScale;
167
128
 
168
- // Build triangle in screen space
169
129
  var posScreen: vec2<f32>;
170
130
  switch vid {
171
- case 0u: { posScreen = anchorScreen; } // Tip
131
+ case 0u: { posScreen = anchorScreen; }
172
132
  case 1u: { posScreen = anchorScreen - arrowDir * arrowLengthPx + perp * arrowWidthPx; }
173
133
  case 2u: { posScreen = anchorScreen - arrowDir * arrowLengthPx - perp * arrowWidthPx; }
174
134
  default: { posScreen = anchorScreen; }
175
135
  }
176
136
 
177
- // Convert back to NDC
178
137
  let pos = posScreen / (scene.viewport * 0.5);
179
138
 
180
139
  var out: VertexOutput;
@@ -252,7 +211,7 @@ function createArrowsDraw(config: ArrowsConfig): Draw {
252
211
 
253
212
  return {
254
213
  id: "arrows",
255
- pass: Pass.Transparent,
214
+ pass: Pass.Overlay,
256
215
  order: 1,
257
216
 
258
217
  execute() {},
@@ -285,13 +244,13 @@ function createArrowsDraw(config: ArrowsConfig): Draw {
285
244
  };
286
245
  }
287
246
 
288
- export interface ArrowsState {
247
+ export interface Arrows {
289
248
  buffer: GPUBuffer;
290
249
  entityIds: GPUBuffer;
291
250
  count: number;
292
251
  }
293
252
 
294
- export const Arrows = resource<ArrowsState>("arrows");
253
+ export const Arrows = resource<Arrows>("arrows");
295
254
 
296
255
  const arrowEntityIdArray = new Uint32Array(MAX_ENTITIES * 2);
297
256
 
@@ -338,7 +297,7 @@ export const ArrowsPlugin: Plugin = {
338
297
 
339
298
  const { device } = compute;
340
299
 
341
- const arrowsState: ArrowsState = {
300
+ const arrowsState: Arrows = {
342
301
  buffer: device.createBuffer({
343
302
  label: "arrows",
344
303
  size: MAX_ENTITIES * 4 * 4,
@@ -1,8 +1,7 @@
1
1
  import { MAX_ENTITIES, resource } from "../../core";
2
2
  import { setTraits, type FieldAccessor } from "../../core/component";
3
3
  import type { Plugin, State, System } from "../../core";
4
- import { Compute, type ComputeNode, type ExecutionContext } from "../../standard/compute";
5
- import { Pass } from "../../standard/render/pass";
4
+ import { Canvas, Compute, type ComputeNode, type ExecutionContext } from "../../standard/compute";
6
5
 
7
6
  export type PhysicsConfig = {
8
7
  springConstant: number;
@@ -12,8 +11,8 @@ export type PhysicsConfig = {
12
11
  };
13
12
 
14
13
  export const DEFAULT_PHYSICS_CONFIG: PhysicsConfig = {
15
- springConstant: 0.0002,
16
- damping: 0.95,
14
+ springConstant: 0.72,
15
+ damping: 0.046,
17
16
  bounds: { min: -20, max: 120 },
18
17
  targetThreshold: 5,
19
18
  };
@@ -136,8 +135,8 @@ function generateBubbles(
136
135
  const x = physics.bounds.min + random() * range;
137
136
  const y = physics.bounds.min + random() * range;
138
137
  const color = generateHslColor(random);
139
- const vx = (random() - 0.5) * 0.3;
140
- const vy = (random() - 0.5) * 0.3;
138
+ const vx = (random() - 0.5) * 18;
139
+ const vy = (random() - 0.5) * 18;
141
140
  const targetX = physics.bounds.min + random() * range;
142
141
  const targetY = physics.bounds.min + random() * range;
143
142
  bubbles.push({ x, y, color, vx, vy, targetX, targetY });
@@ -155,17 +154,22 @@ function distance(x1: number, y1: number, x2: number, y2: number): number {
155
154
  return Math.sqrt(dx * dx + dy * dy);
156
155
  }
157
156
 
158
- function stepBubble(bubble: Bubble, physics: PhysicsConfig = DEFAULT_PHYSICS_CONFIG): Bubble {
157
+ function stepBubble(
158
+ bubble: Bubble,
159
+ dt: number,
160
+ physics: PhysicsConfig = DEFAULT_PHYSICS_CONFIG
161
+ ): Bubble {
159
162
  let { x, y, vx, vy, targetX, targetY, color } = bubble;
160
163
 
161
- vx += (targetX - x) * physics.springConstant;
162
- vy += (targetY - y) * physics.springConstant;
164
+ vx += (targetX - x) * physics.springConstant * dt;
165
+ vy += (targetY - y) * physics.springConstant * dt;
163
166
 
164
- vx *= physics.damping;
165
- vy *= physics.damping;
167
+ const dampingFactor = Math.pow(physics.damping, dt);
168
+ vx *= dampingFactor;
169
+ vy *= dampingFactor;
166
170
 
167
- x += vx;
168
- y += vy;
171
+ x += vx * dt;
172
+ y += vy * dt;
169
173
 
170
174
  x = clamp(x, physics.bounds.min, physics.bounds.max);
171
175
  y = clamp(y, physics.bounds.min, physics.bounds.max);
@@ -427,23 +431,9 @@ setTraits(Gradient, {
427
431
  boundsMin: DEFAULT_PHYSICS_CONFIG.bounds.min,
428
432
  boundsMax: DEFAULT_PHYSICS_CONFIG.bounds.max,
429
433
  }),
430
- accessors: {
431
- angle: Gradient.angle,
432
- enabled: Gradient.enabled,
433
- bubbleSize: Gradient.bubbleSize,
434
- bubbleBlur: Gradient.bubbleBlur,
435
- textureEnabled: Gradient.textureEnabled,
436
- textureOpacity: Gradient.textureOpacity,
437
- overlayEnabled: Gradient.overlayEnabled,
438
- bubbleCount: Gradient.bubbleCount,
439
- springConstant: Gradient.springConstant,
440
- damping: Gradient.damping,
441
- boundsMin: Gradient.boundsMin,
442
- boundsMax: Gradient.boundsMax,
443
- },
444
434
  });
445
435
 
446
- export interface GradientState {
436
+ export interface Gradients {
447
437
  bubbles: Map<number, Bubble[]>;
448
438
  randoms: Map<number, () => number>;
449
439
  width: number;
@@ -470,23 +460,23 @@ export interface GradientState {
470
460
  bubbleCount: number;
471
461
  }
472
462
 
473
- export const GradientResource = resource<GradientState>("gradient");
463
+ export const Gradients = resource<Gradients>("gradient");
474
464
 
475
465
  export function clearGradientState(state: State): void {
476
- const res = GradientResource.from(state);
466
+ const res = Gradients.from(state);
477
467
  if (!res) return;
478
468
  res.bubbles.clear();
479
469
  res.randoms.clear();
480
470
  }
481
471
 
482
472
  export function getBubbles(state: State, eid: number): Bubble[] | undefined {
483
- const res = GradientResource.from(state);
473
+ const res = Gradients.from(state);
484
474
  if (!res) return undefined;
485
475
  return res.bubbles.get(eid);
486
476
  }
487
477
 
488
478
  export function setBubbles(state: State, eid: number, bubbles: Bubble[]): void {
489
- const res = GradientResource.from(state);
479
+ const res = Gradients.from(state);
490
480
  if (!res) return;
491
481
  res.bubbles.set(eid, bubbles);
492
482
  }
@@ -497,7 +487,7 @@ export function updateBubble(
497
487
  index: number,
498
488
  updater: (bubble: Bubble) => Bubble
499
489
  ): void {
500
- const res = GradientResource.from(state);
490
+ const res = Gradients.from(state);
501
491
  if (!res) return;
502
492
  const bubbles = res.bubbles.get(eid);
503
493
  if (!bubbles || index < 0 || index >= bubbles.length) return;
@@ -644,11 +634,9 @@ fn setSat(c: vec3f, s: f32) -> vec3f {
644
634
  return vec3f(0.0);
645
635
  }
646
636
 
647
- // Sort channels and apply saturation
648
637
  var result = vec3f(0.0);
649
638
  let range = cmax - cmin;
650
639
 
651
- // Apply proportional saturation to each channel
652
640
  result.r = (c.r - cmin) * s / range;
653
641
  result.g = (c.g - cmin) * s / range;
654
642
  result.b = (c.b - cmin) * s / range;
@@ -657,7 +645,6 @@ fn setSat(c: vec3f, s: f32) -> vec3f {
657
645
  }
658
646
 
659
647
  fn hueBlend(base: vec3f, blend: vec3f) -> vec3f {
660
- // W3C CSS Compositing spec: Hue = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
661
648
  let withSat = setSat(blend, sat(base));
662
649
  return setLum(withSat, lum(base));
663
650
  }
@@ -771,10 +758,9 @@ fn fs(input: VertexOutput) -> @location(0) vec4f {
771
758
  }
772
759
  `;
773
760
 
774
- function createCompositeNode(res: GradientState): ComputeNode {
761
+ function createCompositeNode(res: Gradients): ComputeNode {
775
762
  return {
776
763
  id: "gradient",
777
- pass: Pass.Opaque,
778
764
  inputs: [],
779
765
  outputs: [{ id: "scene", access: "write" }],
780
766
 
@@ -892,15 +878,14 @@ export const GradientSystem: System = {
892
878
 
893
879
  update(state: State) {
894
880
  const compute = Compute.from(state);
895
- const res = GradientResource.from(state);
896
- if (!compute || !res) return;
897
-
898
- const canvas = state.canvas;
899
- if (!canvas) return;
900
-
901
- if (res.width !== canvas.width || res.height !== canvas.height) {
902
- res.width = canvas.width;
903
- res.height = canvas.height;
881
+ const res = Gradients.from(state);
882
+ const canvas = Canvas.from(state);
883
+ if (!compute || !res || !canvas) return;
884
+
885
+ const { element } = canvas;
886
+ if (res.width !== element.width || res.height !== element.height) {
887
+ res.width = element.width;
888
+ res.height = element.height;
904
889
  }
905
890
 
906
891
  for (const eid of state.query([Gradient])) {
@@ -931,8 +916,9 @@ export const GradientSystem: System = {
931
916
  }
932
917
 
933
918
  const random = res.randoms.get(eid)!;
919
+ const dt = state.time.deltaTime;
934
920
  for (let i = 0; i < b.length; i++) {
935
- b[i] = updateBubbleTarget(stepBubble(b[i], physics), random, physics);
921
+ b[i] = updateBubbleTarget(stepBubble(b[i], dt, physics), random, physics);
936
922
  }
937
923
 
938
924
  if (!bubblesMoved(b)) continue;
@@ -1006,14 +992,12 @@ export const GradientSystem: System = {
1006
992
  },
1007
993
  };
1008
994
 
1009
- export { hashString, createSeededRandom, generateBubbles, stepBubble, parseColor };
1010
-
1011
995
  export const GradientPlugin: Plugin = {
1012
996
  systems: [GradientSystem],
1013
997
  components: { Gradient },
1014
998
 
1015
999
  initialize(state: State) {
1016
- const gradientState: GradientState = {
1000
+ const gradientState: Gradients = {
1017
1001
  bubbles: new Map(),
1018
1002
  randoms: new Map(),
1019
1003
  width: 0,
@@ -1040,7 +1024,7 @@ export const GradientPlugin: Plugin = {
1040
1024
  bubbleCount: 4,
1041
1025
  };
1042
1026
 
1043
- state.setResource(GradientResource, gradientState);
1027
+ state.setResource(Gradients, gradientState);
1044
1028
 
1045
1029
  const compute = Compute.from(state);
1046
1030
  if (compute) {