@footgun/cobalt 0.7.0 → 0.7.1

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.
@@ -1,8 +1,7 @@
1
- import cdt2d from 'cdt2d'
2
- import poly2pslg from 'poly-to-pslg'
1
+ import cdt2d from 'cdt2d'
2
+ import poly2pslg from 'poly-to-pslg'
3
3
  import { mat3, vec2 } from 'wgpu-matrix'
4
4
 
5
-
6
5
  // works similarly to the HTML Canvas transforms:
7
6
  // https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations
8
7
  export default {
@@ -13,7 +12,8 @@ export default {
13
12
  },
14
13
 
15
14
  restore: function (cobalt, node) {
16
- if (node.data.transforms.length > 1) // don't remove the identity matrix
15
+ if (node.data.transforms.length > 1)
16
+ // don't remove the identity matrix
17
17
  node.data.transforms.pop()
18
18
  },
19
19
 
@@ -32,13 +32,11 @@ export default {
32
32
  mat3.scale(m, scale, m)
33
33
  },
34
34
 
35
- strokePath: function (cobalt, node, segments, color, lineWidth=1) {
36
- for (const s of segments)
37
- line(cobalt, node, s[0], s[1], color, lineWidth)
35
+ strokePath: function (cobalt, node, segments, color, lineWidth = 1) {
36
+ for (const s of segments) line(cobalt, node, s[0], s[1], color, lineWidth)
38
37
  },
39
38
 
40
39
  filledPath: function (cobalt, node, points, color) {
41
-
42
40
  const pslg = poly2pslg(points)
43
41
  // The flag { exterior: false } tells it to remove exterior faces
44
42
  const triangles = cdt2d(pslg.points, pslg.edges, { exterior: false })
@@ -47,16 +45,18 @@ export default {
47
45
 
48
46
  let i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
49
47
 
50
-
51
48
  const currentElementCount = node.data.vertexCount * 6
52
49
  const floatsToAdd = triangles.length * 3 * 6
53
- node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
54
-
50
+ node.data.vertices = handleArrayResize(
51
+ Float32Array,
52
+ node.data.vertices,
53
+ currentElementCount,
54
+ floatsToAdd,
55
+ )
55
56
 
56
57
  const pos = vec2.create()
57
58
 
58
59
  for (const tri of triangles) {
59
-
60
60
  // pt 1
61
61
  vec2.transformMat3(points[tri[0]], m, pos)
62
62
  node.data.vertices[i + 0] = pos[0]
@@ -93,18 +93,25 @@ export default {
93
93
  i += 18
94
94
  }
95
95
 
96
- node.data.vertexCount += (3 * triangles.length)
96
+ node.data.vertexCount += 3 * triangles.length
97
97
 
98
98
  node.data.dirty = true
99
99
  },
100
100
 
101
-
102
- ellipse: function (cobalt, node, center, halfWidth, halfHeight, numSegments, color, lineWidth=1) {
103
-
104
- const [ x, y ] = center
101
+ ellipse: function (
102
+ cobalt,
103
+ node,
104
+ center,
105
+ halfWidth,
106
+ halfHeight,
107
+ numSegments,
108
+ color,
109
+ lineWidth = 1,
110
+ ) {
111
+ const [x, y] = center
105
112
 
106
113
  // angle between each segment
107
- const deltaAngle = 2 * Math.PI / numSegments
114
+ const deltaAngle = (2 * Math.PI) / numSegments
108
115
 
109
116
  // Generate points for the ellipsoid
110
117
  for (let i = 0; i < numSegments; i++) {
@@ -118,21 +125,24 @@ export default {
118
125
  const nextX = x + halfWidth * Math.cos(nextAngle)
119
126
  const nextY = y + halfHeight * Math.sin(nextAngle)
120
127
 
121
- line(cobalt, node, [ currX, currY ], [nextX, nextY ], color, lineWidth)
128
+ line(cobalt, node, [currX, currY], [nextX, nextY], color, lineWidth)
122
129
  }
123
130
  },
124
131
 
125
132
  filledEllipse: function (cobalt, node, center, halfWidth, halfHeight, numSegments, color) {
126
-
127
- const [ x, y ] = center
133
+ const [x, y] = center
128
134
 
129
135
  // angle between each segment
130
- const deltaAngle = 2 * Math.PI / numSegments
136
+ const deltaAngle = (2 * Math.PI) / numSegments
131
137
 
132
138
  const currentElementCount = node.data.vertexCount * 6
133
139
  const floatsToAdd = numSegments * 3 * 6
134
- node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
135
-
140
+ node.data.vertices = handleArrayResize(
141
+ Float32Array,
142
+ node.data.vertices,
143
+ currentElementCount,
144
+ floatsToAdd,
145
+ )
136
146
 
137
147
  const m = node.data.transforms.at(-1)
138
148
 
@@ -152,10 +162,10 @@ export default {
152
162
  // First triangle vertex (center of ellipse)
153
163
 
154
164
  const stride = 18 // 2 floats position + 4 floats color per vertex * 3 vertices
155
- const vi = (node.data.vertexCount * 6) + (i * stride)
165
+ const vi = node.data.vertexCount * 6 + i * stride
156
166
 
157
167
  // position
158
- const pos = vec2.transformMat3([ x, y ], m)
168
+ const pos = vec2.transformMat3([x, y], m)
159
169
  node.data.vertices[vi + 0] = pos[0]
160
170
  node.data.vertices[vi + 1] = pos[1]
161
171
 
@@ -164,12 +174,11 @@ export default {
164
174
  node.data.vertices[vi + 3] = color[1]
165
175
  node.data.vertices[vi + 4] = color[2]
166
176
  node.data.vertices[vi + 5] = color[3]
167
-
168
177
 
169
178
  // Second triangle vertex (current point on ellipse)
170
-
179
+
171
180
  // position
172
- vec2.transformMat3([ currX, currY ], m, pos)
181
+ vec2.transformMat3([currX, currY], m, pos)
173
182
  node.data.vertices[vi + 6] = pos[0]
174
183
  node.data.vertices[vi + 7] = pos[1]
175
184
 
@@ -179,10 +188,9 @@ export default {
179
188
  node.data.vertices[vi + 10] = color[2]
180
189
  node.data.vertices[vi + 11] = color[3]
181
190
 
182
-
183
191
  // Third triangle vertex (next point on ellipse)
184
192
  // position
185
- vec2.transformMat3([ nextX, nextY ], m, pos)
193
+ vec2.transformMat3([nextX, nextY], m, pos)
186
194
  node.data.vertices[vi + 12] = pos[0]
187
195
  node.data.vertices[vi + 13] = pos[1]
188
196
 
@@ -193,21 +201,21 @@ export default {
193
201
  node.data.vertices[vi + 17] = color[3]
194
202
  }
195
203
 
196
- node.data.vertexCount += (3 * numSegments)
204
+ node.data.vertexCount += 3 * numSegments
197
205
 
198
206
  node.data.dirty = true
199
207
  },
200
208
 
201
- box: function (cobalt, node, center, width, height, color, lineWidth=1) {
202
- const [ x, y ] = center
203
-
209
+ box: function (cobalt, node, center, width, height, color, lineWidth = 1) {
210
+ const [x, y] = center
211
+
204
212
  const halfWidth = width / 2
205
213
  const halfHeight = height / 2
206
214
 
207
- const topLeft = [ x - halfWidth, y - halfHeight ]
208
- const topRight = [ x + halfWidth, y - halfHeight ]
209
- const bottomLeft = [ x - halfWidth, y + halfHeight ]
210
- const bottomRight = [ x + halfWidth, y + halfHeight ]
215
+ const topLeft = [x - halfWidth, y - halfHeight]
216
+ const topRight = [x + halfWidth, y - halfHeight]
217
+ const bottomLeft = [x - halfWidth, y + halfHeight]
218
+ const bottomRight = [x + halfWidth, y + halfHeight]
211
219
 
212
220
  line(cobalt, node, topLeft, topRight, color, lineWidth)
213
221
  line(cobalt, node, bottomLeft, bottomRight, color, lineWidth)
@@ -216,27 +224,28 @@ export default {
216
224
  },
217
225
 
218
226
  filledBox: function (cobalt, node, center, width, height, color) {
219
-
220
- const [ x, y ] = center
221
-
227
+ const [x, y] = center
228
+
222
229
  const halfWidth = width / 2
223
230
  const halfHeight = height / 2
224
231
 
225
232
  const m = node.data.transforms.at(-1)
226
233
 
227
- const topLeft = vec2.transformMat3([ x - halfWidth, y - halfHeight ], m)
228
- const topRight = vec2.transformMat3([ x + halfWidth, y - halfHeight ], m)
229
- const bottomLeft = vec2.transformMat3([ x - halfWidth, y + halfHeight ], m)
230
- const bottomRight = vec2.transformMat3([ x + halfWidth, y + halfHeight ], m)
231
-
234
+ const topLeft = vec2.transformMat3([x - halfWidth, y - halfHeight], m)
235
+ const topRight = vec2.transformMat3([x + halfWidth, y - halfHeight], m)
236
+ const bottomLeft = vec2.transformMat3([x - halfWidth, y + halfHeight], m)
237
+ const bottomRight = vec2.transformMat3([x + halfWidth, y + halfHeight], m)
232
238
 
233
239
  const currentElementCount = node.data.vertexCount * 6
234
240
  const floatsToAdd = 6 * 6
235
- node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
236
-
237
-
238
- let i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
241
+ node.data.vertices = handleArrayResize(
242
+ Float32Array,
243
+ node.data.vertices,
244
+ currentElementCount,
245
+ floatsToAdd,
246
+ )
239
247
 
248
+ const i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
240
249
 
241
250
  // triangle 1
242
251
  // pt 1
@@ -268,7 +277,6 @@ export default {
268
277
  node.data.vertices[i + 15] = color[1]
269
278
  node.data.vertices[i + 16] = color[2]
270
279
  node.data.vertices[i + 17] = color[3]
271
-
272
280
 
273
281
  // triangle 2
274
282
  // pt 2
@@ -280,7 +288,7 @@ export default {
280
288
  node.data.vertices[i + 21] = color[1]
281
289
  node.data.vertices[i + 22] = color[2]
282
290
  node.data.vertices[i + 23] = color[3]
283
-
291
+
284
292
  // pt 3
285
293
  node.data.vertices[i + 24] = bottomRight[0]
286
294
  node.data.vertices[i + 25] = bottomRight[1]
@@ -301,7 +309,6 @@ export default {
301
309
  node.data.vertices[i + 34] = color[2]
302
310
  node.data.vertices[i + 35] = color[3]
303
311
 
304
-
305
312
  node.data.vertexCount += 6 // 2 triangles in a box, baby
306
313
 
307
314
  node.data.dirty = true
@@ -315,9 +322,7 @@ export default {
315
322
  },
316
323
  }
317
324
 
318
-
319
- function line (cobalt, node, start, end, color, lineWidth=1) {
320
-
325
+ function line(cobalt, node, start, end, color, lineWidth = 1) {
321
326
  const m = node.data.transforms.at(-1)
322
327
  start = vec2.transformMat3(start, m)
323
328
  end = vec2.transformMat3(end, m)
@@ -328,13 +333,17 @@ function line (cobalt, node, start, end, color, lineWidth=1) {
328
333
  const perp = perpendicularComponent(unitBasis)
329
334
 
330
335
  const halfLineWidth = lineWidth / 2
331
-
332
- let i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
333
336
 
337
+ const i = node.data.vertexCount * 6 // 2 floats position + 4 floats color per vertex
334
338
 
335
339
  const currentElementCount = node.data.vertexCount * 6
336
340
  const floatsToAdd = 6 * 6
337
- node.data.vertices = handleArrayResize(Float32Array, node.data.vertices, currentElementCount, floatsToAdd)
341
+ node.data.vertices = handleArrayResize(
342
+ Float32Array,
343
+ node.data.vertices,
344
+ currentElementCount,
345
+ floatsToAdd,
346
+ )
338
347
 
339
348
  // triangle 1
340
349
  // pt 1
@@ -366,7 +375,6 @@ function line (cobalt, node, start, end, color, lineWidth=1) {
366
375
  node.data.vertices[i + 15] = color[1]
367
376
  node.data.vertices[i + 16] = color[2]
368
377
  node.data.vertices[i + 17] = color[3]
369
-
370
378
 
371
379
  // triangle 2
372
380
  // pt 2
@@ -378,7 +386,7 @@ function line (cobalt, node, start, end, color, lineWidth=1) {
378
386
  node.data.vertices[i + 21] = color[1]
379
387
  node.data.vertices[i + 22] = color[2]
380
388
  node.data.vertices[i + 23] = color[3]
381
-
389
+
382
390
  // pt 3
383
391
  node.data.vertices[i + 24] = end[0] + perp[0] * halfLineWidth
384
392
  node.data.vertices[i + 25] = end[1] + perp[1] * halfLineWidth
@@ -399,36 +407,31 @@ function line (cobalt, node, start, end, color, lineWidth=1) {
399
407
  node.data.vertices[i + 34] = color[2]
400
408
  node.data.vertices[i + 35] = color[3]
401
409
 
402
-
403
410
  node.data.vertexCount += 6
404
411
  node.data.dirty = true
405
412
  }
406
413
 
407
-
408
414
  // if the new elements won't fit in the existing vertices array, resize it
409
415
  // @param ArrayType ArrayType one of the TypedArray types (Float32Array, Uint8Array, etc.)
410
416
  // @param TypedArray arr
411
- function handleArrayResize (ArrayType, arr, currentElementCount, elementsToAdd) {
417
+ function handleArrayResize(ArrayType, arr, currentElementCount, elementsToAdd) {
412
418
  // if the new vertices fit in the existing vertices array bail
413
- if ((currentElementCount + elementsToAdd) <= arr.length)
414
- return arr
419
+ if (currentElementCount + elementsToAdd <= arr.length) return arr
415
420
 
416
421
  // attempt to double the existing array size when we need more capacity
417
422
  const newSize = arr.length * 2
418
423
 
419
- const MAX_LENGTH = 16 * 1024 * 1024 / arr.BYTES_PER_ELEMENT
424
+ const MAX_LENGTH = (16 * 1024 * 1024) / arr.BYTES_PER_ELEMENT
420
425
 
421
- if (newSize > MAX_LENGTH)
422
- throw new Error('vertices exceed max array size')
426
+ if (newSize > MAX_LENGTH) throw new Error('vertices exceed max array size')
423
427
 
424
428
  const newArray = new ArrayType(newSize)
425
429
  newArray.set(arr)
426
430
  return newArray
427
431
  }
428
432
 
429
-
430
433
  // return component of vector perpendicular to a unit basis vector
431
434
  // (IMPORTANT NOTE: assumes "basis" has unit magnitude (length==1))
432
- function perpendicularComponent (inp) {
433
- return [ -inp[1], inp[0] ]
435
+ function perpendicularComponent(inp) {
436
+ return [-inp[1], inp[0]]
434
437
  }
@@ -1,17 +1,21 @@
1
1
  import getPreferredFormat from '../get-preferred-format.js'
2
2
  import sceneCompositeWGSL from './scene-composite.wgsl'
3
3
 
4
-
5
4
  export default {
6
5
  type: 'cobalt:bloom',
7
6
  refs: [
8
- { name: 'hdr', type: 'textureView', format: 'rgba16', access: 'read' },
9
- { name: 'bloom', type: 'textureView', format: 'rgba16', access: 'read' },
10
- { name: 'combined', type: 'textureView', format: 'PREFERRED_TEXTURE_FORMAT', access: 'write' },
7
+ { name: 'hdr', type: 'textureView', format: 'rgba16', access: 'read' },
8
+ { name: 'bloom', type: 'textureView', format: 'rgba16', access: 'read' },
9
+ {
10
+ name: 'combined',
11
+ type: 'textureView',
12
+ format: 'PREFERRED_TEXTURE_FORMAT',
13
+ access: 'write',
14
+ },
11
15
  ],
12
16
  // @params Object cobalt renderer world object
13
17
  // @params Object options optional data passed when initing this node
14
- onInit: async function (cobalt, options={}) {
18
+ onInit: async function (cobalt, options = {}) {
15
19
  return init(cobalt, options)
16
20
  },
17
21
 
@@ -30,24 +34,23 @@ export default {
30
34
  resize(cobalt, node)
31
35
  },
32
36
 
33
- onViewportPosition: function (cobalt, node) { },
37
+ onViewportPosition: function (cobalt, node) {},
34
38
  }
35
39
 
36
-
37
- function init (cobalt, node) {
38
- const { options, refs } = node
40
+ function init(cobalt, node) {
41
+ const { options, refs } = node
39
42
 
40
43
  const { device } = cobalt
41
44
  const format = getPreferredFormat(cobalt) // bgra8unorm or bgra8unorm-srgb usually
42
45
 
43
46
  const bloom_intensity = options.bloom_intensity ?? 40.0
44
47
  const bloom_combine_constant = options.bloom_combine_constant ?? 0.68
45
- const dat = new Float32Array([ bloom_intensity, bloom_combine_constant ])
48
+ const dat = new Float32Array([bloom_intensity, bloom_combine_constant])
46
49
  const params_buf = device.createBuffer({
47
50
  label: 'scene composite params buffer',
48
51
  size: dat.byteLength, // vec4<f32> and f32 and u32 with 4 bytes per float32 and 4 bytes per u32
49
52
  mappedAtCreation: true,
50
- usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
53
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
51
54
  })
52
55
 
53
56
  new Float32Array(params_buf.getMappedRange()).set(dat)
@@ -58,50 +61,50 @@ function init (cobalt, node) {
58
61
  label: 'scenecomposite',
59
62
  layout: 'auto',
60
63
  vertex: {
61
- module: device.createShaderModule({
62
- code: sceneCompositeWGSL,
63
- }),
64
- entryPoint: 'vert_main',
64
+ module: device.createShaderModule({
65
+ code: sceneCompositeWGSL,
66
+ }),
67
+ entryPoint: 'vert_main',
65
68
  },
66
69
  fragment: {
67
- module: device.createShaderModule({
68
- code: sceneCompositeWGSL,
69
- }),
70
- entryPoint: 'frag_main',
71
- targets: [
72
- {
73
- format,
74
- },
75
- ],
70
+ module: device.createShaderModule({
71
+ code: sceneCompositeWGSL,
72
+ }),
73
+ entryPoint: 'frag_main',
74
+ targets: [
75
+ {
76
+ format,
77
+ },
78
+ ],
76
79
  },
77
80
  primitive: {
78
- topology: 'triangle-list',
81
+ topology: 'triangle-list',
79
82
  },
80
83
  })
81
84
 
82
85
  const bindGroup = device.createBindGroup({
83
86
  layout: pipeline.getBindGroupLayout(0),
84
87
  entries: [
85
- {
86
- binding: 0,
87
- resource: refs.hdr.data.sampler,
88
- },
89
- // color
90
- {
91
- binding: 1,
92
- resource: refs.hdr.data.view,
93
- },
94
- // emissive
95
- {
96
- binding: 2,
97
- resource: refs.bloom.data.mip_view[0],
98
- },
99
- {
100
- binding: 3,
101
- resource: {
102
- buffer: params_buf,
88
+ {
89
+ binding: 0,
90
+ resource: refs.hdr.data.sampler,
91
+ },
92
+ // color
93
+ {
94
+ binding: 1,
95
+ resource: refs.hdr.data.view,
96
+ },
97
+ // emissive
98
+ {
99
+ binding: 2,
100
+ resource: refs.bloom.data.mip_view[0],
101
+ },
102
+ {
103
+ binding: 3,
104
+ resource: {
105
+ buffer: params_buf,
106
+ },
103
107
  },
104
- },
105
108
  ],
106
109
  })
107
110
 
@@ -112,20 +115,18 @@ function init (cobalt, node) {
112
115
  }
113
116
  }
114
117
 
115
-
116
118
  // combine bloom and color textures and draw to a fullscreen quad
117
- function draw (cobalt, node, commandEncoder) {
118
-
119
+ function draw(cobalt, node, commandEncoder) {
119
120
  const passEncoder = commandEncoder.beginRenderPass({
120
- label: 'scene-composite',
121
- colorAttachments: [
122
- {
123
- view: node.refs.combined.data.view, //getCurrentTextureView(cobalt)
124
- clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
125
- loadOp: 'clear',
126
- storeOp: 'store',
127
- },
128
- ],
121
+ label: 'scene-composite',
122
+ colorAttachments: [
123
+ {
124
+ view: node.refs.combined.data.view, //getCurrentTextureView(cobalt)
125
+ clearValue: { r: 0.0, g: 0.0, b: 0.0, a: 1.0 },
126
+ loadOp: 'clear',
127
+ storeOp: 'store',
128
+ },
129
+ ],
129
130
  })
130
131
 
131
132
  const { pipeline, bindGroup } = node.data
@@ -136,35 +137,33 @@ function draw (cobalt, node, commandEncoder) {
136
137
  passEncoder.end()
137
138
  }
138
139
 
139
-
140
- function resize (cobalt, node) {
140
+ function resize(cobalt, node) {
141
141
  const { pipeline, params_buf } = node.data
142
142
  const { device } = cobalt
143
143
 
144
144
  node.data.bindGroup = device.createBindGroup({
145
145
  layout: pipeline.getBindGroupLayout(0),
146
146
  entries: [
147
- {
148
- binding: 0,
149
- resource: node.refs.hdr.data.sampler,
150
- },
151
- // color
152
- {
153
- binding: 1,
154
- resource: node.refs.hdr.data.view,
155
- },
156
- // emissive
157
- {
158
- binding: 2,
159
- resource: node.refs.bloom.data.mip_view[0], //bloom_mat.bind_groups_textures[2].mip_view[0],
160
- },
161
- {
162
- binding: 3,
163
- resource: {
164
- buffer: params_buf,
147
+ {
148
+ binding: 0,
149
+ resource: node.refs.hdr.data.sampler,
150
+ },
151
+ // color
152
+ {
153
+ binding: 1,
154
+ resource: node.refs.hdr.data.view,
155
+ },
156
+ // emissive
157
+ {
158
+ binding: 2,
159
+ resource: node.refs.bloom.data.mip_view[0], //bloom_mat.bind_groups_textures[2].mip_view[0],
160
+ },
161
+ {
162
+ binding: 3,
163
+ resource: {
164
+ buffer: params_buf,
165
+ },
165
166
  },
166
- },
167
167
  ],
168
168
  })
169
169
  }
170
-