@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.
- package/CHANGELOG.md +4 -0
- package/biome.json +23 -0
- package/bundle.js +16 -14546
- package/esbuild.js +1 -1
- package/examples/01-primitives/main.js +22 -0
- package/package.json +1 -1
- package/src/bloom/bloom.js +188 -174
- package/src/cobalt.js +48 -66
- package/src/create-texture-from-buffer.js +9 -8
- package/src/create-texture-from-url.js +22 -10
- package/src/create-texture.js +15 -14
- package/src/displacement/displacement.js +42 -47
- package/src/fb-blit/fb-blit.js +34 -36
- package/src/fb-texture/fb-texture.js +30 -15
- package/src/get-preferred-format.js +3 -5
- package/src/light/light.js +30 -34
- package/src/light/public-api.js +6 -8
- package/src/primitives/constants.js +1 -1
- package/src/primitives/primitives.js +61 -64
- package/src/primitives/public-api.js +76 -73
- package/src/scene-composite/scene-composite.js +77 -78
- package/src/sprite/public-api.js +31 -46
- package/src/sprite/sprite.js +156 -154
- package/src/sprite-hdr/public-api.js +23 -38
- package/src/sprite-hdr/sprite.js +166 -165
- package/src/spritesheet/read-spritesheet.js +27 -118
- package/src/spritesheet/spritesheet.js +37 -21
- package/src/tile-hdr/atlas.js +54 -50
- package/src/tile-hdr/tile.js +40 -42
- package/src/uuid.js +2 -2
- package/src/spritesheet/create-sprite-quads.js +0 -60
package/src/fb-blit/fb-blit.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import blitWGSL from './fb-blit.wgsl'
|
|
2
1
|
import getPreferredFormat from '../get-preferred-format.js'
|
|
3
|
-
|
|
2
|
+
import blitWGSL from './fb-blit.wgsl'
|
|
4
3
|
|
|
5
4
|
// blit a source texture into a destination texture
|
|
6
5
|
|
|
@@ -13,7 +12,7 @@ export default {
|
|
|
13
12
|
|
|
14
13
|
// @params Object cobalt renderer world object
|
|
15
14
|
// @params Object options optional data passed when initing this node
|
|
16
|
-
onInit: async function (cobalt, options={}) {
|
|
15
|
+
onInit: async function (cobalt, options = {}) {
|
|
17
16
|
return init(cobalt, options)
|
|
18
17
|
},
|
|
19
18
|
|
|
@@ -31,11 +30,10 @@ export default {
|
|
|
31
30
|
resize(cobalt, node)
|
|
32
31
|
},
|
|
33
32
|
|
|
34
|
-
onViewportPosition: function (cobalt, node) {
|
|
33
|
+
onViewportPosition: function (cobalt, node) {},
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
async function init (cobalt, node) {
|
|
36
|
+
async function init(cobalt, node) {
|
|
39
37
|
const { device } = cobalt
|
|
40
38
|
|
|
41
39
|
const bindGroupLayout = device.createBindGroupLayout({
|
|
@@ -43,13 +41,13 @@ async function init (cobalt, node) {
|
|
|
43
41
|
{
|
|
44
42
|
binding: 0,
|
|
45
43
|
visibility: GPUShaderStage.FRAGMENT,
|
|
46
|
-
texture:
|
|
44
|
+
texture: {},
|
|
47
45
|
},
|
|
48
46
|
{
|
|
49
47
|
binding: 1,
|
|
50
48
|
visibility: GPUShaderStage.FRAGMENT,
|
|
51
|
-
sampler: {
|
|
52
|
-
}
|
|
49
|
+
sampler: {},
|
|
50
|
+
},
|
|
53
51
|
],
|
|
54
52
|
})
|
|
55
53
|
|
|
@@ -58,32 +56,34 @@ async function init (cobalt, node) {
|
|
|
58
56
|
entries: [
|
|
59
57
|
{
|
|
60
58
|
binding: 0,
|
|
61
|
-
resource: node.refs.in.data.view
|
|
59
|
+
resource: node.refs.in.data.view,
|
|
62
60
|
},
|
|
63
61
|
{
|
|
64
62
|
binding: 1,
|
|
65
|
-
resource: node.refs.in.data.sampler
|
|
66
|
-
}
|
|
67
|
-
]
|
|
63
|
+
resource: node.refs.in.data.sampler,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
68
66
|
})
|
|
69
67
|
|
|
70
68
|
const pipelineLayout = device.createPipelineLayout({
|
|
71
|
-
bindGroupLayouts: [
|
|
69
|
+
bindGroupLayouts: [bindGroupLayout],
|
|
72
70
|
})
|
|
73
71
|
|
|
74
72
|
const pipeline = device.createRenderPipeline({
|
|
75
73
|
label: 'fb-blit',
|
|
76
74
|
vertex: {
|
|
77
75
|
module: device.createShaderModule({
|
|
78
|
-
code: blitWGSL
|
|
76
|
+
code: blitWGSL,
|
|
79
77
|
}),
|
|
80
78
|
entryPoint: 'vs_main',
|
|
81
|
-
buffers: [
|
|
79
|
+
buffers: [
|
|
80
|
+
/*quad.bufferLayout*/
|
|
81
|
+
],
|
|
82
82
|
},
|
|
83
83
|
|
|
84
84
|
fragment: {
|
|
85
85
|
module: device.createShaderModule({
|
|
86
|
-
code: blitWGSL
|
|
86
|
+
code: blitWGSL,
|
|
87
87
|
}),
|
|
88
88
|
entryPoint: 'fs_main',
|
|
89
89
|
targets: [
|
|
@@ -96,18 +96,18 @@ async function init (cobalt, node) {
|
|
|
96
96
|
},
|
|
97
97
|
alpha: {
|
|
98
98
|
srcFactor: 'zero',
|
|
99
|
-
dstFactor: 'one'
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
]
|
|
99
|
+
dstFactor: 'one',
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
104
|
},
|
|
105
105
|
|
|
106
106
|
primitive: {
|
|
107
|
-
topology: 'triangle-list'
|
|
107
|
+
topology: 'triangle-list',
|
|
108
108
|
},
|
|
109
109
|
|
|
110
|
-
layout: pipelineLayout
|
|
110
|
+
layout: pipelineLayout,
|
|
111
111
|
})
|
|
112
112
|
|
|
113
113
|
return {
|
|
@@ -117,10 +117,9 @@ async function init (cobalt, node) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
function draw (cobalt, node, commandEncoder) {
|
|
120
|
+
function draw(cobalt, node, commandEncoder) {
|
|
122
121
|
const { device } = cobalt
|
|
123
|
-
|
|
122
|
+
|
|
124
123
|
const renderpass = commandEncoder.beginRenderPass({
|
|
125
124
|
label: 'fb-blit',
|
|
126
125
|
colorAttachments: [
|
|
@@ -128,9 +127,9 @@ function draw (cobalt, node, commandEncoder) {
|
|
|
128
127
|
view: node.refs.out,
|
|
129
128
|
clearValue: cobalt.clearValue,
|
|
130
129
|
loadOp: 'load',
|
|
131
|
-
storeOp: 'store'
|
|
132
|
-
}
|
|
133
|
-
]
|
|
130
|
+
storeOp: 'store',
|
|
131
|
+
},
|
|
132
|
+
],
|
|
134
133
|
})
|
|
135
134
|
|
|
136
135
|
renderpass.setPipeline(node.data.pipeline)
|
|
@@ -142,8 +141,7 @@ function draw (cobalt, node, commandEncoder) {
|
|
|
142
141
|
renderpass.end()
|
|
143
142
|
}
|
|
144
143
|
|
|
145
|
-
|
|
146
|
-
function resize (cobalt, node) {
|
|
144
|
+
function resize(cobalt, node) {
|
|
147
145
|
const { device } = cobalt
|
|
148
146
|
|
|
149
147
|
// re-build the bind group
|
|
@@ -152,12 +150,12 @@ function resize (cobalt, node) {
|
|
|
152
150
|
entries: [
|
|
153
151
|
{
|
|
154
152
|
binding: 0,
|
|
155
|
-
resource: node.refs.in.data.view
|
|
153
|
+
resource: node.refs.in.data.view,
|
|
156
154
|
},
|
|
157
155
|
{
|
|
158
156
|
binding: 1,
|
|
159
|
-
resource: node.refs.in.data.sampler
|
|
160
|
-
}
|
|
161
|
-
]
|
|
157
|
+
resource: node.refs.in.data.sampler,
|
|
158
|
+
},
|
|
159
|
+
],
|
|
162
160
|
})
|
|
163
161
|
}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import createTexture
|
|
1
|
+
import createTexture from '../create-texture.js'
|
|
2
2
|
import getPreferredFormat from '../get-preferred-format.js'
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
// Frame buffer textures automatically resize to match the cobalt viewport.
|
|
6
5
|
|
|
7
6
|
export default {
|
|
8
7
|
type: 'fbTexture',
|
|
9
|
-
refs: [
|
|
8
|
+
refs: [],
|
|
10
9
|
|
|
11
10
|
// @params Object cobalt renderer world object
|
|
12
11
|
// @params Object options optional data passed when initing this node
|
|
13
|
-
onInit: async function (cobalt, options={}) {
|
|
12
|
+
onInit: async function (cobalt, options = {}) {
|
|
14
13
|
return init(cobalt, options)
|
|
15
14
|
},
|
|
16
15
|
|
|
@@ -28,32 +27,48 @@ export default {
|
|
|
28
27
|
resize(cobalt, node)
|
|
29
28
|
},
|
|
30
29
|
|
|
31
|
-
onViewportPosition: function (cobalt, node) {
|
|
30
|
+
onViewportPosition: function (cobalt, node) {},
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
async function init (cobalt, node) {
|
|
33
|
+
async function init(cobalt, node) {
|
|
36
34
|
const { device } = cobalt
|
|
37
35
|
|
|
38
|
-
node.options.format =
|
|
36
|
+
node.options.format =
|
|
37
|
+
node.options.format === 'PREFERRED_TEXTURE_FORMAT'
|
|
38
|
+
? getPreferredFormat(cobalt)
|
|
39
|
+
: node.options.format
|
|
39
40
|
|
|
40
41
|
const { format, label, mip_count, usage, viewportScale } = node.options
|
|
41
42
|
|
|
42
|
-
return createTexture(
|
|
43
|
+
return createTexture(
|
|
44
|
+
device,
|
|
45
|
+
label,
|
|
46
|
+
cobalt.viewport.width * viewportScale,
|
|
47
|
+
cobalt.viewport.height * viewportScale,
|
|
48
|
+
mip_count,
|
|
49
|
+
format,
|
|
50
|
+
usage,
|
|
51
|
+
)
|
|
43
52
|
}
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
function destroy (node) {
|
|
54
|
+
function destroy(node) {
|
|
47
55
|
// destroy the existing texture before we re-create it to avoid leaking memory
|
|
48
56
|
node.data.texture.destroy()
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
function resize (cobalt, node) {
|
|
59
|
+
function resize(cobalt, node) {
|
|
53
60
|
const { device } = cobalt
|
|
54
|
-
|
|
61
|
+
destroy(node)
|
|
55
62
|
const { width, height } = cobalt.viewport
|
|
56
63
|
const { options } = node
|
|
57
64
|
const scale = node.options.viewportScale
|
|
58
|
-
node.data = createTexture(
|
|
65
|
+
node.data = createTexture(
|
|
66
|
+
device,
|
|
67
|
+
options.label,
|
|
68
|
+
width * scale,
|
|
69
|
+
height * scale,
|
|
70
|
+
options.mip_count,
|
|
71
|
+
options.format,
|
|
72
|
+
options.usage,
|
|
73
|
+
)
|
|
59
74
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// so far this seems to be 'bgra8unorm' on macos/windows, 'bgra8unorm-srgb' on linux
|
|
2
|
-
export default function getPreferredFormat
|
|
3
|
-
if (cobalt.canvas)
|
|
4
|
-
|
|
5
|
-
else
|
|
6
|
-
return cobalt.context.getPreferredFormat()
|
|
2
|
+
export default function getPreferredFormat(cobalt) {
|
|
3
|
+
if (cobalt.canvas) return navigator.gpu?.getPreferredCanvasFormat()
|
|
4
|
+
else return cobalt.context.getPreferredFormat()
|
|
7
5
|
}
|
package/src/light/light.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import getPreferredFormat from
|
|
1
|
+
import getPreferredFormat from '../get-preferred-format.js'
|
|
2
|
+
import { LightsBuffer } from './lights-buffer.js'
|
|
3
|
+
import { LightsRenderer } from './lights-renderer.js'
|
|
2
4
|
import * as publicAPI from './public-api.js'
|
|
3
|
-
import { Viewport } from
|
|
4
|
-
import { LightsRenderer } from './lights-renderer.js';
|
|
5
|
-
import { LightsBuffer } from './lights-buffer.js';
|
|
6
|
-
|
|
5
|
+
import { Viewport } from './viewport'
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* 2D lighting and Shadows
|
|
@@ -43,7 +42,7 @@ export default {
|
|
|
43
42
|
|
|
44
43
|
onViewportPosition: function (cobalt, node) {
|
|
45
44
|
// runs when the viewport position changes
|
|
46
|
-
node.data.viewport.setTopLeft(...cobalt.viewport.position)
|
|
45
|
+
node.data.viewport.setTopLeft(...cobalt.viewport.position)
|
|
47
46
|
},
|
|
48
47
|
|
|
49
48
|
// optional
|
|
@@ -52,15 +51,13 @@ export default {
|
|
|
52
51
|
},
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
|
|
56
54
|
async function init(cobalt, node) {
|
|
57
|
-
|
|
58
55
|
const { device } = cobalt
|
|
59
56
|
|
|
60
57
|
// a 2048x2048 light texture with 4 channels (rgba) with each light lighting a 256x256 region can hold 256 lights
|
|
61
|
-
const MAX_LIGHT_COUNT = 256
|
|
62
|
-
const MAX_LIGHT_SIZE = 256
|
|
63
|
-
const lightsBuffer = new LightsBuffer(device, MAX_LIGHT_COUNT)
|
|
58
|
+
const MAX_LIGHT_COUNT = 256
|
|
59
|
+
const MAX_LIGHT_SIZE = 256
|
|
60
|
+
const lightsBuffer = new LightsBuffer(device, MAX_LIGHT_COUNT)
|
|
64
61
|
|
|
65
62
|
const viewport = new Viewport({
|
|
66
63
|
viewportSize: {
|
|
@@ -69,13 +66,13 @@ async function init(cobalt, node) {
|
|
|
69
66
|
},
|
|
70
67
|
center: cobalt.viewport.position,
|
|
71
68
|
zoom: cobalt.viewport.zoom,
|
|
72
|
-
})
|
|
69
|
+
})
|
|
73
70
|
|
|
74
71
|
const lightsRenderer = new LightsRenderer({
|
|
75
72
|
device,
|
|
76
73
|
albedo: {
|
|
77
74
|
view: node.refs.in.data.view,
|
|
78
|
-
sampler: node.refs.in.data.sampler
|
|
75
|
+
sampler: node.refs.in.data.sampler,
|
|
79
76
|
},
|
|
80
77
|
targetTexture: node.refs.out.data.texture,
|
|
81
78
|
lightsBuffer,
|
|
@@ -83,10 +80,10 @@ async function init(cobalt, node) {
|
|
|
83
80
|
resolutionPerLight: MAX_LIGHT_SIZE,
|
|
84
81
|
maxLightSize: MAX_LIGHT_SIZE,
|
|
85
82
|
antialiased: false,
|
|
86
|
-
filtering:
|
|
83
|
+
filtering: 'nearest',
|
|
87
84
|
textureFormat: getPreferredFormat(cobalt),
|
|
88
85
|
},
|
|
89
|
-
})
|
|
86
|
+
})
|
|
90
87
|
|
|
91
88
|
return {
|
|
92
89
|
lightsBuffer,
|
|
@@ -101,20 +98,19 @@ async function init(cobalt, node) {
|
|
|
101
98
|
}
|
|
102
99
|
}
|
|
103
100
|
|
|
104
|
-
|
|
105
101
|
function draw(cobalt, node, commandEncoder) {
|
|
106
102
|
if (node.data.lightsBufferNeedsUpdate) {
|
|
107
|
-
const lightsBuffer = node.data.lightsBuffer
|
|
108
|
-
lightsBuffer.setLights(node.data.lights)
|
|
109
|
-
node.data.lightsBufferNeedsUpdate = false
|
|
110
|
-
node.data.lightsTextureNeedsUpdate = true
|
|
103
|
+
const lightsBuffer = node.data.lightsBuffer
|
|
104
|
+
lightsBuffer.setLights(node.data.lights)
|
|
105
|
+
node.data.lightsBufferNeedsUpdate = false
|
|
106
|
+
node.data.lightsTextureNeedsUpdate = true
|
|
111
107
|
}
|
|
112
108
|
|
|
113
|
-
const lightsRenderer = node.data.lightsRenderer
|
|
109
|
+
const lightsRenderer = node.data.lightsRenderer
|
|
114
110
|
|
|
115
111
|
if (node.data.lightsTextureNeedsUpdate) {
|
|
116
|
-
lightsRenderer.computeLightsTexture(commandEncoder)
|
|
117
|
-
node.data.lightsTextureNeedsUpdate = false
|
|
112
|
+
lightsRenderer.computeLightsTexture(commandEncoder)
|
|
113
|
+
node.data.lightsTextureNeedsUpdate = false
|
|
118
114
|
}
|
|
119
115
|
|
|
120
116
|
const renderpass = commandEncoder.beginRenderPass({
|
|
@@ -124,28 +120,28 @@ function draw(cobalt, node, commandEncoder) {
|
|
|
124
120
|
view: node.refs.out.data.view,
|
|
125
121
|
clearValue: cobalt.clearValue,
|
|
126
122
|
loadOp: 'load',
|
|
127
|
-
storeOp: 'store'
|
|
128
|
-
}
|
|
129
|
-
]
|
|
123
|
+
storeOp: 'store',
|
|
124
|
+
},
|
|
125
|
+
],
|
|
130
126
|
})
|
|
131
127
|
|
|
132
|
-
node.data.viewport.setZoom(cobalt.viewport.zoom)
|
|
133
|
-
const invertVpMatrix = node.data.viewport.invertViewProjectionMatrix
|
|
134
|
-
lightsRenderer.render(renderpass, invertVpMatrix)
|
|
128
|
+
node.data.viewport.setZoom(cobalt.viewport.zoom)
|
|
129
|
+
const invertVpMatrix = node.data.viewport.invertViewProjectionMatrix
|
|
130
|
+
lightsRenderer.render(renderpass, invertVpMatrix)
|
|
135
131
|
|
|
136
132
|
renderpass.end()
|
|
137
133
|
}
|
|
138
134
|
|
|
139
135
|
function destroy(node) {
|
|
140
|
-
node.data.lightsBuffer.destroy()
|
|
141
|
-
node.data.lightsRenderer.destroy()
|
|
136
|
+
node.data.lightsBuffer.destroy()
|
|
137
|
+
node.data.lightsRenderer.destroy()
|
|
142
138
|
}
|
|
143
139
|
|
|
144
140
|
function resize(cobalt, node) {
|
|
145
141
|
node.data.lightsRenderer.setAlbedo({
|
|
146
142
|
view: node.refs.in.data.view,
|
|
147
|
-
sampler: node.refs.in.data.sampler
|
|
148
|
-
})
|
|
143
|
+
sampler: node.refs.in.data.sampler,
|
|
144
|
+
})
|
|
149
145
|
|
|
150
|
-
node.data.viewport.setViewportSize(cobalt.viewport.width, cobalt.viewport.height)
|
|
146
|
+
node.data.viewport.setViewportSize(cobalt.viewport.width, cobalt.viewport.height)
|
|
151
147
|
}
|
package/src/light/public-api.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import uuid from '../uuid.js'
|
|
2
1
|
import { vec2 } from 'wgpu-matrix'
|
|
3
|
-
|
|
2
|
+
import uuid from '../uuid.js'
|
|
4
3
|
|
|
5
4
|
// public API to interact with a lighting/shadows node.
|
|
6
5
|
|
|
7
6
|
export function setLights(cobalt, node, lights) {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
node.data.lights = lights
|
|
8
|
+
node.data.lightsBufferNeedsUpdate = true
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
export function setAmbientLight(cobalt, node, color) {
|
|
13
|
-
|
|
12
|
+
node.data.lightsRenderer.setAmbientLight(color)
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export function setOccluders(cobalt, node, segmentsList) {
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
node.data.lightsRenderer.setObstacles(segmentsList)
|
|
17
|
+
node.data.lightsTextureNeedsUpdate = true
|
|
19
18
|
}
|
|
20
|
-
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const FLOAT32S_PER_SPRITE = 12 // vec2(translate) + vec2(scale) + vec4(tint) + opacity + rotation + emissiveIntensity + sortValue
|
|
1
|
+
export const FLOAT32S_PER_SPRITE = 12 // vec2(translate) + vec2(scale) + vec4(tint) + opacity + rotation + emissiveIntensity + sortValue
|
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { FLOAT32S_PER_SPRITE }
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
1
|
+
import round from 'round-half-up-symmetric'
|
|
2
|
+
import { mat3, mat4, vec2, vec3 } from 'wgpu-matrix'
|
|
3
|
+
import getPreferredFormat from '../get-preferred-format.js'
|
|
4
|
+
import { FLOAT32S_PER_SPRITE } from './constants.js'
|
|
5
|
+
import primitivesWGSL from './primitives.wgsl'
|
|
6
|
+
import publicAPI from './public-api.js'
|
|
8
7
|
|
|
9
8
|
// a graphics primitives renderer (lines, boxes, etc.)
|
|
10
9
|
|
|
11
|
-
|
|
12
10
|
// temporary variables, allocated once to avoid garbage collection
|
|
13
11
|
const _tmpVec3 = vec3.create(0, 0, 0)
|
|
14
12
|
|
|
15
|
-
|
|
16
13
|
export default {
|
|
17
14
|
type: 'cobalt:primitives',
|
|
18
|
-
refs: [
|
|
19
|
-
{ name: 'color', type: 'textView', format: 'PREFERRED_TEXTURE_VIEW', access: 'write' },
|
|
20
|
-
],
|
|
15
|
+
refs: [{ name: 'color', type: 'textView', format: 'PREFERRED_TEXTURE_VIEW', access: 'write' }],
|
|
21
16
|
|
|
22
17
|
// cobalt event handling functions
|
|
23
18
|
|
|
24
19
|
// @params Object cobalt renderer world object
|
|
25
20
|
// @params Object options optional data passed when initing this node
|
|
26
|
-
onInit: async function (cobalt, options={}) {
|
|
21
|
+
onInit: async function (cobalt, options = {}) {
|
|
27
22
|
return init(cobalt, options)
|
|
28
23
|
},
|
|
29
24
|
|
|
@@ -50,9 +45,8 @@ export default {
|
|
|
50
45
|
customFunctions: publicAPI,
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
|
|
54
48
|
// This corresponds to a WebGPU render pass. It handles 1 sprite layer.
|
|
55
|
-
async function init
|
|
49
|
+
async function init(cobalt, node) {
|
|
56
50
|
const { device } = cobalt
|
|
57
51
|
|
|
58
52
|
// Define vertices and indices for your line represented as two triangles (a rectangle)
|
|
@@ -70,10 +64,9 @@ async function init (cobalt, node) {
|
|
|
70
64
|
//new Float32Array(vertexBuffer.getMappedRange()).set(vertices);
|
|
71
65
|
//vertexBuffer.unmap()
|
|
72
66
|
|
|
73
|
-
|
|
74
67
|
const uniformBuffer = device.createBuffer({
|
|
75
68
|
size: 64 * 2, // 4x4 matrix with 4 bytes per float32, times 2 matrices (view, projection)
|
|
76
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
69
|
+
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
77
70
|
})
|
|
78
71
|
|
|
79
72
|
// Shader modules
|
|
@@ -86,13 +79,13 @@ async function init (cobalt, node) {
|
|
|
86
79
|
{
|
|
87
80
|
binding: 0,
|
|
88
81
|
visibility: GPUShaderStage.VERTEX,
|
|
89
|
-
buffer: {
|
|
82
|
+
buffer: {},
|
|
90
83
|
},
|
|
91
84
|
],
|
|
92
85
|
})
|
|
93
86
|
|
|
94
87
|
const pipelineLayout = device.createPipelineLayout({
|
|
95
|
-
bindGroupLayouts: [
|
|
88
|
+
bindGroupLayouts: [bindGroupLayout],
|
|
96
89
|
})
|
|
97
90
|
|
|
98
91
|
const bindGroup = device.createBindGroup({
|
|
@@ -101,37 +94,39 @@ async function init (cobalt, node) {
|
|
|
101
94
|
{
|
|
102
95
|
binding: 0,
|
|
103
96
|
resource: {
|
|
104
|
-
buffer: uniformBuffer
|
|
105
|
-
}
|
|
97
|
+
buffer: uniformBuffer,
|
|
98
|
+
},
|
|
106
99
|
},
|
|
107
|
-
]
|
|
100
|
+
],
|
|
108
101
|
})
|
|
109
102
|
|
|
110
103
|
// Create render pipeline
|
|
111
104
|
const pipeline = device.createRenderPipeline({
|
|
112
|
-
label:
|
|
105
|
+
label: 'primitives',
|
|
113
106
|
layout: pipelineLayout,
|
|
114
107
|
vertex: {
|
|
115
108
|
module: shaderModule,
|
|
116
109
|
entryPoint: 'vs_main',
|
|
117
|
-
buffers: [
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
110
|
+
buffers: [
|
|
111
|
+
{
|
|
112
|
+
arrayStride: 6 * Float32Array.BYTES_PER_ELEMENT, // 2 floats per vertex position + 4 floats per vertex color
|
|
113
|
+
//stepMode: 'vertex',
|
|
114
|
+
attributes: [
|
|
115
|
+
// position
|
|
116
|
+
{
|
|
117
|
+
shaderLocation: 0,
|
|
118
|
+
offset: 0,
|
|
119
|
+
format: 'float32x2',
|
|
120
|
+
},
|
|
121
|
+
// color
|
|
122
|
+
{
|
|
123
|
+
shaderLocation: 1,
|
|
124
|
+
format: 'float32x4',
|
|
125
|
+
offset: 8,
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
},
|
|
129
|
+
],
|
|
135
130
|
},
|
|
136
131
|
fragment: {
|
|
137
132
|
module: shaderModule,
|
|
@@ -146,9 +141,9 @@ async function init (cobalt, node) {
|
|
|
146
141
|
},
|
|
147
142
|
alpha: {
|
|
148
143
|
srcFactor: 'zero',
|
|
149
|
-
dstFactor: 'one'
|
|
150
|
-
}
|
|
151
|
-
}
|
|
144
|
+
dstFactor: 'one',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
152
147
|
},
|
|
153
148
|
],
|
|
154
149
|
},
|
|
@@ -157,7 +152,6 @@ async function init (cobalt, node) {
|
|
|
157
152
|
},
|
|
158
153
|
})
|
|
159
154
|
|
|
160
|
-
|
|
161
155
|
return {
|
|
162
156
|
uniformBuffer, // perspective and view matrices for the camera
|
|
163
157
|
vertexBuffer,
|
|
@@ -173,14 +167,13 @@ async function init (cobalt, node) {
|
|
|
173
167
|
// saving/restoring will push/pop transforms off of this stack.
|
|
174
168
|
// works very similarly to HTML Canvas's transforms.
|
|
175
169
|
// https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations
|
|
176
|
-
transforms: [
|
|
170
|
+
transforms: [mat3.identity()],
|
|
177
171
|
}
|
|
178
172
|
}
|
|
179
173
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (node.data.vertexCount === 0) // no primitives to draw, bail
|
|
174
|
+
function draw(cobalt, node, commandEncoder) {
|
|
175
|
+
if (node.data.vertexCount === 0)
|
|
176
|
+
// no primitives to draw, bail
|
|
184
177
|
return
|
|
185
178
|
|
|
186
179
|
const { device } = cobalt
|
|
@@ -198,13 +191,19 @@ function draw (cobalt, node, commandEncoder) {
|
|
|
198
191
|
})
|
|
199
192
|
}
|
|
200
193
|
|
|
201
|
-
|
|
194
|
+
const byteCount = node.data.vertexCount * stride
|
|
202
195
|
if (byteCount > node.data.vertexBuffer.size) {
|
|
203
196
|
console.error('too many primitives, bailing')
|
|
204
197
|
return
|
|
205
198
|
}
|
|
206
|
-
|
|
207
|
-
cobalt.device.queue.writeBuffer(
|
|
199
|
+
|
|
200
|
+
cobalt.device.queue.writeBuffer(
|
|
201
|
+
node.data.vertexBuffer,
|
|
202
|
+
0,
|
|
203
|
+
node.data.vertices.buffer,
|
|
204
|
+
0,
|
|
205
|
+
byteCount,
|
|
206
|
+
)
|
|
208
207
|
}
|
|
209
208
|
|
|
210
209
|
const loadOp = node.options.loadOp || 'load'
|
|
@@ -217,20 +216,19 @@ function draw (cobalt, node, commandEncoder) {
|
|
|
217
216
|
view: node.refs.color, //node.refs.color.data.view,
|
|
218
217
|
clearValue: cobalt.clearValue,
|
|
219
218
|
loadOp,
|
|
220
|
-
storeOp: 'store'
|
|
221
|
-
}
|
|
222
|
-
]
|
|
219
|
+
storeOp: 'store',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
223
222
|
})
|
|
224
223
|
|
|
225
224
|
renderpass.setPipeline(node.data.pipeline)
|
|
226
225
|
renderpass.setBindGroup(0, node.data.bindGroup)
|
|
227
226
|
renderpass.setVertexBuffer(0, node.data.vertexBuffer)
|
|
228
|
-
renderpass.draw(node.data.vertexCount)
|
|
227
|
+
renderpass.draw(node.data.vertexCount) // Draw 18 vertices, forming six triangles
|
|
229
228
|
renderpass.end()
|
|
230
229
|
}
|
|
231
230
|
|
|
232
|
-
|
|
233
|
-
function destroy (node) {
|
|
231
|
+
function destroy(node) {
|
|
234
232
|
node.data.vertexBuffer.destroy()
|
|
235
233
|
node.data.vertexBuffer = null
|
|
236
234
|
node.data.uniformBuffer.destroy()
|
|
@@ -238,20 +236,19 @@ function destroy (node) {
|
|
|
238
236
|
node.data.transforms.length = 0
|
|
239
237
|
}
|
|
240
238
|
|
|
241
|
-
|
|
242
|
-
function _writeMatricesBuffer (cobalt, node) {
|
|
239
|
+
function _writeMatricesBuffer(cobalt, node) {
|
|
243
240
|
const { device } = cobalt
|
|
244
241
|
|
|
245
242
|
const GAME_WIDTH = cobalt.viewport.width / cobalt.viewport.zoom
|
|
246
243
|
const GAME_HEIGHT = cobalt.viewport.height / cobalt.viewport.zoom
|
|
247
244
|
|
|
248
245
|
// left right bottom top near far
|
|
249
|
-
const projection = mat4.ortho(0,
|
|
246
|
+
const projection = mat4.ortho(0, GAME_WIDTH, GAME_HEIGHT, 0, -10.0, 10.0)
|
|
250
247
|
|
|
251
248
|
// TODO: 1.0 must be subtracted from both x and y values otherwise everything get shifted down and to the right
|
|
252
249
|
// when rendered. This is true for both sdl and browser backed rendering. I don't understand why though!!
|
|
253
|
-
vec3.set(-cobalt.viewport.position[0] - 1.0, -cobalt.viewport.position[1] - 1.0
|
|
254
|
-
|
|
250
|
+
vec3.set(-cobalt.viewport.position[0] - 1.0, -cobalt.viewport.position[1] - 1.0, 0, _tmpVec3)
|
|
251
|
+
|
|
255
252
|
const view = mat4.translation(_tmpVec3)
|
|
256
253
|
|
|
257
254
|
device.queue.writeBuffer(node.data.uniformBuffer, 0, view.buffer)
|