@footgun/cobalt 0.6.14 → 0.7.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.
- package/CHANGELOG.md +19 -0
- package/bundle.js +1318 -1304
- package/examples/01-primitives/index.html +1 -1
- package/examples/02-sprites/entity-sprite.js +10 -15
- package/examples/02-sprites/hdr.html +321 -0
- package/examples/02-sprites/index.html +21 -120
- package/examples/02-sprites/system-renderer.js +2 -2
- package/examples/03-tiles/index.html +87 -32
- package/examples/03-tiles/system-renderer.js +2 -2
- package/examples/04-overlay/index.html +178 -21
- package/examples/05-bloom/index.html +23 -23
- package/examples/05-bloom/system-renderer.js +2 -2
- package/examples/06-displacement/index.html +20 -112
- package/examples/06-displacement/system-renderer.js +2 -2
- package/examples/08-light/index.html +51 -123
- package/package.json +1 -1
- package/src/cobalt.js +8 -8
- package/src/sprite/public-api.js +57 -177
- package/src/sprite/sprite.js +301 -177
- package/src/sprite/sprite.wgsl +68 -87
- package/src/sprite-hdr/public-api.js +95 -0
- package/src/sprite-hdr/sprite.js +414 -0
- package/src/sprite-hdr/sprite.wgsl +101 -0
- package/src/{sprite → spritesheet}/create-sprite-quads.js +11 -11
- package/src/{sprite → spritesheet}/read-spritesheet.js +62 -28
- package/src/spritesheet/spritesheet.js +75 -0
- package/src/{tile → tile-hdr}/atlas.js +5 -3
- package/src/{tile → tile-hdr}/tile.js +15 -6
- package/examples/04-overlay/deps.js +0 -1
- package/src/overlay/constants.js +0 -1
- package/src/overlay/overlay.js +0 -343
- package/src/overlay/overlay.wgsl +0 -88
- package/src/sprite/constants.js +0 -1
- package/src/sprite/sorted-binary-insert.js +0 -45
- package/src/sprite/spritesheet.js +0 -215
- /package/examples/02-sprites/{Game.js → Global.js} +0 -0
- /package/examples/03-tiles/{Game.js → Global.js} +0 -0
- /package/examples/05-bloom/{Game.js → Global.js} +0 -0
- /package/examples/06-displacement/{Game.js → Global.js} +0 -0
- /package/examples/08-light/{Game.js → Global.js} +0 -0
- /package/src/{tile → tile-hdr}/tile.wgsl +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<title class="titleText">
|
|
5
|
+
<title class="titleText">WebGPU - Cobalt primitive rendering</title>
|
|
6
6
|
<meta name="description" content="Web GPU 2d cobalt" />
|
|
7
7
|
<meta name="author" content="Michael Reinstein" />
|
|
8
8
|
<meta name="viewport" content="width=device-width" />
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Cobalt from '../../bundle.js'
|
|
2
2
|
import animationComponent from './component-animation.js'
|
|
3
3
|
import transformComponent from './component-transform.js'
|
|
4
|
-
import { ECS, vec3, vec4 } from './deps.js'
|
|
4
|
+
import { ECS, vec2, vec3, vec4 } from './deps.js'
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
export default function spriteEntity (world, opts) {
|
|
@@ -15,28 +15,23 @@ export default function spriteEntity (world, opts) {
|
|
|
15
15
|
name: opts.name
|
|
16
16
|
}))
|
|
17
17
|
|
|
18
|
-
const tint = vec4.create(0, 0, 0, 0)
|
|
19
|
-
|
|
20
|
-
const opacity = opts.opacity ?? 255
|
|
21
|
-
|
|
22
18
|
const spriteNode = opts.spriteNode
|
|
23
19
|
|
|
24
20
|
const cobaltSpriteId = spriteNode.addSprite(opts.name,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
opts.zIndex)
|
|
21
|
+
opts.position,
|
|
22
|
+
opts.scale,
|
|
23
|
+
opts.tint,
|
|
24
|
+
opts.opacity,
|
|
25
|
+
opts.rotation)
|
|
31
26
|
|
|
32
27
|
ECS.addComponentToEntity(world, ENTITY, 'sprite', {
|
|
33
28
|
name: opts.name,
|
|
34
29
|
|
|
35
30
|
layer: opts.layer,
|
|
36
|
-
rotation:
|
|
37
|
-
scale:
|
|
38
|
-
opacity:
|
|
39
|
-
tint:
|
|
31
|
+
rotation: opts.rotation, // radians
|
|
32
|
+
scale: opts.scale,
|
|
33
|
+
opacity: opts.opacity, // 0 is transparent, 1 is opaque
|
|
34
|
+
tint: opts.tint,
|
|
40
35
|
|
|
41
36
|
// cobalt references
|
|
42
37
|
cobaltSpriteId,
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<title class="titleText">WebGPU - Cobalt HDR sprite rendering</title>
|
|
6
|
+
<meta name="description" content="Web GPU 2d cobalt" />
|
|
7
|
+
<meta name="author" content="Michael Reinstein" />
|
|
8
|
+
<meta name="viewport" content="width=device-width" />
|
|
9
|
+
<meta name="viewport" content="initial-scale=1, maximum-scale=1" />
|
|
10
|
+
|
|
11
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
12
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
13
|
+
|
|
14
|
+
<style>
|
|
15
|
+
|
|
16
|
+
body {
|
|
17
|
+
padding: 0;
|
|
18
|
+
margin: 0;
|
|
19
|
+
overscroll-behavior: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
img {
|
|
23
|
+
image-rendering: -moz-crisp-edges;
|
|
24
|
+
image-rendering: -webkit-crisp-edges;
|
|
25
|
+
image-rendering: pixelated;
|
|
26
|
+
image-rendering: crisp-edges;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.viewport-container {
|
|
30
|
+
position: fixed;
|
|
31
|
+
top: 0;
|
|
32
|
+
left: 0;
|
|
33
|
+
bottom: 0;
|
|
34
|
+
right: 0;
|
|
35
|
+
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
justify-content: center;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
canvas {
|
|
42
|
+
background-color: green;
|
|
43
|
+
border: none;
|
|
44
|
+
image-rendering: -moz-crisp-edges;
|
|
45
|
+
image-rendering: -webkit-crisp-edges;
|
|
46
|
+
image-rendering: pixelated;
|
|
47
|
+
image-rendering: crisp-edges;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
canvas::-webkit-scrollbar {
|
|
51
|
+
display: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
</style>
|
|
55
|
+
</head>
|
|
56
|
+
<body>
|
|
57
|
+
|
|
58
|
+
<div class="viewport-container">
|
|
59
|
+
<canvas id="viewport" width="480" height="270"></canvas>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<script type="module">
|
|
63
|
+
import Global from './Global.js'
|
|
64
|
+
import * as Cobalt from '../../bundle.js'
|
|
65
|
+
import constants from './constants.js'
|
|
66
|
+
import dat from 'https://cdn.skypack.dev/pin/dat.gui@v0.7.9-2wtQAdFH5SRwnJLDWGNz/mode=imports,min/optimized/dat.gui.js'
|
|
67
|
+
import debounce from 'https://cdn.skypack.dev/pin/lodash.debounce@v4.0.8-4GXU9B066R3Th6HmjZmO/lodash.debounce.js'
|
|
68
|
+
//import animationSystem from './system-animation.js'
|
|
69
|
+
import rendererSystem from './system-renderer.js'
|
|
70
|
+
import spriteEntity from './entity-sprite.js'
|
|
71
|
+
import { ECS, vec2 } from './deps.js'
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
async function main () {
|
|
75
|
+
|
|
76
|
+
const canvas = document.querySelector('canvas')
|
|
77
|
+
|
|
78
|
+
const viewportWidth = constants.GAME_WIDTH
|
|
79
|
+
const viewportHeight = constants.GAME_HEIGHT
|
|
80
|
+
Global.renderer = await Cobalt.init(canvas, viewportWidth, viewportHeight)
|
|
81
|
+
|
|
82
|
+
// instantiate all resource nodes
|
|
83
|
+
const spritesheet = await Cobalt.initNode(Global.renderer, {
|
|
84
|
+
type: 'cobalt:spritesheet',
|
|
85
|
+
refs: { },
|
|
86
|
+
options: {
|
|
87
|
+
spriteSheetJsonUrl: './assets/spritesheet.json',
|
|
88
|
+
colorTextureUrl: 'assets/spritesheet.png',
|
|
89
|
+
emissiveTextureUrl: 'assets/spritesheet_emissive.png'
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const hdrTex = await Cobalt.initNode(Global.renderer, {
|
|
94
|
+
type: 'cobalt:fbTexture',
|
|
95
|
+
refs: { },
|
|
96
|
+
options: {
|
|
97
|
+
label: 'hdr color texture',
|
|
98
|
+
format: 'rgba16float',
|
|
99
|
+
mip_count: 1,
|
|
100
|
+
viewportScale: 1.0,
|
|
101
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING,
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const emissiveTex = await Cobalt.initNode(Global.renderer, {
|
|
106
|
+
type: 'cobalt:fbTexture',
|
|
107
|
+
refs: { },
|
|
108
|
+
options: {
|
|
109
|
+
label: 'hdr emissive texture',
|
|
110
|
+
format: 'rgba16float',
|
|
111
|
+
mip_count: 1,
|
|
112
|
+
viewportScale: 1.0,
|
|
113
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const bloomTex = await Cobalt.initNode(Global.renderer, {
|
|
118
|
+
type: 'cobalt:fbTexture',
|
|
119
|
+
refs: { },
|
|
120
|
+
options: {
|
|
121
|
+
label: 'hdr bloom texture',
|
|
122
|
+
format: 'rgba16float',
|
|
123
|
+
mip_count: 7,
|
|
124
|
+
viewportScale: 0.5,
|
|
125
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING,
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const bloomNode = await Cobalt.initNode(Global.renderer, {
|
|
130
|
+
type: 'cobalt:bloom',
|
|
131
|
+
refs: {
|
|
132
|
+
// key is the var name defined in this node
|
|
133
|
+
// value is the var name in the cobalt resources dictionary
|
|
134
|
+
emissive: emissiveTex,
|
|
135
|
+
hdr: hdrTex,
|
|
136
|
+
bloom: bloomTex
|
|
137
|
+
},
|
|
138
|
+
options: {
|
|
139
|
+
// any extra options you want to pass to this node
|
|
140
|
+
bloom_intensity: 0.0,
|
|
141
|
+
bloom_knee: 0.0,
|
|
142
|
+
bloom_threshold: 0.1, // 1.0
|
|
143
|
+
/*
|
|
144
|
+
// sprite instance 1
|
|
145
|
+
sprite_instances: [
|
|
146
|
+
{
|
|
147
|
+
emissive_intensity: 1.0,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
emissive_intensity: 0.5,
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
*/
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
const tmpTex = await Cobalt.initNode(Global.renderer, {
|
|
158
|
+
type: 'cobalt:fbTexture',
|
|
159
|
+
refs: { },
|
|
160
|
+
options: {
|
|
161
|
+
label: 'bloom + hdr compositing',
|
|
162
|
+
format: 'PREFERRED_TEXTURE_FORMAT',
|
|
163
|
+
mip_count: 1,
|
|
164
|
+
viewportScale: 1.0,
|
|
165
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
// instantiate all runnable nodes
|
|
170
|
+
const spriteNode = await Cobalt.initNode(Global.renderer, {
|
|
171
|
+
type: 'cobalt:spriteHDR',
|
|
172
|
+
refs: {
|
|
173
|
+
// key is the var name defined in this node
|
|
174
|
+
// value is the var name in the cobalt resources dictionary
|
|
175
|
+
spritesheet: spritesheet,
|
|
176
|
+
emissive: emissiveTex,
|
|
177
|
+
color: hdrTex,
|
|
178
|
+
},
|
|
179
|
+
options: {
|
|
180
|
+
loadOp: 'clear',
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
const compositeNode = await Cobalt.initNode(Global.renderer, {
|
|
186
|
+
type: 'cobalt:composite',
|
|
187
|
+
refs: {
|
|
188
|
+
hdr: hdrTex,
|
|
189
|
+
bloom: bloomTex,
|
|
190
|
+
combined: tmpTex,
|
|
191
|
+
},
|
|
192
|
+
options: {
|
|
193
|
+
bloom_combine_constant: 0.0,
|
|
194
|
+
},
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
const b = await Cobalt.initNode(Global.renderer, {
|
|
199
|
+
type: 'cobalt:fbBlit',
|
|
200
|
+
refs: {
|
|
201
|
+
in: tmpTex,
|
|
202
|
+
out: 'FRAME_TEXTURE_VIEW',
|
|
203
|
+
},
|
|
204
|
+
options: { }
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
// use resizeViewport to init values on load:
|
|
209
|
+
resizeViewport(Global.renderer, window.innerWidth, window.innerHeight)
|
|
210
|
+
|
|
211
|
+
// window resize is *expensive* - best to debounce:
|
|
212
|
+
const debouncedResize = debounce(function () {
|
|
213
|
+
resizeViewport(Global.renderer, window.innerWidth, window.innerHeight)
|
|
214
|
+
}, 50)
|
|
215
|
+
|
|
216
|
+
window.addEventListener('resize', debouncedResize, { passive: true })
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
const world = ECS.createWorld()
|
|
221
|
+
ECS.addSystem(world, rendererSystem(Global.renderer))
|
|
222
|
+
|
|
223
|
+
Cobalt.setViewportPosition(Global.renderer, [ 240, 135 ])
|
|
224
|
+
|
|
225
|
+
ECS.addSystem(world, function cameraLoopSystem(world) {
|
|
226
|
+
const onUpdate = function (dt) {
|
|
227
|
+
const elapsed = performance.now()
|
|
228
|
+
const x = (Math.sin(elapsed / 2000) * 0.5 + 0.5) * 128
|
|
229
|
+
const y = (Math.sin(elapsed / 5000) * 0.5 + 0.5) * 170
|
|
230
|
+
|
|
231
|
+
Cobalt.setViewportPosition(Global.renderer, [ x, y ])
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return { onUpdate }
|
|
235
|
+
})
|
|
236
|
+
|
|
237
|
+
Global.world = world
|
|
238
|
+
|
|
239
|
+
// test sprites
|
|
240
|
+
const s2 = spriteEntity(world, {
|
|
241
|
+
name: 'health_empty-0.png',
|
|
242
|
+
position: [ 50, 20 ],
|
|
243
|
+
tint: [ 0, 0, 0, 0 ],
|
|
244
|
+
scale: [ 1, 1 ],
|
|
245
|
+
rotation: 0,
|
|
246
|
+
opacity: 1,
|
|
247
|
+
spriteNode,
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
const s = spriteEntity(world, {
|
|
251
|
+
name: 'health-0.png',
|
|
252
|
+
position: [ 260, 135 ],
|
|
253
|
+
tint: [ 0, 0, 0, 0 ],
|
|
254
|
+
scale: [ 1, 1 ],
|
|
255
|
+
rotation: 0,
|
|
256
|
+
opacity: 0.2,
|
|
257
|
+
spriteNode,
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
const s3 = spriteEntity(world, {
|
|
261
|
+
name: 'health-0.png',
|
|
262
|
+
position: [ 128, 90 ],
|
|
263
|
+
tint: [ 0, 0, 0, 0 ],
|
|
264
|
+
scale: [ 1, 1 ],
|
|
265
|
+
rotation: 0,
|
|
266
|
+
opacity: 1,
|
|
267
|
+
spriteNode,
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
const gameLoop = function () {
|
|
271
|
+
tick(Global)
|
|
272
|
+
requestAnimationFrame(gameLoop)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
requestAnimationFrame(gameLoop)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
function tick (context) {
|
|
280
|
+
const newTime = performance.now()
|
|
281
|
+
const frameTime = newTime - context.lastFrameTime
|
|
282
|
+
context.lastFrameTime = newTime
|
|
283
|
+
ECS.update(context.world, frameTime)
|
|
284
|
+
ECS.cleanup(context.world)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
function resizeViewport (renderer, width, height) {
|
|
289
|
+
|
|
290
|
+
const { canvas, device } = renderer
|
|
291
|
+
|
|
292
|
+
// determine which screen dimension is most constrained
|
|
293
|
+
// we floor the render scale to an integer because we get weird texture artifacts when trying to render at
|
|
294
|
+
// certain float values (e.g., 3.0145833333333334)
|
|
295
|
+
const renderScale = Math.floor(Math.min(width/constants.GAME_WIDTH, height/constants.GAME_HEIGHT))
|
|
296
|
+
|
|
297
|
+
canvas.width = Math.ceil(constants.GAME_WIDTH)
|
|
298
|
+
canvas.height = Math.ceil(constants.GAME_HEIGHT)
|
|
299
|
+
|
|
300
|
+
Cobalt.setViewportDimensions(renderer, constants.GAME_WIDTH, constants.GAME_HEIGHT)
|
|
301
|
+
|
|
302
|
+
// https://www.khronos.org/webgl/wiki/HandlingHighDPI
|
|
303
|
+
// webgl display resolution size within canvas
|
|
304
|
+
const resolution = window.devicePixelRatio || 1
|
|
305
|
+
|
|
306
|
+
// center the canvas if native window doesn't match aspect ratio
|
|
307
|
+
canvas.style.width = canvas.width * renderScale + 'px'
|
|
308
|
+
canvas.style.height = canvas.height * renderScale + 'px'
|
|
309
|
+
|
|
310
|
+
canvas.style.left = Math.round((width - canvas.width * renderScale) / 2) + 'px'
|
|
311
|
+
canvas.style.top = Math.round((height - canvas.height * renderScale) / 2) + 'px'
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
main()
|
|
316
|
+
|
|
317
|
+
</script>
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
</body>
|
|
321
|
+
</html>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<title class="titleText">
|
|
5
|
+
<title class="titleText">WebGPU - Cobalt non-HDR sprite rendering</title>
|
|
6
6
|
<meta name="description" content="Web GPU 2d cobalt" />
|
|
7
7
|
<meta name="author" content="Michael Reinstein" />
|
|
8
8
|
<meta name="viewport" content="width=device-width" />
|
|
@@ -60,12 +60,11 @@
|
|
|
60
60
|
</div>
|
|
61
61
|
|
|
62
62
|
<script type="module">
|
|
63
|
-
import
|
|
63
|
+
import Global from './Global.js'
|
|
64
64
|
import * as Cobalt from '../../bundle.js'
|
|
65
65
|
import constants from './constants.js'
|
|
66
66
|
import dat from 'https://cdn.skypack.dev/pin/dat.gui@v0.7.9-2wtQAdFH5SRwnJLDWGNz/mode=imports,min/optimized/dat.gui.js'
|
|
67
67
|
import debounce from 'https://cdn.skypack.dev/pin/lodash.debounce@v4.0.8-4GXU9B066R3Th6HmjZmO/lodash.debounce.js'
|
|
68
|
-
//import animationSystem from './system-animation.js'
|
|
69
68
|
import rendererSystem from './system-renderer.js'
|
|
70
69
|
import spriteEntity from './entity-sprite.js'
|
|
71
70
|
import { ECS, vec2 } from './deps.js'
|
|
@@ -77,10 +76,10 @@ async function main () {
|
|
|
77
76
|
|
|
78
77
|
const viewportWidth = constants.GAME_WIDTH
|
|
79
78
|
const viewportHeight = constants.GAME_HEIGHT
|
|
80
|
-
|
|
79
|
+
Global.renderer = await Cobalt.init(canvas, viewportWidth, viewportHeight)
|
|
81
80
|
|
|
82
81
|
// instantiate all resource nodes
|
|
83
|
-
const spritesheet = await Cobalt.initNode(
|
|
82
|
+
const spritesheet = await Cobalt.initNode(Global.renderer, {
|
|
84
83
|
type: 'cobalt:spritesheet',
|
|
85
84
|
refs: { },
|
|
86
85
|
options: {
|
|
@@ -90,91 +89,14 @@ async function main () {
|
|
|
90
89
|
}
|
|
91
90
|
})
|
|
92
91
|
|
|
93
|
-
const hdrTex = await Cobalt.initNode(Game.renderer, {
|
|
94
|
-
type: 'cobalt:fbTexture',
|
|
95
|
-
refs: { },
|
|
96
|
-
options: {
|
|
97
|
-
label: 'hdr color texture',
|
|
98
|
-
format: 'rgba16float',
|
|
99
|
-
mip_count: 1,
|
|
100
|
-
viewportScale: 1.0,
|
|
101
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING,
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
const emissiveTex = await Cobalt.initNode(Game.renderer, {
|
|
106
|
-
type: 'cobalt:fbTexture',
|
|
107
|
-
refs: { },
|
|
108
|
-
options: {
|
|
109
|
-
label: 'hdr emissive texture',
|
|
110
|
-
format: 'rgba16float',
|
|
111
|
-
mip_count: 1,
|
|
112
|
-
viewportScale: 1.0,
|
|
113
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
|
|
114
|
-
}
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
const bloomTex = await Cobalt.initNode(Game.renderer, {
|
|
118
|
-
type: 'cobalt:fbTexture',
|
|
119
|
-
refs: { },
|
|
120
|
-
options: {
|
|
121
|
-
label: 'hdr bloom texture',
|
|
122
|
-
format: 'rgba16float',
|
|
123
|
-
mip_count: 7,
|
|
124
|
-
viewportScale: 0.5,
|
|
125
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.TEXTURE_BINDING,
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
const bloomNode = await Cobalt.initNode(Game.renderer, {
|
|
130
|
-
type: 'cobalt:bloom',
|
|
131
|
-
refs: {
|
|
132
|
-
// key is the var name defined in this node
|
|
133
|
-
// value is the var name in the cobalt resources dictionary
|
|
134
|
-
emissive: emissiveTex,
|
|
135
|
-
hdr: hdrTex,
|
|
136
|
-
bloom: bloomTex
|
|
137
|
-
},
|
|
138
|
-
options: {
|
|
139
|
-
// any extra options you want to pass to this node
|
|
140
|
-
bloom_intensity: 0.0,
|
|
141
|
-
bloom_knee: 0.0,
|
|
142
|
-
bloom_threshold: 0.1, // 1.0
|
|
143
|
-
/*
|
|
144
|
-
// sprite instance 1
|
|
145
|
-
sprite_instances: [
|
|
146
|
-
{
|
|
147
|
-
emissive_intensity: 1.0,
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
emissive_intensity: 0.5,
|
|
151
|
-
},
|
|
152
|
-
],
|
|
153
|
-
*/
|
|
154
|
-
}
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
const tmpTex = await Cobalt.initNode(Game.renderer, {
|
|
158
|
-
type: 'cobalt:fbTexture',
|
|
159
|
-
refs: { },
|
|
160
|
-
options: {
|
|
161
|
-
label: 'bloom + hdr compositing',
|
|
162
|
-
format: 'PREFERRED_TEXTURE_FORMAT',
|
|
163
|
-
mip_count: 1,
|
|
164
|
-
viewportScale: 1.0,
|
|
165
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST | GPUTextureUsage.TEXTURE_BINDING,
|
|
166
|
-
}
|
|
167
|
-
})
|
|
168
|
-
|
|
169
92
|
// instantiate all runnable nodes
|
|
170
|
-
const spriteNode = await Cobalt.initNode(
|
|
93
|
+
const spriteNode = await Cobalt.initNode(Global.renderer, {
|
|
171
94
|
type: 'cobalt:sprite',
|
|
172
95
|
refs: {
|
|
173
96
|
// key is the var name defined in this node
|
|
174
97
|
// value is the var name in the cobalt resources dictionary
|
|
175
98
|
spritesheet: spritesheet,
|
|
176
|
-
|
|
177
|
-
hdr: hdrTex,
|
|
99
|
+
color: 'FRAME_TEXTURE_VIEW',
|
|
178
100
|
},
|
|
179
101
|
options: {
|
|
180
102
|
loadOp: 'clear',
|
|
@@ -182,35 +104,12 @@ async function main () {
|
|
|
182
104
|
})
|
|
183
105
|
|
|
184
106
|
|
|
185
|
-
const compositeNode = await Cobalt.initNode(Game.renderer, {
|
|
186
|
-
type: 'cobalt:composite',
|
|
187
|
-
refs: {
|
|
188
|
-
hdr: hdrTex,
|
|
189
|
-
bloom: bloomTex,
|
|
190
|
-
combined: tmpTex,
|
|
191
|
-
},
|
|
192
|
-
options: {
|
|
193
|
-
bloom_combine_constant: 0.0,
|
|
194
|
-
},
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const b = await Cobalt.initNode(Game.renderer, {
|
|
199
|
-
type: 'cobalt:fbBlit',
|
|
200
|
-
refs: {
|
|
201
|
-
in: tmpTex,
|
|
202
|
-
out: 'FRAME_TEXTURE_VIEW',
|
|
203
|
-
},
|
|
204
|
-
options: { }
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
|
|
208
107
|
// use resizeViewport to init values on load:
|
|
209
|
-
resizeViewport(
|
|
108
|
+
resizeViewport(Global.renderer, window.innerWidth, window.innerHeight)
|
|
210
109
|
|
|
211
110
|
// window resize is *expensive* - best to debounce:
|
|
212
111
|
const debouncedResize = debounce(function () {
|
|
213
|
-
resizeViewport(
|
|
112
|
+
resizeViewport(Global.renderer, window.innerWidth, window.innerHeight)
|
|
214
113
|
}, 50)
|
|
215
114
|
|
|
216
115
|
window.addEventListener('resize', debouncedResize, { passive: true })
|
|
@@ -218,9 +117,9 @@ async function main () {
|
|
|
218
117
|
|
|
219
118
|
|
|
220
119
|
const world = ECS.createWorld()
|
|
221
|
-
ECS.addSystem(world, rendererSystem(
|
|
120
|
+
ECS.addSystem(world, rendererSystem(Global.renderer))
|
|
222
121
|
|
|
223
|
-
Cobalt.setViewportPosition(
|
|
122
|
+
Cobalt.setViewportPosition(Global.renderer, [ 240, 135 ])
|
|
224
123
|
|
|
225
124
|
ECS.addSystem(world, function cameraLoopSystem(world) {
|
|
226
125
|
const onUpdate = function (dt) {
|
|
@@ -228,35 +127,37 @@ async function main () {
|
|
|
228
127
|
const x = (Math.sin(elapsed / 2000) * 0.5 + 0.5) * 128
|
|
229
128
|
const y = (Math.sin(elapsed / 5000) * 0.5 + 0.5) * 170
|
|
230
129
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
Cobalt.setViewportPosition(Game.renderer, [ x, y ])
|
|
130
|
+
Cobalt.setViewportPosition(Global.renderer, [ x, y ])
|
|
234
131
|
}
|
|
235
132
|
|
|
236
133
|
return { onUpdate }
|
|
237
134
|
})
|
|
238
135
|
|
|
239
|
-
|
|
136
|
+
Global.world = world
|
|
240
137
|
|
|
241
138
|
// test sprites
|
|
242
139
|
const s2 = spriteEntity(world, {
|
|
243
140
|
name: 'health_empty-0.png',
|
|
244
141
|
position: [ 50, 50 ],
|
|
245
|
-
|
|
246
|
-
|
|
142
|
+
tint: [ 0, 0, 0, 0 ],
|
|
143
|
+
scale: [ 1, 1 ],
|
|
144
|
+
rotation: 0,
|
|
145
|
+
opacity: 1,
|
|
247
146
|
spriteNode,
|
|
248
147
|
})
|
|
249
148
|
|
|
250
149
|
const s = spriteEntity(world, {
|
|
251
150
|
name: 'health-0.png',
|
|
252
151
|
position: [ 240, 135 ],
|
|
253
|
-
|
|
254
|
-
|
|
152
|
+
tint: [ 0, 0, 0, 0 ],
|
|
153
|
+
scale: [ 1, 1 ],
|
|
154
|
+
rotation: 0,
|
|
155
|
+
opacity: 1,
|
|
255
156
|
spriteNode,
|
|
256
157
|
})
|
|
257
158
|
|
|
258
159
|
const gameLoop = function () {
|
|
259
|
-
tick(
|
|
160
|
+
tick(Global)
|
|
260
161
|
requestAnimationFrame(gameLoop)
|
|
261
162
|
}
|
|
262
163
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as Cobalt from '../../bundle.js'
|
|
2
|
-
import
|
|
2
|
+
import Global from './Global.js'
|
|
3
3
|
import { ECS } from './deps.js'
|
|
4
4
|
|
|
5
5
|
|
|
@@ -30,7 +30,7 @@ export default function createRendererSystem (renderer) {
|
|
|
30
30
|
oldSprite.spriteNode.removeSprite(oldSprite.sprite.cobaltSpriteId)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
Cobalt.draw(
|
|
33
|
+
Cobalt.draw(Global.renderer)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
return { onUpdate }
|