@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
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
struct ViewParams {
|
|
2
|
+
view : mat4x4<f32>,
|
|
3
|
+
proj : mat4x4<f32>
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
@group(0) @binding(0) var<uniform> uView : ViewParams;
|
|
7
|
+
@group(0) @binding(1) var uSampler : sampler;
|
|
8
|
+
@group(0) @binding(2) var uTex : texture_2d<f32>;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
struct SpriteDesc {
|
|
12
|
+
uvOrigin : vec2<f32>,
|
|
13
|
+
uvSpan : vec2<f32>,
|
|
14
|
+
frameSize : vec2<f32>, // pixels
|
|
15
|
+
centerOffset : vec2<f32>, // pixels
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
@group(0) @binding(3) var<storage, read> Sprites : array<SpriteDesc>;
|
|
19
|
+
|
|
20
|
+
@group(0) @binding(4) var emissiveTexture: texture_2d<f32>;
|
|
21
|
+
|
|
22
|
+
struct VSOut {
|
|
23
|
+
@builtin(position) pos : vec4<f32>,
|
|
24
|
+
@location(0) uv : vec2<f32>,
|
|
25
|
+
@location(1) tint : vec4<f32>,
|
|
26
|
+
@location(2) opacity : f32,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// corners for a unit-centered quad in strip order
|
|
30
|
+
const corners = array<vec2<f32>, 4>(
|
|
31
|
+
vec2<f32>(-0.5, -0.5),
|
|
32
|
+
vec2<f32>( 0.5, -0.5),
|
|
33
|
+
vec2<f32>(-0.5, 0.5),
|
|
34
|
+
vec2<f32>( 0.5, 0.5),
|
|
35
|
+
);
|
|
36
|
+
const uvBase = array<vec2<f32>, 4>(
|
|
37
|
+
vec2<f32>(0.0, 0.0),
|
|
38
|
+
vec2<f32>(1.0, 0.0),
|
|
39
|
+
vec2<f32>(0.0, 1.0),
|
|
40
|
+
vec2<f32>(1.0, 1.0),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// multiple render targets
|
|
44
|
+
struct GBufferOutput {
|
|
45
|
+
@location(0) color : vec4<f32>,
|
|
46
|
+
@location(1) emissive : vec4<f32>,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@vertex
|
|
51
|
+
fn vs_main(@builtin(vertex_index) vid : u32,
|
|
52
|
+
// per-instance attributes (locations 0..4)
|
|
53
|
+
@location(0) i_pos : vec2<f32>,
|
|
54
|
+
@location(1) i_size : vec2<f32>, // scales descriptor frame size (1,1 means use descriptor size)
|
|
55
|
+
@location(2) i_scale : vec2<f32>, // per-axis scale
|
|
56
|
+
@location(3) i_tint : vec4<f32>,
|
|
57
|
+
@location(4) i_spriteId : u32,
|
|
58
|
+
@location(5) i_opacity : f32,
|
|
59
|
+
@location(6) i_rotation : f32
|
|
60
|
+
) -> VSOut {
|
|
61
|
+
|
|
62
|
+
let rot = i_rotation;
|
|
63
|
+
let c = cos(rot);
|
|
64
|
+
let s = sin(rot);
|
|
65
|
+
|
|
66
|
+
let d = Sprites[i_spriteId];
|
|
67
|
+
let corner = corners[vid];
|
|
68
|
+
|
|
69
|
+
let sizePx = d.frameSize * i_size * i_scale; // per-axis scale applied on trimmed frame
|
|
70
|
+
var local = corner * sizePx;
|
|
71
|
+
local += d.centerOffset * i_scale; // compensate trimming // compensate trimming (so rotation is around original center)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
let rotated = vec2<f32>(local.x * c - local.y * s, local.x * s + local.y * c);
|
|
75
|
+
let world = vec4<f32>(rotated + i_pos, 0.0, 1.0);
|
|
76
|
+
|
|
77
|
+
var out : VSOut;
|
|
78
|
+
out.pos = uView.proj * uView.view * world;
|
|
79
|
+
out.uv = d.uvOrigin + d.uvSpan * uvBase[vid];
|
|
80
|
+
out.tint = i_tint;
|
|
81
|
+
out.opacity = i_opacity;
|
|
82
|
+
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@fragment
|
|
88
|
+
fn fs_main(in : VSOut) -> GBufferOutput {
|
|
89
|
+
|
|
90
|
+
var output : GBufferOutput;
|
|
91
|
+
|
|
92
|
+
let texel = textureSample(uTex, uSampler, in.uv);
|
|
93
|
+
output.color = vec4<f32>(texel.rgb * (1.0 - in.tint.a) + (in.tint.rgb * in.tint.a), texel.a * in.opacity);
|
|
94
|
+
|
|
95
|
+
let emissive = textureSample(emissiveTexture, uSampler, in.uv);
|
|
96
|
+
|
|
97
|
+
// the alpha channel in the emissive texture is used for emission strength
|
|
98
|
+
output.emissive = vec4(emissive.rgb, 1.0) * emissive.a;
|
|
99
|
+
|
|
100
|
+
return output;
|
|
101
|
+
}
|
|
@@ -5,15 +5,15 @@ export default function createSpriteQuads (device, spritesheet) {
|
|
|
5
5
|
/*
|
|
6
6
|
const vertices = new Float32Array([
|
|
7
7
|
// position tex
|
|
8
|
-
// x y
|
|
9
|
-
-0.5, -0.5,
|
|
10
|
-
-0.5, 0.5,
|
|
11
|
-
0.5, 0.5,
|
|
12
|
-
|
|
8
|
+
// x y u v
|
|
9
|
+
-0.5, -0.5, 0.0, 0.0,
|
|
10
|
+
-0.5, 0.5, 0.0, 1.0,
|
|
11
|
+
0.5, 0.5, 1.0,
|
|
12
|
+
|
|
13
13
|
// triangle 2 (2nd half of quad)
|
|
14
|
-
-0.5, -0.5,
|
|
15
|
-
0.5, 0.5,
|
|
16
|
-
0.5, -0.5,
|
|
14
|
+
-0.5, -0.5, 0.0, 0.0,
|
|
15
|
+
0.5, 0.5, 1.0, 1.0,
|
|
16
|
+
0.5, -0.5, 1.0, 0.0,
|
|
17
17
|
])
|
|
18
18
|
*/
|
|
19
19
|
|
|
@@ -35,20 +35,20 @@ export default function createSpriteQuads (device, spritesheet) {
|
|
|
35
35
|
buffer.unmap()
|
|
36
36
|
|
|
37
37
|
const bufferLayout = {
|
|
38
|
-
arrayStride:
|
|
38
|
+
arrayStride: 16,
|
|
39
39
|
stepMode: 'vertex',
|
|
40
40
|
attributes: [
|
|
41
41
|
// position
|
|
42
42
|
{
|
|
43
43
|
shaderLocation: 0,
|
|
44
|
-
format: '
|
|
44
|
+
format: 'float32x2',
|
|
45
45
|
offset: 0
|
|
46
46
|
},
|
|
47
47
|
// uv
|
|
48
48
|
{
|
|
49
49
|
shaderLocation: 1,
|
|
50
50
|
format: 'float32x2',
|
|
51
|
-
offset:
|
|
51
|
+
offset: 8
|
|
52
52
|
}
|
|
53
53
|
]
|
|
54
54
|
}
|
|
@@ -2,26 +2,18 @@
|
|
|
2
2
|
// copied into the renderer's vertex buffer
|
|
3
3
|
//
|
|
4
4
|
// @return Float32Array vertices (interleaved positions and uvs)
|
|
5
|
+
/*
|
|
5
6
|
export default function readSpriteSheet (spritesheetJson) {
|
|
6
7
|
|
|
7
8
|
// a sprite is a quad (2 triangles) so it has 6 vertices
|
|
8
|
-
// each vertex has
|
|
9
|
-
const spriteFloatCount =
|
|
9
|
+
// each vertex has 4 float32 (interleaved vec2 position, vec2 uv)
|
|
10
|
+
const spriteFloatCount = 4 * 6
|
|
10
11
|
|
|
11
12
|
// each key in the spritesheet is a unique sprite type
|
|
12
13
|
const spriteCount = Object.keys(spritesheetJson.frames).length
|
|
13
14
|
|
|
14
15
|
const vertices = new Float32Array(spriteCount * spriteFloatCount)
|
|
15
16
|
|
|
16
|
-
/*
|
|
17
|
-
stores mapping between sprite name and first vertex index. e.g.,
|
|
18
|
-
[
|
|
19
|
-
'hero_run-0', // 1st vertex index is at 0
|
|
20
|
-
'bullet_travel-0' // 1st vertex index is at 6
|
|
21
|
-
'bob_idle-1' // 1st vertex index is at 12
|
|
22
|
-
]
|
|
23
|
-
these will alway be multiples of 6, because there are 6 vertices per sprite
|
|
24
|
-
*/
|
|
25
17
|
const locations = [ ]
|
|
26
18
|
|
|
27
19
|
const spriteMeta = { }
|
|
@@ -44,10 +36,10 @@ export default function readSpriteSheet (spritesheetJson) {
|
|
|
44
36
|
const maxX = -0.5 + ((frame.spriteSourceSize.x + frame.spriteSourceSize.w) / frame.sourceSize.w)
|
|
45
37
|
const maxY = -0.5 + ((frame.spriteSourceSize.y + frame.spriteSourceSize.h) / frame.sourceSize.h)
|
|
46
38
|
|
|
47
|
-
const p0 = [ minX, minY
|
|
48
|
-
const p1 = [ minX, maxY
|
|
49
|
-
const p2 = [ maxX, maxY
|
|
50
|
-
const p3 = [ maxX, minY
|
|
39
|
+
const p0 = [ minX, minY ]
|
|
40
|
+
const p1 = [ minX, maxY ]
|
|
41
|
+
const p2 = [ maxX, maxY ]
|
|
42
|
+
const p3 = [ maxX, minY ]
|
|
51
43
|
|
|
52
44
|
|
|
53
45
|
// calculate uvs
|
|
@@ -64,29 +56,71 @@ export default function readSpriteSheet (spritesheetJson) {
|
|
|
64
56
|
|
|
65
57
|
|
|
66
58
|
// quad triangles are [ p0, p1, p2 ] , [ p0, p2, p3 ]
|
|
67
|
-
// vertex data is interleaved; a single vertex has a
|
|
59
|
+
// vertex data is interleaved; a single vertex has a vec2 position followed immediately by vec2 uv
|
|
68
60
|
vertices.set(p0, i)
|
|
69
|
-
vertices.set(uv0, i +
|
|
61
|
+
vertices.set(uv0, i + 2)
|
|
70
62
|
|
|
71
|
-
vertices.set(p1, i +
|
|
72
|
-
vertices.set(uv1, i +
|
|
63
|
+
vertices.set(p1, i + 4)
|
|
64
|
+
vertices.set(uv1, i + 6)
|
|
73
65
|
|
|
74
|
-
vertices.set(p2, i +
|
|
75
|
-
vertices.set(uv2, i +
|
|
66
|
+
vertices.set(p2, i + 8)
|
|
67
|
+
vertices.set(uv2, i + 10)
|
|
76
68
|
|
|
77
|
-
vertices.set(p0, i +
|
|
78
|
-
vertices.set(uv0, i +
|
|
69
|
+
vertices.set(p0, i + 12)
|
|
70
|
+
vertices.set(uv0, i + 14)
|
|
79
71
|
|
|
80
|
-
vertices.set(p2, i +
|
|
81
|
-
vertices.set(uv2, i +
|
|
72
|
+
vertices.set(p2, i + 16)
|
|
73
|
+
vertices.set(uv2, i + 18)
|
|
82
74
|
|
|
83
|
-
vertices.set(p3, i +
|
|
84
|
-
vertices.set(uv3, i +
|
|
75
|
+
vertices.set(p3, i + 20)
|
|
76
|
+
vertices.set(uv3, i + 22)
|
|
85
77
|
|
|
86
78
|
i += spriteFloatCount
|
|
87
79
|
}
|
|
88
80
|
|
|
89
|
-
return {
|
|
81
|
+
return { spriteMeta, locations, vertices }
|
|
82
|
+
}
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* ------------------------------ TexturePacker (no rotation) ------------------------------
|
|
88
|
+
* Accepts the "Hash" JSON format from TexturePacker. Assumes rotated=false.
|
|
89
|
+
*
|
|
90
|
+
* texturepacker frame structure:
|
|
91
|
+
"f2.png":
|
|
92
|
+
{
|
|
93
|
+
"frame": {"x":15,"y":1,"w":10,"h":15},
|
|
94
|
+
"rotated": false,
|
|
95
|
+
"trimmed": true,
|
|
96
|
+
"spriteSourceSize": {"x":22,"y":17,"w":10,"h":15},
|
|
97
|
+
"sourceSize": {"w":32,"h":32}
|
|
98
|
+
},
|
|
99
|
+
*/
|
|
100
|
+
export default function buildSpriteTableFromTexturePacker (doc) {
|
|
101
|
+
const atlasW = doc.meta.size.w;
|
|
102
|
+
const atlasH = doc.meta.size.h;
|
|
103
|
+
const names = Object.keys(doc.frames).sort();
|
|
104
|
+
const descs = new Array(names.length);
|
|
105
|
+
|
|
106
|
+
for (let i=0; i<names.length; i++) {
|
|
107
|
+
const fr = doc.frames[names[i]];
|
|
108
|
+
|
|
109
|
+
const fx = fr.frame.x, fy = fr.frame.y, fw = fr.frame.w, fh = fr.frame.h;
|
|
110
|
+
const offX = fx / atlasW, offY = fy / atlasH;
|
|
111
|
+
const spanX = fw / atlasW, spanY = fh / atlasH;
|
|
112
|
+
const sw = fr.sourceSize.w, sh = fr.sourceSize.h;
|
|
113
|
+
const ox = fr.spriteSourceSize.x, oy = fr.spriteSourceSize.y;
|
|
114
|
+
const cx = (ox + fw*0.5) - (sw*0.5);
|
|
115
|
+
const cy = (oy + fh*0.5) - (sh*0.5);
|
|
116
|
+
descs[i] = {
|
|
117
|
+
UvOrigin: [offX, offY],
|
|
118
|
+
UvSpan: [spanX, spanY],
|
|
119
|
+
FrameSize:[fw, fh],
|
|
120
|
+
CenterOffset:[cx, cy],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return { descs, names };
|
|
90
124
|
}
|
|
91
125
|
|
|
92
126
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import createTextureFromBuffer from '../create-texture-from-buffer.js'
|
|
2
|
+
import createTextureFromUrl from '../create-texture-from-url.js'
|
|
3
|
+
import readSpriteSheet from './read-spritesheet.js'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// shared spritesheet resource, used by each sprite render node
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
type: 'cobalt:spritesheet',
|
|
10
|
+
refs: [ ],
|
|
11
|
+
|
|
12
|
+
// @params Object cobalt renderer world object
|
|
13
|
+
// @params Object options optional data passed when initing this node
|
|
14
|
+
onInit: async function (cobalt, options={}) {
|
|
15
|
+
return init(cobalt, options)
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
onRun: function (cobalt, node, webGpuCommandEncoder) { },
|
|
19
|
+
|
|
20
|
+
onDestroy: function (cobalt, node) {
|
|
21
|
+
// any cleanup for your node should go here (releasing textures, etc.)
|
|
22
|
+
destroy(node)
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
onResize: function (cobalt, node) { },
|
|
26
|
+
|
|
27
|
+
onViewportPosition: function (cobalt, node) { },
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
// configure the common settings for sprite rendering
|
|
32
|
+
async function init (cobalt, node) {
|
|
33
|
+
const { canvas, device } = cobalt
|
|
34
|
+
|
|
35
|
+
let spritesheet, colorTexture, emissiveTexture
|
|
36
|
+
|
|
37
|
+
const format = node.options.format || 'rgba8unorm'
|
|
38
|
+
|
|
39
|
+
if (canvas) {
|
|
40
|
+
// browser (canvas) path
|
|
41
|
+
spritesheet = await fetch(node.options.spriteSheetJsonUrl)
|
|
42
|
+
spritesheet = await spritesheet.json()
|
|
43
|
+
spritesheet = readSpriteSheet(spritesheet)
|
|
44
|
+
|
|
45
|
+
colorTexture = await createTextureFromUrl(cobalt, 'sprite', node.options.colorTextureUrl, format)
|
|
46
|
+
emissiveTexture = await createTextureFromUrl(cobalt, 'emissive sprite', node.options.emissiveTextureUrl, format)
|
|
47
|
+
|
|
48
|
+
// for some reason this needs to be done _after_ creating the material, or the rendering will be blurry
|
|
49
|
+
canvas.style.imageRendering = 'pixelated'
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// sdl + gpu path
|
|
53
|
+
spritesheet = readSpriteSheet(node.options.spriteSheetJson)
|
|
54
|
+
|
|
55
|
+
colorTexture = await createTextureFromBuffer(cobalt, 'sprite', node.options.colorTexture, format)
|
|
56
|
+
emissiveTexture = await createTextureFromBuffer(cobalt, 'emissive sprite', node.options.emissiveTexture, format)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Map sprite name → ID
|
|
60
|
+
const idByName = new Map(spritesheet.names.map((n,i)=>[n,i]))
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
colorTexture,
|
|
64
|
+
emissiveTexture,
|
|
65
|
+
spritesheet,
|
|
66
|
+
idByName,
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
function destroy (node) {
|
|
72
|
+
node.data.quads.buffer.destroy()
|
|
73
|
+
node.data.colorTexture.buffer.destroy()
|
|
74
|
+
node.data.emissiveTexture.texture.destroy()
|
|
75
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import createTextureFromBuffer from '../create-texture-from-buffer.js'
|
|
2
2
|
import createTextureFromUrl from '../create-texture-from-url.js'
|
|
3
|
+
import getPreferredFormat from '../get-preferred-format.js'
|
|
3
4
|
import tileWGSL from './tile.wgsl'
|
|
5
|
+
import round from 'round-half-up-symmetric'
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
const _buf = new Float32Array(8) //(136) // tile instance data stored in a UBO
|
|
@@ -139,7 +141,7 @@ async function init (cobalt, nodeData) {
|
|
|
139
141
|
entryPoint: 'fs_main',
|
|
140
142
|
targets: [
|
|
141
143
|
{
|
|
142
|
-
format:
|
|
144
|
+
format: nodeData.options.outputFormat || getPreferredFormat(cobalt),
|
|
143
145
|
blend: {
|
|
144
146
|
color: {
|
|
145
147
|
srcFactor: 'src-alpha',
|
|
@@ -183,8 +185,8 @@ function destroy (data) {
|
|
|
183
185
|
|
|
184
186
|
function _writeTileBuffer (c, nodeData) {
|
|
185
187
|
// c.viewport.position is the top left visible corner of the level
|
|
186
|
-
_buf[0] = c.viewport.position[0]
|
|
187
|
-
_buf[1] = c.viewport.position[1]
|
|
188
|
+
_buf[0] = round(c.viewport.position[0])
|
|
189
|
+
_buf[1] = round(c.viewport.position[1])
|
|
188
190
|
|
|
189
191
|
const tile = nodeData.data
|
|
190
192
|
const { tileScale, tileSize } = tile
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import createTextureFromBuffer from '../create-texture-from-buffer.js'
|
|
2
2
|
import createTextureFromUrl from '../create-texture-from-url.js'
|
|
3
|
+
import getPreferredFormat from '../get-preferred-format.js'
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
/*
|
|
6
|
-
Tile layers are totally static, and there are usually many of them
|
|
7
|
+
Tile layers are totally static, and there are usually many of them on several layers.
|
|
7
8
|
|
|
8
9
|
These use a `TileRenderPass` data structure which provides 100% GPU hardware based tile rendering, making them _almost_ free CPU-wise.
|
|
9
10
|
|
|
@@ -17,9 +18,10 @@ Inspired by/ported from https://blog.tojicode.com/2012/07/sprite-tile-maps-on-gp
|
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
export default {
|
|
20
|
-
type: 'cobalt:
|
|
21
|
+
type: 'cobalt:tileHDR',
|
|
21
22
|
refs: [
|
|
22
|
-
{ name: 'tileAtlas', type: 'textureView', format: 'rgba8unorm', access: '
|
|
23
|
+
{ name: 'tileAtlas', type: 'textureView', format: 'rgba8unorm', access: 'read' },
|
|
24
|
+
{ name: "hdr", type: "textureView", format: "rgba16float", access: "write", },
|
|
23
25
|
],
|
|
24
26
|
|
|
25
27
|
// @params Object cobalt renderer world object
|
|
@@ -47,12 +49,13 @@ export default {
|
|
|
47
49
|
|
|
48
50
|
// optional
|
|
49
51
|
customFunctions: {
|
|
52
|
+
|
|
50
53
|
setTexture: async function (cobalt, node, texture) {
|
|
51
54
|
const { canvas, device } = cobalt
|
|
52
55
|
|
|
53
56
|
destroy(node)
|
|
54
57
|
|
|
55
|
-
const format = node.options.format ||
|
|
58
|
+
const format = node.options.format || getPreferredFormat(cobalt)
|
|
56
59
|
|
|
57
60
|
let material
|
|
58
61
|
|
|
@@ -98,7 +101,7 @@ async function init (cobalt, nodeData) {
|
|
|
98
101
|
|
|
99
102
|
let material
|
|
100
103
|
|
|
101
|
-
const format = nodeData.options.format ||
|
|
104
|
+
const format = nodeData.options.format || getPreferredFormat(cobalt)
|
|
102
105
|
|
|
103
106
|
// build the tile layer and add it to the cobalt data structure
|
|
104
107
|
if (canvas) {
|
|
@@ -156,6 +159,11 @@ async function init (cobalt, nodeData) {
|
|
|
156
159
|
|
|
157
160
|
function draw (cobalt, nodeData, commandEncoder) {
|
|
158
161
|
|
|
162
|
+
// calling setTexture can cause the texture to be destroyed followed by this draw command
|
|
163
|
+
// so check for the undefined texture first and bail for a frame.
|
|
164
|
+
if (!nodeData.data.material.texture)
|
|
165
|
+
return
|
|
166
|
+
|
|
159
167
|
const { device } = cobalt
|
|
160
168
|
|
|
161
169
|
// on the first render, we should clear the color attachment.
|
|
@@ -166,7 +174,8 @@ function draw (cobalt, nodeData, commandEncoder) {
|
|
|
166
174
|
label: 'tile',
|
|
167
175
|
colorAttachments: [
|
|
168
176
|
{
|
|
169
|
-
|
|
177
|
+
// hdr is passsed as a node || FRAME_TEXTURE_VIEW
|
|
178
|
+
view: nodeData.refs.hdr.data?.view || nodeData.refs.hdr,
|
|
170
179
|
clearValue: cobalt.clearValue,
|
|
171
180
|
loadOp,
|
|
172
181
|
storeOp: 'store'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { mat4, vec2, vec3, vec4 } from 'https://wgpu-matrix.org/dist/3.x/wgpu-matrix.module.js'
|
package/src/overlay/constants.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const FLOAT32S_PER_SPRITE = 12 // vec2(translate) + vec2(scale) + vec4(tint) + opacity + rotation + emissiveIntensity + sortValue
|