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