@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/cobalt.js
CHANGED
|
@@ -1,40 +1,36 @@
|
|
|
1
|
-
export { default as createTexture }
|
|
2
|
-
export { default as createTextureFromUrl } from './create-texture-from-url.js'
|
|
1
|
+
export { default as createTexture } from './create-texture.js'
|
|
3
2
|
export { default as createTextureFromBuffer } from './create-texture-from-buffer.js'
|
|
4
|
-
|
|
3
|
+
export { default as createTextureFromUrl } from './create-texture-from-url.js'
|
|
5
4
|
|
|
6
5
|
// built-in run nodes
|
|
7
|
-
import bloomNode
|
|
8
|
-
import compositeNode from './scene-composite/scene-composite.js'
|
|
9
|
-
import spriteHDRNode from './sprite-hdr/sprite.js'
|
|
10
|
-
import tileHDRNode from './tile-hdr/tile.js'
|
|
6
|
+
import bloomNode from './bloom/bloom.js'
|
|
11
7
|
import displacementNode from './displacement/displacement.js'
|
|
12
|
-
import fbBlitNode
|
|
13
|
-
import
|
|
14
|
-
import lightNode
|
|
15
|
-
import
|
|
16
|
-
|
|
8
|
+
import fbBlitNode from './fb-blit/fb-blit.js'
|
|
9
|
+
import fbTextureNode from './fb-texture/fb-texture.js'
|
|
10
|
+
import lightNode from './light/light.js'
|
|
11
|
+
import primitivesNode from './primitives/primitives.js'
|
|
12
|
+
import compositeNode from './scene-composite/scene-composite.js'
|
|
13
|
+
import spriteNode from './sprite/sprite.js'
|
|
14
|
+
import spriteHDRNode from './sprite-hdr/sprite.js'
|
|
15
|
+
import spritesheetNode from './spritesheet/spritesheet.js'
|
|
17
16
|
// built-in resource nodes
|
|
18
|
-
import tileAtlasNode
|
|
19
|
-
import
|
|
20
|
-
import fbTextureNode from './fb-texture/fb-texture.js'
|
|
21
|
-
|
|
17
|
+
import tileAtlasNode from './tile-hdr/atlas.js'
|
|
18
|
+
import tileHDRNode from './tile-hdr/tile.js'
|
|
22
19
|
|
|
23
20
|
// create and initialize a WebGPU renderer for a given canvas
|
|
24
21
|
// returns the data structure containing all WebGPU related stuff
|
|
25
|
-
export async function init
|
|
26
|
-
|
|
22
|
+
export async function init(ctx, viewportWidth, viewportHeight) {
|
|
27
23
|
let device, gpu, context, canvas
|
|
28
24
|
|
|
29
25
|
// determine if an sdl/gpu context was passed, or if this is a browser canvas
|
|
30
26
|
if (ctx.sdlWindow && ctx.gpu) {
|
|
31
27
|
// this is an sdl/gpu context
|
|
32
28
|
gpu = ctx.gpu
|
|
33
|
-
|
|
34
|
-
const instance = gpu.create([
|
|
29
|
+
|
|
30
|
+
const instance = gpu.create(['verbose=1', 'enable-dawn-features=allow_unsafe_apis'])
|
|
35
31
|
const adapter = await instance.requestAdapter()
|
|
36
32
|
device = await adapter.requestDevice({
|
|
37
|
-
requiredFeatures: [
|
|
33
|
+
requiredFeatures: ['texture-component-swizzle'],
|
|
38
34
|
})
|
|
39
35
|
context = gpu.renderGPUDeviceToWindow({ device, window: ctx.sdlWindow })
|
|
40
36
|
|
|
@@ -42,7 +38,6 @@ export async function init (ctx, viewportWidth, viewportHeight) {
|
|
|
42
38
|
global.GPUBufferUsage = gpu.GPUBufferUsage
|
|
43
39
|
global.GPUShaderStage = gpu.GPUShaderStage
|
|
44
40
|
global.GPUTextureUsage = gpu.GPUTextureUsage
|
|
45
|
-
|
|
46
41
|
} else {
|
|
47
42
|
// ctx is a canvas element
|
|
48
43
|
canvas = ctx
|
|
@@ -57,7 +52,7 @@ export async function init (ctx, viewportWidth, viewportHeight) {
|
|
|
57
52
|
context.configure({
|
|
58
53
|
device,
|
|
59
54
|
format: navigator.gpu?.getPreferredCanvasFormat(), // bgra8unorm
|
|
60
|
-
alphaMode: 'opaque'
|
|
55
|
+
alphaMode: 'opaque',
|
|
61
56
|
})
|
|
62
57
|
}
|
|
63
58
|
|
|
@@ -84,15 +79,15 @@ export async function init (ctx, viewportWidth, viewportHeight) {
|
|
|
84
79
|
return {
|
|
85
80
|
nodeDefs,
|
|
86
81
|
// runnable nodes. ordering dictates render order (first to last)
|
|
87
|
-
nodes: [
|
|
82
|
+
nodes: [],
|
|
88
83
|
|
|
89
84
|
// keeps references to all node refs that need to access the per-frame default texture view
|
|
90
85
|
// these refs are updated on each invocation of Cobalt.draw(...)
|
|
91
|
-
defaultTextureViewRefs: [
|
|
86
|
+
defaultTextureViewRefs: [],
|
|
92
87
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
88
|
+
canvas,
|
|
89
|
+
device,
|
|
90
|
+
context,
|
|
96
91
|
gpu,
|
|
97
92
|
|
|
98
93
|
// used in the color attachments of renderpass
|
|
@@ -102,31 +97,27 @@ export async function init (ctx, viewportWidth, viewportHeight) {
|
|
|
102
97
|
width: viewportWidth,
|
|
103
98
|
height: viewportHeight,
|
|
104
99
|
zoom: 1.0,
|
|
105
|
-
position: [
|
|
100
|
+
position: [0, 0], // top-left corner of the viewport
|
|
106
101
|
},
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
104
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (!nodeDefinition?.type)
|
|
113
|
-
throw new Error(`Can't define a new node missing a type.`)
|
|
105
|
+
export function defineNode(c, nodeDefinition) {
|
|
106
|
+
if (!nodeDefinition?.type) throw new Error(`Can't define a new node missing a type.`)
|
|
114
107
|
|
|
115
108
|
c.nodeDefs[nodeDefinition.type] = nodeDefinition
|
|
116
109
|
}
|
|
117
110
|
|
|
118
|
-
|
|
119
|
-
export async function initNode (c, nodeData) {
|
|
111
|
+
export async function initNode(c, nodeData) {
|
|
120
112
|
const nodeDef = c.nodeDefs[nodeData?.type]
|
|
121
113
|
|
|
122
|
-
if (!nodeDef)
|
|
123
|
-
throw new Error(`Can't initialize a new node missing a type.`)
|
|
114
|
+
if (!nodeDef) throw new Error(`Can't initialize a new node missing a type.`)
|
|
124
115
|
|
|
125
116
|
const node = {
|
|
126
117
|
type: nodeData.type,
|
|
127
|
-
refs: nodeData.refs || {
|
|
128
|
-
options: nodeData.options || {
|
|
129
|
-
data: {
|
|
118
|
+
refs: nodeData.refs || {},
|
|
119
|
+
options: nodeData.options || {},
|
|
120
|
+
data: {},
|
|
130
121
|
enabled: true, // when disabled, the node won't be run
|
|
131
122
|
}
|
|
132
123
|
|
|
@@ -139,8 +130,8 @@ export async function initNode (c, nodeData) {
|
|
|
139
130
|
|
|
140
131
|
node.data = await nodeDef.onInit(c, node)
|
|
141
132
|
|
|
142
|
-
// copy in all custom functions, and ensure the first parameter is the node itself
|
|
143
|
-
const customFunctions = nodeDef.customFunctions || {
|
|
133
|
+
// copy in all custom functions, and ensure the first parameter is the node itself
|
|
134
|
+
const customFunctions = nodeDef.customFunctions || {}
|
|
144
135
|
for (const fnName in customFunctions) {
|
|
145
136
|
node[fnName] = function (...args) {
|
|
146
137
|
return customFunctions[fnName](c, node, ...args)
|
|
@@ -151,9 +142,8 @@ export async function initNode (c, nodeData) {
|
|
|
151
142
|
return node
|
|
152
143
|
}
|
|
153
144
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const { device, context } = c
|
|
145
|
+
export function draw(c) {
|
|
146
|
+
const { device, context } = c
|
|
157
147
|
|
|
158
148
|
const commandEncoder = device.createCommandEncoder()
|
|
159
149
|
|
|
@@ -161,28 +151,24 @@ export function draw (c) {
|
|
|
161
151
|
|
|
162
152
|
// some nodes may need a reference to the default texture view (the frame backing)
|
|
163
153
|
// this is generated each draw frame so we need to update the references
|
|
164
|
-
for (const r of c.defaultTextureViewRefs)
|
|
165
|
-
r.node.refs[r.refName] = v
|
|
154
|
+
for (const r of c.defaultTextureViewRefs) r.node.refs[r.refName] = v
|
|
166
155
|
|
|
167
156
|
// run all of the enabled nodes
|
|
168
157
|
for (const node of c.nodes) {
|
|
169
|
-
if (!node.enabled)
|
|
170
|
-
continue
|
|
158
|
+
if (!node.enabled) continue
|
|
171
159
|
|
|
172
160
|
const nodeDef = c.nodeDefs[node.type]
|
|
173
161
|
nodeDef.onRun(c, node, commandEncoder)
|
|
174
162
|
}
|
|
175
163
|
|
|
176
|
-
device.queue.submit([
|
|
164
|
+
device.queue.submit([commandEncoder.finish()])
|
|
177
165
|
|
|
178
166
|
// for sdl + gpu setups, we need to do this swap() step
|
|
179
|
-
if (!c.canvas)
|
|
180
|
-
c.context.swap()
|
|
167
|
+
if (!c.canvas) c.context.swap()
|
|
181
168
|
}
|
|
182
169
|
|
|
183
|
-
|
|
184
170
|
// clean up all the loaded data so we could re-load a level, etc.
|
|
185
|
-
export function reset
|
|
171
|
+
export function reset(c) {
|
|
186
172
|
for (const n of c.nodes) {
|
|
187
173
|
const nodeDef = c.nodeDefs[n.type]
|
|
188
174
|
nodeDef.onDestroy(c, n)
|
|
@@ -191,10 +177,9 @@ export function reset (c) {
|
|
|
191
177
|
c.defaultTextureViewRefs.length = 0
|
|
192
178
|
}
|
|
193
179
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
c.viewport.height = height
|
|
180
|
+
export function setViewportDimensions(c, width, height) {
|
|
181
|
+
c.viewport.width = width
|
|
182
|
+
c.viewport.height = height
|
|
198
183
|
|
|
199
184
|
for (const n of c.nodes) {
|
|
200
185
|
const nodeDef = c.nodeDefs[n.type]
|
|
@@ -202,11 +187,10 @@ export function setViewportDimensions (c, width, height) {
|
|
|
202
187
|
}
|
|
203
188
|
}
|
|
204
189
|
|
|
205
|
-
|
|
206
190
|
// @param Array pos 2D point the viewport is centered on
|
|
207
|
-
export function setViewportPosition
|
|
208
|
-
c.viewport.position[0] = pos[0] -
|
|
209
|
-
c.viewport.position[1] = pos[1] -
|
|
191
|
+
export function setViewportPosition(c, pos) {
|
|
192
|
+
c.viewport.position[0] = pos[0] - c.viewport.width / 2 / c.viewport.zoom
|
|
193
|
+
c.viewport.position[1] = pos[1] - c.viewport.height / 2 / c.viewport.zoom
|
|
210
194
|
|
|
211
195
|
for (const n of c.nodes) {
|
|
212
196
|
const nodeDef = c.nodeDefs[n.type]
|
|
@@ -214,10 +198,8 @@ export function setViewportPosition (c, pos) {
|
|
|
214
198
|
}
|
|
215
199
|
}
|
|
216
200
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (cobalt.canvas)
|
|
220
|
-
return cobalt.context.getCurrentTexture().createView()
|
|
201
|
+
export function getCurrentTextureView(cobalt) {
|
|
202
|
+
if (cobalt.canvas) return cobalt.context.getCurrentTexture().createView()
|
|
221
203
|
else {
|
|
222
204
|
//return cobalt.context.getCurrentTexture().createView()
|
|
223
205
|
return cobalt.context.getCurrentTextureView()
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import createTexture
|
|
1
|
+
import createTexture from './create-texture.js'
|
|
2
2
|
import getPreferredFormat from './get-preferred-format.js'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
export default function createTextureFromBuffer (c, label, image, format) {
|
|
6
|
-
|
|
4
|
+
export default function createTextureFromBuffer(c, label, image, format) {
|
|
7
5
|
format = format || getPreferredFormat(c)
|
|
8
6
|
|
|
9
|
-
const usage =
|
|
7
|
+
const usage =
|
|
8
|
+
GPUTextureUsage.TEXTURE_BINDING |
|
|
9
|
+
GPUTextureUsage.COPY_DST |
|
|
10
|
+
GPUTextureUsage.RENDER_ATTACHMENT
|
|
10
11
|
const mip_count = 1
|
|
11
12
|
const t = createTexture(c.device, label, image.width, image.height, mip_count, format, usage)
|
|
12
13
|
|
|
@@ -24,8 +25,8 @@ export default function createTextureFromBuffer (c, label, image, format) {
|
|
|
24
25
|
{ texture: t.texture },
|
|
25
26
|
image.data,
|
|
26
27
|
{ bytesPerRow: 4 * image.width },
|
|
27
|
-
{ width: image.width, height: image.height }
|
|
28
|
-
)
|
|
28
|
+
{ width: image.width, height: image.height },
|
|
29
|
+
)
|
|
29
30
|
|
|
30
31
|
// nearest neighbor filtering is good for da pixel art
|
|
31
32
|
const samplerDescriptor = {
|
|
@@ -34,7 +35,7 @@ export default function createTextureFromBuffer (c, label, image, format) {
|
|
|
34
35
|
magFilter: 'nearest',
|
|
35
36
|
minFilter: 'nearest',
|
|
36
37
|
mipmapFilter: 'nearest',
|
|
37
|
-
maxAnisotropy: 1
|
|
38
|
+
maxAnisotropy: 1,
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
t.sampler = c.device.createSampler(samplerDescriptor)
|
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
import createTexture
|
|
1
|
+
import createTexture from './create-texture.js'
|
|
2
2
|
import getPreferredFormat from './get-preferred-format.js'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
export default async function createTextureFromUrl (c, label, url, format) {
|
|
4
|
+
export default async function createTextureFromUrl(c, label, url, format) {
|
|
6
5
|
const response = await fetch(url)
|
|
7
6
|
const blob = await response.blob()
|
|
8
7
|
|
|
9
8
|
format = format || getPreferredFormat(c)
|
|
10
9
|
|
|
11
|
-
const imageData = await createImageBitmap(
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const imageData = await createImageBitmap(
|
|
11
|
+
blob /*, { premultiplyAlpha: 'none', resizeQuality: 'pixelated' }*/,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
const usage =
|
|
15
|
+
GPUTextureUsage.TEXTURE_BINDING |
|
|
16
|
+
GPUTextureUsage.COPY_DST |
|
|
17
|
+
GPUTextureUsage.RENDER_ATTACHMENT
|
|
14
18
|
const mip_count = 1
|
|
15
|
-
const t = createTexture(
|
|
19
|
+
const t = createTexture(
|
|
20
|
+
c.device,
|
|
21
|
+
label,
|
|
22
|
+
imageData.width,
|
|
23
|
+
imageData.height,
|
|
24
|
+
mip_count,
|
|
25
|
+
format,
|
|
26
|
+
usage,
|
|
27
|
+
)
|
|
16
28
|
|
|
17
29
|
c.device.queue.copyExternalImageToTexture(
|
|
18
30
|
{ source: imageData },
|
|
19
31
|
{ texture: t.texture },
|
|
20
32
|
{
|
|
21
33
|
width: imageData.width,
|
|
22
|
-
height: imageData.height
|
|
23
|
-
}
|
|
34
|
+
height: imageData.height,
|
|
35
|
+
},
|
|
24
36
|
)
|
|
25
37
|
|
|
26
38
|
// nearest neighbor filtering is good for da pixel art
|
|
@@ -30,7 +42,7 @@ export default async function createTextureFromUrl (c, label, url, format) {
|
|
|
30
42
|
magFilter: 'nearest',
|
|
31
43
|
minFilter: 'nearest',
|
|
32
44
|
mipmapFilter: 'nearest',
|
|
33
|
-
maxAnisotropy: 1
|
|
45
|
+
maxAnisotropy: 1,
|
|
34
46
|
}
|
|
35
47
|
|
|
36
48
|
t.sampler = c.device.createSampler(samplerDescriptor)
|
package/src/create-texture.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
export default function createTexture
|
|
2
|
-
|
|
1
|
+
export default function createTexture(device, label, width, height, mip_count, format, usage) {
|
|
3
2
|
const texture = device.createTexture({
|
|
4
3
|
label,
|
|
5
4
|
size: { width, height },
|
|
@@ -12,19 +11,21 @@ export default function createTexture (device, label, width, height, mip_count,
|
|
|
12
11
|
|
|
13
12
|
const view = texture.createView()
|
|
14
13
|
|
|
15
|
-
const mip_view = [
|
|
14
|
+
const mip_view = []
|
|
16
15
|
|
|
17
|
-
for (let i=0; i < mip_count; i++)
|
|
18
|
-
mip_view.push(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
for (let i = 0; i < mip_count; i++)
|
|
17
|
+
mip_view.push(
|
|
18
|
+
texture.createView({
|
|
19
|
+
label,
|
|
20
|
+
format,
|
|
21
|
+
dimension: '2d',
|
|
22
|
+
aspect: 'all',
|
|
23
|
+
baseMipLevel: i,
|
|
24
|
+
mipLevelCount: 1,
|
|
25
|
+
baseArrayLayer: 0,
|
|
26
|
+
arrayLayerCount: 1,
|
|
27
|
+
}),
|
|
28
|
+
)
|
|
28
29
|
|
|
29
30
|
const sampler = device.createSampler({
|
|
30
31
|
label: `${label} sampler`,
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import getPreferredFormat
|
|
2
|
-
import {
|
|
1
|
+
import getPreferredFormat from '../get-preferred-format.js'
|
|
2
|
+
import { DisplacementComposition } from './displacement-composition.js'
|
|
3
3
|
import { DisplacementParametersBuffer } from './displacement-parameters-buffer.js'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
4
|
+
import { DisplacementTexture } from './displacement-texture.js'
|
|
5
|
+
import { TrianglesBuffer } from './triangles-buffer.js'
|
|
7
6
|
|
|
8
7
|
// adapted to webgpu from https://github.com/pixijs/pixijs/tree/dev/packages/filter-displacement
|
|
9
8
|
|
|
10
9
|
export default {
|
|
11
10
|
type: 'cobalt:displacement',
|
|
12
11
|
refs: [
|
|
12
|
+
// input framebuffer texture with the scene drawn
|
|
13
|
+
{ name: 'color', type: 'textureView', format: 'bgra8unorm', access: 'read' },
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
{ name: 'color', type: 'textureView', format: 'bgra8unorm', access: 'read' },
|
|
16
|
-
|
|
17
|
-
// displacement map (perlin noise texture works well here)
|
|
15
|
+
// displacement map (perlin noise texture works well here)
|
|
18
16
|
{ name: 'map', type: 'cobaltTexture', format: 'bgra8unorm', access: 'read' },
|
|
19
17
|
|
|
20
18
|
// result we're writing to
|
|
@@ -25,7 +23,7 @@ export default {
|
|
|
25
23
|
|
|
26
24
|
// @params Object cobalt renderer world object
|
|
27
25
|
// @params Object options optional data passed when initing this node
|
|
28
|
-
onInit: async function (cobalt, options={}) {
|
|
26
|
+
onInit: async function (cobalt, options = {}) {
|
|
29
27
|
return init(cobalt, options)
|
|
30
28
|
},
|
|
31
29
|
|
|
@@ -41,37 +39,37 @@ export default {
|
|
|
41
39
|
|
|
42
40
|
onResize: function (cobalt, node) {
|
|
43
41
|
// do whatever you need when the dimensions of the renderer change (resize textures, etc.)
|
|
44
|
-
node.data.displacementTexture.resize(cobalt.viewport.width, cobalt.viewport.height)
|
|
42
|
+
node.data.displacementTexture.resize(cobalt.viewport.width, cobalt.viewport.height)
|
|
45
43
|
|
|
46
|
-
node.data.displacementComposition.setColorTextureView(node.refs.color.data.view)
|
|
47
|
-
node.data.displacementComposition.setNoiseMapTextureView(node.refs.map.view)
|
|
48
|
-
node.data.displacementComposition.setDisplacementTextureView(
|
|
44
|
+
node.data.displacementComposition.setColorTextureView(node.refs.color.data.view)
|
|
45
|
+
node.data.displacementComposition.setNoiseMapTextureView(node.refs.map.view)
|
|
46
|
+
node.data.displacementComposition.setDisplacementTextureView(
|
|
47
|
+
node.data.displacementTexture.getView(),
|
|
48
|
+
)
|
|
49
49
|
},
|
|
50
50
|
|
|
51
51
|
onViewportPosition: function (cobalt, node) {
|
|
52
|
-
|
|
52
|
+
node.data.displacementTexture.setViewport(cobalt.viewport)
|
|
53
53
|
},
|
|
54
54
|
|
|
55
55
|
// optional
|
|
56
56
|
customFunctions: {
|
|
57
|
-
|
|
58
57
|
addTriangle: function (cobalt, node, triangleVertices) {
|
|
59
|
-
return node.data.trianglesBuffer.addTriangle(triangleVertices)
|
|
58
|
+
return node.data.trianglesBuffer.addTriangle(triangleVertices)
|
|
60
59
|
},
|
|
61
60
|
|
|
62
61
|
removeTriangle: function (cobalt, node, triangleId) {
|
|
63
|
-
node.data.trianglesBuffer.removeTriangle(triangleId)
|
|
62
|
+
node.data.trianglesBuffer.removeTriangle(triangleId)
|
|
64
63
|
},
|
|
65
64
|
|
|
66
65
|
setPosition: function (cobalt, node, triangleId, triangleVertices) {
|
|
67
|
-
node.data.trianglesBuffer.setTriangle(triangleId, triangleVertices)
|
|
66
|
+
node.data.trianglesBuffer.setTriangle(triangleId, triangleVertices)
|
|
68
67
|
},
|
|
69
68
|
},
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
|
|
73
71
|
// This corresponds to a WebGPU render pass. It handles 1 sprite layer.
|
|
74
|
-
async function init
|
|
72
|
+
async function init(cobalt, node) {
|
|
75
73
|
const { device } = cobalt
|
|
76
74
|
|
|
77
75
|
const displacementParameters = new DisplacementParametersBuffer({
|
|
@@ -80,15 +78,15 @@ async function init (cobalt, node) {
|
|
|
80
78
|
offsetX: node.options.offseyX ?? 0,
|
|
81
79
|
offsetY: node.options.offseyY ?? 0,
|
|
82
80
|
scale: node.options.scale ?? 20,
|
|
83
|
-
}
|
|
81
|
+
},
|
|
84
82
|
})
|
|
85
83
|
|
|
86
|
-
const MAX_SPRITE_COUNT = 256
|
|
84
|
+
const MAX_SPRITE_COUNT = 256 // max number of displacement sprites in this render pass
|
|
87
85
|
|
|
88
86
|
const trianglesBuffer = new TrianglesBuffer({
|
|
89
87
|
device,
|
|
90
88
|
maxSpriteCount: MAX_SPRITE_COUNT,
|
|
91
|
-
})
|
|
89
|
+
})
|
|
92
90
|
|
|
93
91
|
const displacementTexture = new DisplacementTexture({
|
|
94
92
|
device,
|
|
@@ -99,7 +97,7 @@ async function init (cobalt, node) {
|
|
|
99
97
|
blurFactor: 8,
|
|
100
98
|
|
|
101
99
|
trianglesBuffer,
|
|
102
|
-
})
|
|
100
|
+
})
|
|
103
101
|
|
|
104
102
|
const displacementComposition = new DisplacementComposition({
|
|
105
103
|
device,
|
|
@@ -108,9 +106,9 @@ async function init (cobalt, node) {
|
|
|
108
106
|
colorTextureView: node.refs.color.data.view,
|
|
109
107
|
noiseMapTextureView: node.refs.map.view,
|
|
110
108
|
displacementTextureView: displacementTexture.getView(),
|
|
111
|
-
|
|
109
|
+
|
|
112
110
|
displacementParametersBuffer: displacementParameters,
|
|
113
|
-
})
|
|
111
|
+
})
|
|
114
112
|
|
|
115
113
|
return {
|
|
116
114
|
displacementParameters,
|
|
@@ -120,16 +118,14 @@ async function init (cobalt, node) {
|
|
|
120
118
|
}
|
|
121
119
|
}
|
|
122
120
|
|
|
123
|
-
|
|
124
121
|
function draw(cobalt, node, commandEncoder) {
|
|
125
|
-
const spriteCount = node.data.trianglesBuffer.spriteCount
|
|
122
|
+
const spriteCount = node.data.trianglesBuffer.spriteCount
|
|
126
123
|
|
|
127
|
-
if (spriteCount === 0)
|
|
128
|
-
return
|
|
124
|
+
if (spriteCount === 0) return
|
|
129
125
|
|
|
130
|
-
node.data.trianglesBuffer.update()
|
|
126
|
+
node.data.trianglesBuffer.update()
|
|
131
127
|
|
|
132
|
-
node.data.displacementTexture.update(commandEncoder)
|
|
128
|
+
node.data.displacementTexture.update(commandEncoder)
|
|
133
129
|
|
|
134
130
|
const renderpass = commandEncoder.beginRenderPass({
|
|
135
131
|
label: 'displacement',
|
|
@@ -138,25 +134,24 @@ function draw(cobalt, node, commandEncoder) {
|
|
|
138
134
|
view: node.refs.out,
|
|
139
135
|
clearValue: cobalt.clearValue,
|
|
140
136
|
loadOp: 'load',
|
|
141
|
-
storeOp: 'store'
|
|
142
|
-
}
|
|
137
|
+
storeOp: 'store',
|
|
138
|
+
},
|
|
143
139
|
],
|
|
144
|
-
})
|
|
145
|
-
renderpass.executeBundles([node.data.displacementComposition.getRenderBundle()])
|
|
140
|
+
})
|
|
141
|
+
renderpass.executeBundles([node.data.displacementComposition.getRenderBundle()])
|
|
146
142
|
renderpass.end()
|
|
147
143
|
}
|
|
148
144
|
|
|
145
|
+
function destroy(node) {
|
|
146
|
+
node.data.trianglesBuffer.destroy()
|
|
147
|
+
node.data.trianglesBuffer = null
|
|
149
148
|
|
|
150
|
-
|
|
151
|
-
node.data.
|
|
152
|
-
node.data.trianglesBuffer = null;
|
|
153
|
-
|
|
154
|
-
node.data.displacementParameters.destroy();
|
|
155
|
-
node.data.displacementParameters = null;
|
|
149
|
+
node.data.displacementParameters.destroy()
|
|
150
|
+
node.data.displacementParameters = null
|
|
156
151
|
|
|
157
|
-
node.data.displacementTexture.destroy()
|
|
158
|
-
node.data.displacementTexture = null
|
|
152
|
+
node.data.displacementTexture.destroy()
|
|
153
|
+
node.data.displacementTexture = null
|
|
159
154
|
|
|
160
|
-
node.data.displacementComposition.destroy()
|
|
161
|
-
node.data.displacementComposition = null
|
|
155
|
+
node.data.displacementComposition.destroy()
|
|
156
|
+
node.data.displacementComposition = null
|
|
162
157
|
}
|