webgpu-computed 0.0.10 → 0.0.12
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/package.json +1 -1
- package/src/build.d.ts +2 -2
- package/src/index.js +191 -171
- package/src/utils/GpuComputed.d.ts +5 -3
package/package.json
CHANGED
package/src/build.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { GpuComputed } from './utils/GpuComputed';
|
|
1
|
+
import { GpuComputed, AtomicUint32Array } from './utils/GpuComputed';
|
|
2
2
|
import * as WGSL_Fun from "./utils/WGSL_Fun";
|
|
3
|
-
export { GpuComputed, WGSL_Fun };
|
|
3
|
+
export { GpuComputed, WGSL_Fun, AtomicUint32Array };
|
package/src/index.js
CHANGED
|
@@ -1,127 +1,140 @@
|
|
|
1
|
-
async function
|
|
1
|
+
async function _(f, e = !0) {
|
|
2
2
|
if (typeof global < "u" && typeof require < "u")
|
|
3
3
|
return require(f);
|
|
4
4
|
{
|
|
5
|
-
let
|
|
5
|
+
let r = await import(
|
|
6
6
|
/* @vite-ignore */
|
|
7
7
|
f
|
|
8
8
|
);
|
|
9
|
-
return e && (
|
|
9
|
+
return e && (r = r.default), r;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
function q(f) {
|
|
13
|
+
if (f instanceof Float32Array) return "f32";
|
|
14
|
+
if (f instanceof Int32Array) return "i32";
|
|
15
|
+
if (f instanceof Uint32Array) return "u32";
|
|
16
|
+
throw new Error(
|
|
17
|
+
`Unsupported ArrayBufferView type: ${f.constructor.name}`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
12
20
|
function S(f) {
|
|
13
21
|
return f && f[0].toUpperCase() + f.slice(1);
|
|
14
22
|
}
|
|
15
23
|
function x(f) {
|
|
16
24
|
return O.includes(f);
|
|
17
25
|
}
|
|
18
|
-
function
|
|
26
|
+
function A(f) {
|
|
19
27
|
return f && Array.isArray(f) && f.length ? f.every((e) => e && typeof e == "object" && "name" in e && "type" in e && x(e.type)) : !1;
|
|
20
28
|
}
|
|
21
29
|
function $(f) {
|
|
22
|
-
return f && "layout" in f &&
|
|
30
|
+
return f && "layout" in f && A(f.layout);
|
|
23
31
|
}
|
|
24
|
-
function
|
|
25
|
-
const
|
|
26
|
-
return (
|
|
32
|
+
function U(f, e) {
|
|
33
|
+
const r = E[e];
|
|
34
|
+
return (r - f % r) % r;
|
|
27
35
|
}
|
|
28
|
-
function
|
|
36
|
+
function z(f, e) {
|
|
29
37
|
return f + (e - f % e) % e;
|
|
30
38
|
}
|
|
31
|
-
function
|
|
32
|
-
const e = Object.keys(f),
|
|
33
|
-
const
|
|
34
|
-
if (Array.isArray(
|
|
35
|
-
for (const
|
|
36
|
-
if (
|
|
37
|
-
throw new Error(`${
|
|
39
|
+
function P(f) {
|
|
40
|
+
const e = Object.keys(f), r = e.map((l) => {
|
|
41
|
+
const a = f[l];
|
|
42
|
+
if (Array.isArray(a)) {
|
|
43
|
+
for (const o of ["vec2", "vec3", "vec4", "mat3x3", "mat4x4"])
|
|
44
|
+
if (B[o] === a.length) return o;
|
|
45
|
+
throw new Error(`${l} 不支持的数组长度 ${a.length}`);
|
|
38
46
|
}
|
|
39
|
-
if (typeof
|
|
40
|
-
throw new Error(`${
|
|
47
|
+
if (typeof a == "number") return "f32";
|
|
48
|
+
throw new Error(`${l} 不支持的类型`);
|
|
41
49
|
});
|
|
42
|
-
if (e.length !==
|
|
43
|
-
let
|
|
44
|
-
const s = e.map((
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
name:
|
|
49
|
-
type:
|
|
50
|
-
offset:
|
|
51
|
-
size:
|
|
50
|
+
if (e.length !== r.length) throw new Error("keys 与 types 长度不一致");
|
|
51
|
+
let u = 0;
|
|
52
|
+
const s = e.map((l, a) => {
|
|
53
|
+
const o = r[a];
|
|
54
|
+
u += U(u, o);
|
|
55
|
+
const i = {
|
|
56
|
+
name: l,
|
|
57
|
+
type: o,
|
|
58
|
+
offset: u,
|
|
59
|
+
size: B[o]
|
|
52
60
|
};
|
|
53
|
-
return
|
|
54
|
-
}),
|
|
61
|
+
return u += B[o], i;
|
|
62
|
+
}), t = Math.max(...r.map((l) => E[l]));
|
|
55
63
|
return {
|
|
56
|
-
stride:
|
|
64
|
+
stride: u + (t - u % t) % t,
|
|
57
65
|
layout: s
|
|
58
66
|
};
|
|
59
67
|
}
|
|
60
|
-
const
|
|
68
|
+
const B = {
|
|
61
69
|
f32: 1,
|
|
70
|
+
u32: 1,
|
|
62
71
|
vec2: 2,
|
|
63
72
|
vec3: 3,
|
|
64
73
|
vec4: 4,
|
|
65
74
|
mat3x3: 12,
|
|
66
75
|
mat4x4: 16
|
|
67
76
|
// array: Infinity
|
|
68
|
-
},
|
|
77
|
+
}, E = {
|
|
69
78
|
f32: 1,
|
|
79
|
+
u32: 1,
|
|
70
80
|
vec2: 2,
|
|
71
81
|
vec3: 4,
|
|
72
82
|
vec4: 4,
|
|
73
83
|
mat3x3: 4,
|
|
74
84
|
mat4x4: 4
|
|
75
85
|
// array: 1
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
};
|
|
87
|
+
class D extends Uint32Array {
|
|
88
|
+
}
|
|
89
|
+
const O = ["f32", "u32", "vec2", "vec3", "vec4", "mat3x3", "mat4x4"];
|
|
90
|
+
let h = null, b = null;
|
|
91
|
+
class T {
|
|
79
92
|
template;
|
|
80
93
|
option;
|
|
81
94
|
pipeline;
|
|
82
95
|
device;
|
|
83
96
|
groupLayout;
|
|
84
97
|
code;
|
|
85
|
-
constructor(e,
|
|
86
|
-
this.template = e, this.option =
|
|
98
|
+
constructor(e, r) {
|
|
99
|
+
this.template = e, this.option = r, this.improveTemplateOption(this.template);
|
|
87
100
|
}
|
|
88
101
|
/** 完善模版数据
|
|
89
102
|
* @param template
|
|
90
103
|
*/
|
|
91
104
|
improveTemplateOption(e) {
|
|
92
|
-
const
|
|
93
|
-
let
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
const r = (t) => {
|
|
106
|
+
let n = 0;
|
|
107
|
+
t.forEach((l) => {
|
|
108
|
+
n += U(n, l.type), l.offset = n, l.size = B[l.type], n += l.size;
|
|
96
109
|
});
|
|
97
|
-
},
|
|
98
|
-
t
|
|
99
|
-
const
|
|
100
|
-
let
|
|
101
|
-
for (const
|
|
102
|
-
|
|
110
|
+
}, u = (t) => {
|
|
111
|
+
r(t.layout);
|
|
112
|
+
const n = t.layout[t.layout.length - 1], l = n.offset + n.size;
|
|
113
|
+
let a = 1;
|
|
114
|
+
for (const o of t.layout) a = Math.max(a, E[o.type]);
|
|
115
|
+
t.stride = z(l, a);
|
|
103
116
|
};
|
|
104
|
-
Object.keys(e).forEach((
|
|
105
|
-
const
|
|
106
|
-
|
|
117
|
+
Object.keys(e).forEach((t) => {
|
|
118
|
+
const n = e[t];
|
|
119
|
+
A(n) ? r(n) : $(n) ? u(n) : Array.isArray(n) && typeof n[0] == "number" && (e[t] = new Float32Array());
|
|
107
120
|
});
|
|
108
121
|
}
|
|
109
122
|
/** 获取Gpu设备
|
|
110
123
|
* @returns
|
|
111
124
|
*/
|
|
112
125
|
async getDevice() {
|
|
113
|
-
if (!
|
|
114
|
-
return { adapter:
|
|
126
|
+
if (!h || !b) throw new Error("webgpu未初始化或不可用");
|
|
127
|
+
return { adapter: h, device: b };
|
|
115
128
|
}
|
|
116
129
|
/**
|
|
117
130
|
* 初始化计算管线
|
|
118
131
|
*/
|
|
119
132
|
async initPipeline() {
|
|
120
133
|
if (!this.template) throw new Error("初始化计算管线错误,未找到可用数据模版");
|
|
121
|
-
await
|
|
122
|
-
const e = this.template, { device:
|
|
123
|
-
this.device =
|
|
124
|
-
if (
|
|
134
|
+
await T.init();
|
|
135
|
+
const e = this.template, { device: r } = await this.getDevice(), u = [], s = [], t = [];
|
|
136
|
+
this.device = r, Object.keys(e).forEach((y, d) => {
|
|
137
|
+
if (t.push({
|
|
125
138
|
binding: d,
|
|
126
139
|
// 绑定到组里的0号位插槽
|
|
127
140
|
visibility: GPUShaderStage.COMPUTE,
|
|
@@ -129,45 +142,47 @@ class z {
|
|
|
129
142
|
buffer: {
|
|
130
143
|
type: "storage"
|
|
131
144
|
}
|
|
132
|
-
}),
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
} else if ($(e[
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
} else
|
|
139
|
-
|
|
145
|
+
}), A(e[y])) {
|
|
146
|
+
const g = e[y], v = g.map((w) => `${w.name}:${w.type === "f32" ? "f32" : w.type + "<f32>"}`).join(","), m = `${S(y)}Struct`;
|
|
147
|
+
u.push(`struct ${S(y)}Struct {${v}};`), s.push(`@group(0) @binding(${d}) var<storage, read_write> ${y}: ${m};`);
|
|
148
|
+
} else if ($(e[y])) {
|
|
149
|
+
const g = e[y], v = g.layout.map((w) => `${w.name}:${w.type === "f32" ? "f32" : w.type + "<f32>"}`).join(","), m = `${S(y)}Struct`;
|
|
150
|
+
u.push(`struct ${m} {${v}};`), s.push(`@group(0) @binding(${d}) var<storage, read_write> ${y}: array<${m}>;`);
|
|
151
|
+
} else if (ArrayBuffer.isView(e[y]) && !(e[y] instanceof DataView)) {
|
|
152
|
+
const g = e[y], v = q(g);
|
|
153
|
+
g instanceof D ? s.push(`@group(0) @binding(${d}) var<storage, read_write> ${y}: array<atomic<${v}>>;`) : s.push(`@group(0) @binding(${d}) var<storage, read_write> ${y}: array<${v}>;`);
|
|
154
|
+
}
|
|
140
155
|
});
|
|
141
156
|
const {
|
|
142
|
-
beforeCodes:
|
|
143
|
-
workgroupSize:
|
|
144
|
-
globalInvocationIdName:
|
|
145
|
-
workgroupIndexName:
|
|
146
|
-
code:
|
|
147
|
-
} = this.option ?? {},
|
|
157
|
+
beforeCodes: n = [],
|
|
158
|
+
workgroupSize: l = [32, 1, 1],
|
|
159
|
+
globalInvocationIdName: a = "grid",
|
|
160
|
+
workgroupIndexName: o = "index",
|
|
161
|
+
code: i = ""
|
|
162
|
+
} = this.option ?? {}, c = (
|
|
148
163
|
/*wgsl*/
|
|
149
164
|
`
|
|
150
|
-
${
|
|
165
|
+
${u.join("")}
|
|
151
166
|
${s.join("")}
|
|
152
|
-
${
|
|
167
|
+
${n.join(" ") ?? ""}
|
|
153
168
|
|
|
154
|
-
@compute @workgroup_size(${
|
|
155
|
-
fn main(@builtin(global_invocation_id) ${
|
|
156
|
-
var ${
|
|
157
|
-
${
|
|
169
|
+
@compute @workgroup_size(${l.join(",")})
|
|
170
|
+
fn main(@builtin(global_invocation_id) ${a}: vec3<u32>) {
|
|
171
|
+
var ${o} = ${a}.x;
|
|
172
|
+
${i}
|
|
158
173
|
}
|
|
159
174
|
`
|
|
160
175
|
);
|
|
161
|
-
this.code =
|
|
162
|
-
const
|
|
163
|
-
entries:
|
|
176
|
+
this.code = c;
|
|
177
|
+
const p = r.createBindGroupLayout({
|
|
178
|
+
entries: t
|
|
164
179
|
});
|
|
165
|
-
this.groupLayout =
|
|
166
|
-
layout:
|
|
167
|
-
bindGroupLayouts: [
|
|
180
|
+
this.groupLayout = p, this.pipeline = r.createComputePipeline({
|
|
181
|
+
layout: r.createPipelineLayout({
|
|
182
|
+
bindGroupLayouts: [p]
|
|
168
183
|
}),
|
|
169
184
|
compute: {
|
|
170
|
-
module:
|
|
185
|
+
module: r.createShaderModule({ code: c, label: "" }),
|
|
171
186
|
entryPoint: "main"
|
|
172
187
|
}
|
|
173
188
|
});
|
|
@@ -178,44 +193,46 @@ ${s.join("")}
|
|
|
178
193
|
createBindGroup(e) {
|
|
179
194
|
if (!this.template) throw new Error("创建buffer组错误,未找到可用数据模版");
|
|
180
195
|
if (!this.device) throw new Error("创建buffer组错误,未找到可用的gpu设备,请确保初始化完计算管线");
|
|
181
|
-
const
|
|
182
|
-
function
|
|
183
|
-
if (!
|
|
184
|
-
const
|
|
196
|
+
const r = this.device, u = this.template, s = [];
|
|
197
|
+
function t(a, o, i = 0, c) {
|
|
198
|
+
if (!c) {
|
|
199
|
+
const p = o[o.length - 1], y = p.offset + p.size;
|
|
185
200
|
let d = 1;
|
|
186
|
-
for (const
|
|
187
|
-
|
|
201
|
+
for (const g of o) d = Math.max(d, E[g.type]);
|
|
202
|
+
c = c ?? new Array(z(y, d)).fill(0);
|
|
188
203
|
}
|
|
189
|
-
return
|
|
190
|
-
let
|
|
191
|
-
Array.isArray(
|
|
192
|
-
for (let d = 0; d <
|
|
193
|
-
|
|
194
|
-
}),
|
|
204
|
+
return o.forEach((p) => {
|
|
205
|
+
let y = a[p.name];
|
|
206
|
+
Array.isArray(y) || (y = [y]);
|
|
207
|
+
for (let d = 0; d < p.size; d++)
|
|
208
|
+
c[i + p.offset + d] = Number(y[d] ?? 0);
|
|
209
|
+
}), c;
|
|
195
210
|
}
|
|
196
|
-
function
|
|
197
|
-
const
|
|
198
|
-
return
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
}),
|
|
211
|
+
function n(a, o) {
|
|
212
|
+
const i = new Array(o.stride * a.length).fill(0);
|
|
213
|
+
return a.forEach((c, p) => {
|
|
214
|
+
const y = p * o.stride;
|
|
215
|
+
t(c, o.layout, y, i);
|
|
216
|
+
}), i;
|
|
202
217
|
}
|
|
203
|
-
return Object.keys(
|
|
204
|
-
if (!(
|
|
205
|
-
const
|
|
206
|
-
let
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
218
|
+
return Object.keys(u).forEach((a) => {
|
|
219
|
+
if (!(a in e)) throw new Error(`传入的数据中,不存在${a}字段`);
|
|
220
|
+
const o = u[a], i = e[a];
|
|
221
|
+
let c = [];
|
|
222
|
+
A(o) ? c = t(i, o) : $(o) ? c = n(i, o) : Array.isArray(i) && (c = i);
|
|
223
|
+
let p = null;
|
|
224
|
+
if (o instanceof Float32Array ? p = new Float32Array(c) : o instanceof Uint32Array ? p = new Uint32Array(c) : o instanceof Int32Array ? p = new Int32Array(c) : p = new Float32Array(c), !p) throw new Error("不支持的数组类型" + o);
|
|
225
|
+
const y = r.createBuffer({
|
|
226
|
+
size: p.byteLength,
|
|
210
227
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC | GPUBufferUsage.STORAGE
|
|
211
228
|
});
|
|
212
|
-
|
|
229
|
+
r.queue.writeBuffer(y, 0, p), s.push({ name: a, buffer: y });
|
|
213
230
|
}), {
|
|
214
|
-
group:
|
|
231
|
+
group: r.createBindGroup({
|
|
215
232
|
layout: this.groupLayout,
|
|
216
|
-
entries: s.map((
|
|
217
|
-
binding:
|
|
218
|
-
resource: { buffer:
|
|
233
|
+
entries: s.map((a, o) => ({
|
|
234
|
+
binding: o,
|
|
235
|
+
resource: { buffer: a.buffer }
|
|
219
236
|
}))
|
|
220
237
|
}),
|
|
221
238
|
buffers: s
|
|
@@ -225,24 +242,24 @@ ${s.join("")}
|
|
|
225
242
|
* @param array
|
|
226
243
|
* @param key
|
|
227
244
|
*/
|
|
228
|
-
dataMap(e,
|
|
229
|
-
if (!(
|
|
230
|
-
if ($(this.template[
|
|
231
|
-
const
|
|
232
|
-
for (let
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
const
|
|
236
|
-
|
|
237
|
-
}),
|
|
245
|
+
dataMap(e, r) {
|
|
246
|
+
if (!(r in this.template)) throw new Error("未找到数据字段:" + r);
|
|
247
|
+
if ($(this.template[r])) {
|
|
248
|
+
const u = this.template[r], s = e.length / u.stride, t = [];
|
|
249
|
+
for (let n = 0; n < s; n++) {
|
|
250
|
+
const l = n * u.stride, a = {};
|
|
251
|
+
u.layout.forEach((o) => {
|
|
252
|
+
const i = e.slice(l + o.offset, l + o.offset + o.size);
|
|
253
|
+
a[o.name] = i.length === 1 ? i[0] : i;
|
|
254
|
+
}), t.push(a);
|
|
238
255
|
}
|
|
239
|
-
return
|
|
256
|
+
return t;
|
|
240
257
|
}
|
|
241
|
-
if (
|
|
242
|
-
const
|
|
243
|
-
return
|
|
244
|
-
const
|
|
245
|
-
s[
|
|
258
|
+
if (A(this.template[r])) {
|
|
259
|
+
const u = this.template[r], s = {};
|
|
260
|
+
return u.forEach((t) => {
|
|
261
|
+
const n = e.slice(t.offset, t.offset + t.size);
|
|
262
|
+
s[t.name] = n.length === 1 ? n[0] : n;
|
|
246
263
|
}), s;
|
|
247
264
|
}
|
|
248
265
|
return e;
|
|
@@ -253,24 +270,25 @@ ${s.join("")}
|
|
|
253
270
|
* @param synchronize 需要同步的数据字段
|
|
254
271
|
* @returns
|
|
255
272
|
*/
|
|
256
|
-
async computed(e,
|
|
273
|
+
async computed(e, r, u) {
|
|
257
274
|
if (!this.pipeline) throw new Error("未找到可用计算管线,请确保计算管线已经创建成功");
|
|
258
|
-
const s = this.device,
|
|
259
|
-
|
|
260
|
-
const
|
|
261
|
-
if (
|
|
262
|
-
const
|
|
263
|
-
size:
|
|
275
|
+
const s = this.device, t = this.pipeline, n = s.createCommandEncoder(), l = n.beginComputePass();
|
|
276
|
+
l.setPipeline(t), l.setBindGroup(0, e.group), l.dispatchWorkgroups(r[0], r[1], r[2]), l.end();
|
|
277
|
+
const a = e.buffers?.map((i) => {
|
|
278
|
+
if (u?.includes(i.name)) {
|
|
279
|
+
const c = s.createBuffer({
|
|
280
|
+
size: i.buffer.size,
|
|
264
281
|
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
|
|
265
282
|
});
|
|
266
|
-
return
|
|
283
|
+
return n.copyBufferToBuffer(i.buffer, 0, c, 0, c.size), { buffer: c, name: i.name };
|
|
267
284
|
}
|
|
268
|
-
}).filter((
|
|
269
|
-
return s.queue.submit([
|
|
270
|
-
|
|
271
|
-
await
|
|
272
|
-
const
|
|
273
|
-
|
|
285
|
+
}).filter((i) => !!i);
|
|
286
|
+
return s.queue.submit([n.finish()]), await s.queue.onSubmittedWorkDone(), await Promise.all(
|
|
287
|
+
a.map(async (i) => {
|
|
288
|
+
await i.buffer.mapAsync(GPUMapMode.READ);
|
|
289
|
+
const c = i.buffer.getMappedRange();
|
|
290
|
+
let p = null;
|
|
291
|
+
return this.template[i.name] instanceof Float32Array ? p = new Float32Array(c) : this.template[i.name] instanceof Uint32Array ? p = new Uint32Array(c) : this.template[i.name] instanceof Int32Array ? p = new Int32Array(c) : p = new Float32Array(c), [...p];
|
|
274
292
|
})
|
|
275
293
|
);
|
|
276
294
|
}
|
|
@@ -278,14 +296,14 @@ ${s.join("")}
|
|
|
278
296
|
* @returns
|
|
279
297
|
*/
|
|
280
298
|
static async init() {
|
|
281
|
-
if (!(
|
|
299
|
+
if (!(h && b)) {
|
|
282
300
|
if (typeof globalThis < "u" && typeof window > "u") {
|
|
283
|
-
const { create: e, globals:
|
|
284
|
-
Object.assign(globalThis,
|
|
301
|
+
const { create: e, globals: r } = await _("webgpu", !1);
|
|
302
|
+
Object.assign(globalThis, r), globalThis.navigator || (globalThis.navigator = {}), Object.assign(globalThis.navigator, { gpu: e([]) });
|
|
285
303
|
}
|
|
286
304
|
if (!navigator.gpu) throw new Error("该环境不支持webgpu");
|
|
287
|
-
if (
|
|
288
|
-
if (b = await
|
|
305
|
+
if (h || (h = await navigator.gpu.requestAdapter({})), !h) throw new Error("获取适配器失败");
|
|
306
|
+
if (b = await h.requestDevice(), !h) throw new Error("获取设备失败");
|
|
289
307
|
}
|
|
290
308
|
}
|
|
291
309
|
/** 注销gpu设备
|
|
@@ -297,19 +315,20 @@ ${s.join("")}
|
|
|
297
315
|
* @param data
|
|
298
316
|
*/
|
|
299
317
|
static buildBufferTypeByData(e) {
|
|
300
|
-
return Object.keys(e).reduce((
|
|
301
|
-
|
|
302
|
-
if (Array.isArray(
|
|
303
|
-
if (typeof
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
a[s] = o;
|
|
318
|
+
return Object.keys(e).reduce((u, s) => {
|
|
319
|
+
let t = e[s];
|
|
320
|
+
if (Array.isArray(t) && typeof t[0] == "number" && (t = new Float32Array()), Array.isArray(t))
|
|
321
|
+
if (typeof t[0] == "object" || t.length) {
|
|
322
|
+
const n = P(t[0]);
|
|
323
|
+
u[s] = n;
|
|
307
324
|
} else console.log(`字段:${s}, 不支持该值对应数据类型或数组为空`);
|
|
308
|
-
else if (
|
|
309
|
-
|
|
310
|
-
|
|
325
|
+
else if (ArrayBuffer.isView(t) && !(t instanceof DataView))
|
|
326
|
+
u[s] = t;
|
|
327
|
+
else if (typeof t == "object") {
|
|
328
|
+
const n = P(t);
|
|
329
|
+
u[s] = n.layout;
|
|
311
330
|
} else console.log(`字段:${s}, 不支持的数据类型`);
|
|
312
|
-
return
|
|
331
|
+
return u;
|
|
313
332
|
}, {});
|
|
314
333
|
}
|
|
315
334
|
/** 通过数据创建
|
|
@@ -317,18 +336,18 @@ ${s.join("")}
|
|
|
317
336
|
* @returns
|
|
318
337
|
*/
|
|
319
338
|
static async fromByData(e) {
|
|
320
|
-
let { data:
|
|
321
|
-
const s = this.buildBufferTypeByData(
|
|
322
|
-
return await
|
|
339
|
+
let { data: r, ...u } = e;
|
|
340
|
+
const s = this.buildBufferTypeByData(r), t = new T(s, u);
|
|
341
|
+
return await t.initPipeline(), t;
|
|
323
342
|
}
|
|
324
343
|
/** 快捷计算方法
|
|
325
344
|
* @param opt
|
|
326
345
|
* @returns
|
|
327
346
|
*/
|
|
328
347
|
static async computed(e) {
|
|
329
|
-
let { data:
|
|
330
|
-
const
|
|
331
|
-
return
|
|
348
|
+
let { data: r, map: u = !1, workgroupCount: s, synchronize: t, onSuccess: n, ...l } = e;
|
|
349
|
+
const a = await this.fromByData({ data: r, ...l }), o = a.createBindGroup(r), i = await a.computed(o, s, t);
|
|
350
|
+
return n && n({ gpuComputed: a, group: o, results: i }), u ? i.map((c, p) => a.dataMap(c, t[p])) : i;
|
|
332
351
|
}
|
|
333
352
|
}
|
|
334
353
|
const j = (
|
|
@@ -340,7 +359,7 @@ const j = (
|
|
|
340
359
|
return v + q.w * t + cross(q.xyz, t);
|
|
341
360
|
}
|
|
342
361
|
`
|
|
343
|
-
),
|
|
362
|
+
), G = (
|
|
344
363
|
/* wgsl */
|
|
345
364
|
`
|
|
346
365
|
fn point_in_obb(
|
|
@@ -360,12 +379,13 @@ const j = (
|
|
|
360
379
|
return all(abs(pLocal) <= halfSize);
|
|
361
380
|
}
|
|
362
381
|
`
|
|
363
|
-
),
|
|
382
|
+
), L = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
364
383
|
__proto__: null,
|
|
365
|
-
point_in_obb:
|
|
384
|
+
point_in_obb: G,
|
|
366
385
|
quat_rotate: j
|
|
367
386
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
368
387
|
export {
|
|
369
|
-
|
|
370
|
-
|
|
388
|
+
D as AtomicUint32Array,
|
|
389
|
+
T as GpuComputed,
|
|
390
|
+
L as WGSL_Fun
|
|
371
391
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type WGSl_TYPE = "f32" | "vec2" | "vec3" | "vec4" | "mat3x3" | "mat4x4";
|
|
1
|
+
type WGSl_TYPE = "f32" | "u32" | "vec2" | "vec3" | "vec4" | "mat3x3" | "mat4x4";
|
|
2
2
|
type GpuComputedOption = {
|
|
3
3
|
workgroupSize?: [number, number, number];
|
|
4
4
|
globalInvocationIdName?: string;
|
|
@@ -25,7 +25,9 @@ interface IStructArray {
|
|
|
25
25
|
stride?: number;
|
|
26
26
|
layout: IStruct;
|
|
27
27
|
}
|
|
28
|
-
type BufferDataType = Record<string, (number[]) | IStruct | IStructArray>;
|
|
28
|
+
type BufferDataType = Record<string, (number[]) | ArrayBufferView | IStruct | IStructArray>;
|
|
29
|
+
export declare class AtomicUint32Array extends Uint32Array {
|
|
30
|
+
}
|
|
29
31
|
export declare class GpuComputed {
|
|
30
32
|
template?: BufferDataType;
|
|
31
33
|
option?: GpuComputedOption;
|
|
@@ -81,7 +83,7 @@ export declare class GpuComputed {
|
|
|
81
83
|
/**
|
|
82
84
|
* @param data
|
|
83
85
|
*/
|
|
84
|
-
static buildBufferTypeByData(data: Record<string, any>): Record<string, IStructArray |
|
|
86
|
+
static buildBufferTypeByData(data: Record<string, any>): Record<string, IStructArray | IStruct | ArrayBufferView<ArrayBufferLike>>;
|
|
85
87
|
/** 通过数据创建
|
|
86
88
|
* @param opt
|
|
87
89
|
* @returns
|