webgpu-computed 0.0.1 → 0.0.3
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/.zh.md +395 -0
- package/README.md +121 -100
- package/package.json +2 -2
package/.zh.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# webgpu-computed
|
|
2
|
+
|
|
3
|
+
一个简化的 WebGPU 计算库,封装了繁琐的初始化和缓冲区管理,让开发者专注于 WGSL 着色器逻辑。
|
|
4
|
+
|
|
5
|
+
## 特性
|
|
6
|
+
|
|
7
|
+
- 🚀 简化 WebGPU 初始化
|
|
8
|
+
- 📦 自动缓冲区管理和布局计算
|
|
9
|
+
- 🔧 支持复杂数据结构(向量、矩阵)
|
|
10
|
+
- ⚡ 高性能 GPU 计算
|
|
11
|
+
- 📚 内置常用 WGSL 函数
|
|
12
|
+
|
|
13
|
+
## 安装
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install webgpu-computed
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## node 环境配置
|
|
20
|
+
可安装webgpu包
|
|
21
|
+
```bash
|
|
22
|
+
npm install webgpu
|
|
23
|
+
```
|
|
24
|
+
然后初始化环境
|
|
25
|
+
```js
|
|
26
|
+
import { create, globals } from 'webgpu'
|
|
27
|
+
|
|
28
|
+
Object.assign(globalThis, globals)
|
|
29
|
+
const navigator = { gpu: create([]) }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 快速开始
|
|
33
|
+
|
|
34
|
+
### 1. 初始化 WebGPU
|
|
35
|
+
|
|
36
|
+
在使用任何计算功能前,需要先初始化 WebGPU 环境:
|
|
37
|
+
|
|
38
|
+
```javascript
|
|
39
|
+
import { GpuComputed } from 'webgpu-computed';
|
|
40
|
+
|
|
41
|
+
// 初始化 WebGPU
|
|
42
|
+
await GpuComputed.init();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. 执行简单计算
|
|
46
|
+
|
|
47
|
+
以下是一个简单的向量加法示例:
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
import { GpuComputed } from 'webgpu-computed';
|
|
51
|
+
|
|
52
|
+
// 准备数据
|
|
53
|
+
const data = {
|
|
54
|
+
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
55
|
+
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
56
|
+
output: new Array(4).fill(0) // 输出缓冲区
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// WGSL 计算代码
|
|
60
|
+
const code = `
|
|
61
|
+
output[index] = inputA[index] + inputB[index];
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
// 执行计算
|
|
65
|
+
const results = await GpuComputed.computed({
|
|
66
|
+
code,
|
|
67
|
+
data,
|
|
68
|
+
workgroupCount: [1] // 工作组数量
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
console.log(results); // [[1.5, 3.5, 5.5, 7.5]]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 3. 使用复杂数据结构
|
|
75
|
+
|
|
76
|
+
库支持向量和矩阵类型:
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
const data = {
|
|
80
|
+
positions: [
|
|
81
|
+
{ pos: [1.0, 2.0, 3.0], vel: [0.1, 0.2, 0.3] },
|
|
82
|
+
{ pos: [4.0, 5.0, 6.0], vel: [0.4, 0.5, 0.6] }
|
|
83
|
+
],
|
|
84
|
+
output: new Array(2).fill({ pos: [0,0,0], vel: [0,0,0] })
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const code = `
|
|
88
|
+
output[index].pos = positions[index].pos + positions[index].vel;
|
|
89
|
+
output[index].vel = positions[index].vel * 2.0;
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
const results = await GpuComputed.computed({
|
|
93
|
+
code,
|
|
94
|
+
data,
|
|
95
|
+
workgroupCount: [1]
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## API 参考
|
|
100
|
+
|
|
101
|
+
### GpuComputed 类
|
|
102
|
+
|
|
103
|
+
#### 静态方法
|
|
104
|
+
|
|
105
|
+
##### `GpuComputed.init()`
|
|
106
|
+
|
|
107
|
+
初始化 WebGPU 环境。必须在使用其他功能前调用。
|
|
108
|
+
|
|
109
|
+
**返回值**: `Promise<void>`
|
|
110
|
+
|
|
111
|
+
**抛出**: 如果浏览器不支持 WebGPU 或获取适配器/设备失败
|
|
112
|
+
|
|
113
|
+
##### `GpuComputed.computed(options)`
|
|
114
|
+
|
|
115
|
+
执行 GPU 计算任务。
|
|
116
|
+
|
|
117
|
+
**参数**:
|
|
118
|
+
|
|
119
|
+
- `code` (string): WGSL 计算代码
|
|
120
|
+
- `data` (object): 输入/输出数据对象
|
|
121
|
+
- `workgroupCount` (array): 工作组数量 [x, y?, z?]
|
|
122
|
+
- `workgroupSize` (array, 可选): 工作组大小,默认 [32, 1, 1]
|
|
123
|
+
- `globalInvocationIdName` (string, 可选): 全局调用 ID 变量名,默认 "grid"
|
|
124
|
+
- `workgroupIndexName` (string, 可选): 工作组索引变量名,默认 "index"
|
|
125
|
+
- `synchronize` (array, 可选): 需要同步回 CPU 的缓冲区名称数组
|
|
126
|
+
- `beforeCodes` (array, 可选): 计算函数前的 WGSL 代码片段
|
|
127
|
+
- `onSuccess` (function, 可选): 计算成功回调函数
|
|
128
|
+
|
|
129
|
+
**返回值**: `Promise<Array<Float32Array>>` - 同步缓冲区的数据
|
|
130
|
+
|
|
131
|
+
### 数据类型
|
|
132
|
+
|
|
133
|
+
支持以下 WGSL 类型:
|
|
134
|
+
|
|
135
|
+
- `f32`: 单精度浮点数
|
|
136
|
+
- `vec2`: 二维向量
|
|
137
|
+
- `vec3`: 三维向量
|
|
138
|
+
- `vec4`: 四维向量
|
|
139
|
+
- `mat3x3`: 3x3 矩阵
|
|
140
|
+
- `mat4x4`: 4x4 矩阵
|
|
141
|
+
|
|
142
|
+
### 内置 WGSL 函数
|
|
143
|
+
|
|
144
|
+
库提供了一些常用的 WGSL 辅助函数:
|
|
145
|
+
|
|
146
|
+
#### 四元数旋转
|
|
147
|
+
|
|
148
|
+
```wgsl
|
|
149
|
+
fn quat_rotate(q: vec4<f32>, v: vec3<f32>) -> vec3<f32>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
使用示例:
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
import { WGSL_Fun } from 'webgpu-computed';
|
|
156
|
+
|
|
157
|
+
await GpuComputed.computed({
|
|
158
|
+
code: "",
|
|
159
|
+
data: {....},
|
|
160
|
+
beforeCodes:[WGSL_Fun.quat_rotate]
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### 点在 OBB 中的检测
|
|
166
|
+
|
|
167
|
+
```wgsl
|
|
168
|
+
fn point_in_obb(point: vec3<f32>, center: vec3<f32>, halfSize: vec3<f32>, quat: vec4<f32>) -> bool
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## 高级用法
|
|
172
|
+
|
|
173
|
+
### 自定义工作组配置
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
await GpuComputed.computed({
|
|
177
|
+
code: '...',
|
|
178
|
+
data: {...},
|
|
179
|
+
workgroupCount: [4, 4], // 16 个工作组
|
|
180
|
+
workgroupSize: [16, 16], // 每个工作组 256 个线程
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 同步数据回 CPU
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
const results = await GpuComputed.computed({
|
|
188
|
+
code: '...',
|
|
189
|
+
data: {...},
|
|
190
|
+
synchronize: ['output'], // 指定需要同步的缓冲区
|
|
191
|
+
workgroupCount: [1]
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// results 包含同步回的数据
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 回调函数
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
await GpuComputed.computed({
|
|
201
|
+
code: '...',
|
|
202
|
+
data: {...},
|
|
203
|
+
workgroupCount: [1],
|
|
204
|
+
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
205
|
+
console.log('计算完成', results);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 浏览器支持
|
|
211
|
+
|
|
212
|
+
- Chrome 113+
|
|
213
|
+
- Edge 113+
|
|
214
|
+
- Firefox (部分支持)
|
|
215
|
+
- Safari (部分支持)
|
|
216
|
+
|
|
217
|
+
确保浏览器支持 WebGPU API。
|
|
218
|
+
|
|
219
|
+
## 示例项目
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
import { GpuComputed } from "webgpu-computed"
|
|
223
|
+
|
|
224
|
+
// 1. 初始化 WebGPU
|
|
225
|
+
console.log('初始化 WebGPU...');
|
|
226
|
+
await GpuComputed.init();
|
|
227
|
+
console.log('WebGPU 初始化成功');
|
|
228
|
+
|
|
229
|
+
// 2. 简单数组计算示例
|
|
230
|
+
console.log('\n=== 简单数组计算 ===');
|
|
231
|
+
const simpleData = {
|
|
232
|
+
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
233
|
+
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
234
|
+
output: new Array(4).fill(0)
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const simpleCode = `
|
|
238
|
+
output[index] = inputA[index] + inputB[index];
|
|
239
|
+
`;
|
|
240
|
+
|
|
241
|
+
const simpleResults = await GpuComputed.computed({
|
|
242
|
+
code: simpleCode,
|
|
243
|
+
data: simpleData,
|
|
244
|
+
workgroupCount: [1],
|
|
245
|
+
synchronize: ['output']
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
console.log('简单计算结果:', simpleResults[0]); // [1.5, 3.5, 5.5, 7.5]
|
|
249
|
+
|
|
250
|
+
// 3. 复杂数据结构示例(结构体)
|
|
251
|
+
console.log('\n=== 复杂数据结构计算 ===');
|
|
252
|
+
const complexData = {
|
|
253
|
+
particles: [
|
|
254
|
+
{ position: [1.0, 2.0, 3.0], velocity: [0.1, 0.2, 0.3], mass: 1.0 },
|
|
255
|
+
{ position: [4.0, 5.0, 6.0], velocity: [0.4, 0.5, 0.6], mass: 2.0 }
|
|
256
|
+
],
|
|
257
|
+
output: [
|
|
258
|
+
{ position: [0, 0, 0], velocity: [0, 0, 0], mass: 0 },
|
|
259
|
+
{ position: [0, 0, 0], velocity: [0, 0, 0], mass: 0 }
|
|
260
|
+
]
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const complexCode = `
|
|
264
|
+
output[index].position = particles[index].position + particles[index].velocity;
|
|
265
|
+
output[index].velocity = particles[index].velocity * 2.0;
|
|
266
|
+
output[index].mass = particles[index].mass * 1.5;
|
|
267
|
+
`;
|
|
268
|
+
|
|
269
|
+
const complexResults = await GpuComputed.computed({
|
|
270
|
+
code: complexCode,
|
|
271
|
+
data: complexData,
|
|
272
|
+
workgroupCount: [1],
|
|
273
|
+
synchronize: ['output']
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
console.log('复杂计算结果:', complexResults[0]);
|
|
277
|
+
|
|
278
|
+
// 4. 使用内置 WGSL 函数示例
|
|
279
|
+
console.log('\n=== 使用内置 WGSL 函数 ===');
|
|
280
|
+
const wgslFunData = {
|
|
281
|
+
points: [
|
|
282
|
+
{
|
|
283
|
+
x: 1.0, y: 0.0, z: 0.0
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
x: 0.0, y: 1.0, z: 0.0
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
x: -1.0, y: 0.0, z: 0.0
|
|
290
|
+
}
|
|
291
|
+
],
|
|
292
|
+
obbCenter: [0.0, 0.0, 0.0],
|
|
293
|
+
obbHalfSize: [2.0, 2.0, 2.0],
|
|
294
|
+
obbRotation: [0.0, 0.0, 0.0, 1.0], // 单位四元数,无旋转
|
|
295
|
+
results: new Array(3).fill(0)
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const wgslFunCode = `
|
|
299
|
+
let point = vec3(points[index].x, points[index].y, points[index].z);
|
|
300
|
+
let center = vec3<f32>(obbCenter[0], obbCenter[1], obbCenter[2]);
|
|
301
|
+
let halfSize = vec3<f32>(obbHalfSize[0], obbHalfSize[1], obbHalfSize[2]);
|
|
302
|
+
let quat = vec4<f32>(obbRotation[0], obbRotation[1], obbRotation[2], obbRotation[3]);
|
|
303
|
+
|
|
304
|
+
if (point_in_obb(point, center, halfSize, quat)) {
|
|
305
|
+
results[index] = 1.0;
|
|
306
|
+
} else {
|
|
307
|
+
results[index] = 0.0;
|
|
308
|
+
}
|
|
309
|
+
`;
|
|
310
|
+
|
|
311
|
+
const wgslFunResults = await GpuComputed.computed({
|
|
312
|
+
code: wgslFunCode,
|
|
313
|
+
data: wgslFunData,
|
|
314
|
+
workgroupCount: [1],
|
|
315
|
+
beforeCodes: [WGSL_Fun.quat_rotate, WGSL_Fun.point_in_obb, /** 可添加自己的函数代码 */],
|
|
316
|
+
synchronize: ['results']
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
console.log('OBB 检测结果:', wgslFunResults[0]); // [1, 1, 1] 所有点都在 OBB 内
|
|
320
|
+
|
|
321
|
+
// 5. 自定义工作组配置示例
|
|
322
|
+
console.log('\n=== 自定义工作组配置 ===');
|
|
323
|
+
const largeData = {
|
|
324
|
+
largeArray: new Array(1024).fill(0).map((_, i) => i * 1.0),
|
|
325
|
+
output: new Array(1024).fill(0)
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const largeCode = `
|
|
329
|
+
output[index] = largeArray[index] * 2.0;
|
|
330
|
+
`;
|
|
331
|
+
|
|
332
|
+
const largeResults = await GpuComputed.computed({
|
|
333
|
+
code: largeCode,
|
|
334
|
+
data: largeData,
|
|
335
|
+
workgroupCount: [32], // 32 个工作组
|
|
336
|
+
workgroupSize: [32, 1, 1], // 每个工作组 32 个线程,总共 1024 个线程
|
|
337
|
+
synchronize: ['output']
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
console.log('大数组计算结果 (前10个):', largeResults[0].slice(0, 10));
|
|
341
|
+
|
|
342
|
+
// 6. 使用回调函数示例
|
|
343
|
+
console.log('\n=== 使用回调函数 ===');
|
|
344
|
+
const callbackData = {
|
|
345
|
+
values: [10.0, 20.0, 30.0],
|
|
346
|
+
squares: new Array(3).fill(0)
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const callbackCode = `
|
|
350
|
+
squares[index] = values[index] * values[index];
|
|
351
|
+
`;
|
|
352
|
+
|
|
353
|
+
await GpuComputed.computed({
|
|
354
|
+
code: callbackCode,
|
|
355
|
+
data: callbackData,
|
|
356
|
+
workgroupCount: [1],
|
|
357
|
+
synchronize: ['squares'],
|
|
358
|
+
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
359
|
+
console.log('回调函数触发,计算平方结果:', results[0]); // [100, 400, 900]
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
// 7. 多维工作组示例
|
|
364
|
+
console.log('\n=== 多维工作组 ===');
|
|
365
|
+
const matrixData = {
|
|
366
|
+
matrixA: new Array(16).fill(0).map((_, i) => i * 1.0),
|
|
367
|
+
matrixB: new Array(16).fill(0).map((_, i) => (i + 1) * 1.0),
|
|
368
|
+
result: new Array(16).fill(0)
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const matrixCode = `
|
|
372
|
+
let x = index % 4u;
|
|
373
|
+
let y = index / 4u;
|
|
374
|
+
let idx = y * 4u + x;
|
|
375
|
+
result[idx] = matrixA[idx] + matrixB[idx];
|
|
376
|
+
`;
|
|
377
|
+
|
|
378
|
+
const matrixResults = await GpuComputed.computed({
|
|
379
|
+
code: matrixCode,
|
|
380
|
+
data: matrixData,
|
|
381
|
+
workgroupCount: [4, 4], // 4x4 工作组网格
|
|
382
|
+
workgroupSize: [1, 1, 1], // 每个工作组 1 个线程
|
|
383
|
+
synchronize: ['result']
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
console.log('矩阵计算结果:', matrixResults[0]);
|
|
387
|
+
|
|
388
|
+
console.log('\n所有功能示例运行完成!');
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## 许可证
|
|
392
|
+
|
|
393
|
+
ISC License
|
|
394
|
+
|
|
395
|
+
---
|
package/README.md
CHANGED
|
@@ -1,66 +1,85 @@
|
|
|
1
|
+
For the Chinese version, see [中文版](.zh.md)
|
|
2
|
+
|
|
1
3
|
# webgpu-computed
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
A simplified WebGPU computing library that encapsulates tedious initialization and buffer management, allowing developers to focus on WGSL shader logic.
|
|
4
6
|
|
|
5
|
-
##
|
|
7
|
+
## Features
|
|
6
8
|
|
|
7
|
-
- 🚀
|
|
8
|
-
- 📦
|
|
9
|
-
- 🔧
|
|
10
|
-
- ⚡
|
|
11
|
-
- 📚
|
|
9
|
+
- 🚀 Simplified WebGPU initialization
|
|
10
|
+
- 📦 Automatic buffer management and layout calculation
|
|
11
|
+
- 🔧 Support for complex data structures (vectors, matrices)
|
|
12
|
+
- ⚡ High-performance GPU computing
|
|
13
|
+
- 📚 Built-in common WGSL functions
|
|
12
14
|
|
|
13
|
-
##
|
|
15
|
+
## Installation
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
18
|
npm install webgpu-computed
|
|
17
19
|
```
|
|
18
20
|
|
|
19
|
-
##
|
|
21
|
+
## Node.js Environment Configuration
|
|
22
|
+
|
|
23
|
+
You can install the webgpu package
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install webgpu
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Then initialize the environment
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import { create, globals } from 'webgpu'
|
|
33
|
+
|
|
34
|
+
Object.assign(globalThis, globals)
|
|
35
|
+
const navigator = { gpu: create([]) }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
20
39
|
|
|
21
|
-
### 1.
|
|
40
|
+
### 1. Initialize WebGPU
|
|
22
41
|
|
|
23
|
-
|
|
42
|
+
Before using any computing features, you need to initialize the WebGPU environment:
|
|
24
43
|
|
|
25
44
|
```javascript
|
|
26
45
|
import { GpuComputed } from 'webgpu-computed';
|
|
27
46
|
|
|
28
|
-
//
|
|
47
|
+
// Initialize WebGPU
|
|
29
48
|
await GpuComputed.init();
|
|
30
49
|
```
|
|
31
50
|
|
|
32
|
-
### 2.
|
|
51
|
+
### 2. Perform Simple Computation
|
|
33
52
|
|
|
34
|
-
|
|
53
|
+
Here is a simple vector addition example:
|
|
35
54
|
|
|
36
55
|
```javascript
|
|
37
56
|
import { GpuComputed } from 'webgpu-computed';
|
|
38
57
|
|
|
39
|
-
//
|
|
58
|
+
// Prepare data
|
|
40
59
|
const data = {
|
|
41
60
|
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
42
61
|
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
43
|
-
output: new Array(4).fill(0) //
|
|
62
|
+
output: new Array(4).fill(0) // Output buffer
|
|
44
63
|
};
|
|
45
64
|
|
|
46
|
-
// WGSL
|
|
65
|
+
// WGSL computation code
|
|
47
66
|
const code = `
|
|
48
67
|
output[index] = inputA[index] + inputB[index];
|
|
49
68
|
`;
|
|
50
69
|
|
|
51
|
-
//
|
|
70
|
+
// Execute computation
|
|
52
71
|
const results = await GpuComputed.computed({
|
|
53
72
|
code,
|
|
54
73
|
data,
|
|
55
|
-
workgroupCount: [1] //
|
|
74
|
+
workgroupCount: [1] // Number of workgroups
|
|
56
75
|
});
|
|
57
76
|
|
|
58
77
|
console.log(results); // [[1.5, 3.5, 5.5, 7.5]]
|
|
59
78
|
```
|
|
60
79
|
|
|
61
|
-
### 3.
|
|
80
|
+
### 3. Using Complex Data Structures
|
|
62
81
|
|
|
63
|
-
|
|
82
|
+
The library supports vector and matrix types:
|
|
64
83
|
|
|
65
84
|
```javascript
|
|
66
85
|
const data = {
|
|
@@ -83,60 +102,60 @@ const results = await GpuComputed.computed({
|
|
|
83
102
|
});
|
|
84
103
|
```
|
|
85
104
|
|
|
86
|
-
## API
|
|
105
|
+
## API Reference
|
|
87
106
|
|
|
88
|
-
### GpuComputed
|
|
107
|
+
### GpuComputed Class
|
|
89
108
|
|
|
90
|
-
####
|
|
109
|
+
#### Static Methods
|
|
91
110
|
|
|
92
111
|
##### `GpuComputed.init()`
|
|
93
112
|
|
|
94
|
-
|
|
113
|
+
Initializes the WebGPU environment. Must be called before using other features.
|
|
95
114
|
|
|
96
|
-
|
|
115
|
+
**Returns**: `Promise<void>`
|
|
97
116
|
|
|
98
|
-
|
|
117
|
+
**Throws**: If the browser does not support WebGPU or fails to obtain adapter/device
|
|
99
118
|
|
|
100
119
|
##### `GpuComputed.computed(options)`
|
|
101
120
|
|
|
102
|
-
|
|
121
|
+
Executes a GPU computation task.
|
|
103
122
|
|
|
104
|
-
|
|
123
|
+
**Parameters**:
|
|
105
124
|
|
|
106
|
-
- `code` (string): WGSL
|
|
107
|
-
- `data` (object):
|
|
108
|
-
- `workgroupCount` (array):
|
|
109
|
-
- `workgroupSize` (array,
|
|
110
|
-
- `globalInvocationIdName` (string,
|
|
111
|
-
- `workgroupIndexName` (string,
|
|
112
|
-
- `synchronize` (array,
|
|
113
|
-
- `beforeCodes` (array,
|
|
114
|
-
- `onSuccess` (function,
|
|
125
|
+
- `code` (string): WGSL computation code
|
|
126
|
+
- `data` (object): Input/output data object
|
|
127
|
+
- `workgroupCount` (array): Number of workgroups [x, y?, z?]
|
|
128
|
+
- `workgroupSize` (array, optional): Workgroup size, default [32, 1, 1]
|
|
129
|
+
- `globalInvocationIdName` (string, optional): Global invocation ID variable name, default "grid"
|
|
130
|
+
- `workgroupIndexName` (string, optional): Workgroup index variable name, default "index"
|
|
131
|
+
- `synchronize` (array, optional): Array of buffer names to synchronize back to CPU
|
|
132
|
+
- `beforeCodes` (array, optional): WGSL code snippets before the computation function
|
|
133
|
+
- `onSuccess` (function, optional): Success callback function
|
|
115
134
|
|
|
116
|
-
|
|
135
|
+
**Returns**: `Promise<Array<Float32Array>>` - Data from synchronized buffers
|
|
117
136
|
|
|
118
|
-
###
|
|
137
|
+
### Data Types
|
|
119
138
|
|
|
120
|
-
|
|
139
|
+
Supports the following WGSL types:
|
|
121
140
|
|
|
122
|
-
- `f32`:
|
|
123
|
-
- `vec2`:
|
|
124
|
-
- `vec3`:
|
|
125
|
-
- `vec4`:
|
|
126
|
-
- `mat3x3`: 3x3
|
|
127
|
-
- `mat4x4`: 4x4
|
|
141
|
+
- `f32`: Single-precision float
|
|
142
|
+
- `vec2`: 2D vector
|
|
143
|
+
- `vec3`: 3D vector
|
|
144
|
+
- `vec4`: 4D vector
|
|
145
|
+
- `mat3x3`: 3x3 matrix
|
|
146
|
+
- `mat4x4`: 4x4 matrix
|
|
128
147
|
|
|
129
|
-
###
|
|
148
|
+
### Built-in WGSL Functions
|
|
130
149
|
|
|
131
|
-
|
|
150
|
+
The library provides some commonly used WGSL helper functions:
|
|
132
151
|
|
|
133
|
-
####
|
|
152
|
+
#### Quaternion Rotation
|
|
134
153
|
|
|
135
154
|
```wgsl
|
|
136
155
|
fn quat_rotate(q: vec4<f32>, v: vec3<f32>) -> vec3<f32>
|
|
137
156
|
```
|
|
138
157
|
|
|
139
|
-
|
|
158
|
+
Usage example:
|
|
140
159
|
|
|
141
160
|
```javascript
|
|
142
161
|
import { WGSL_Fun } from 'webgpu-computed';
|
|
@@ -146,42 +165,41 @@ await GpuComputed.computed({
|
|
|
146
165
|
data: {....},
|
|
147
166
|
beforeCodes:[WGSL_Fun.quat_rotate]
|
|
148
167
|
})
|
|
149
|
-
|
|
150
168
|
```
|
|
151
169
|
|
|
152
|
-
####
|
|
170
|
+
#### Point in OBB Detection
|
|
153
171
|
|
|
154
172
|
```wgsl
|
|
155
173
|
fn point_in_obb(point: vec3<f32>, center: vec3<f32>, halfSize: vec3<f32>, quat: vec4<f32>) -> bool
|
|
156
174
|
```
|
|
157
175
|
|
|
158
|
-
##
|
|
176
|
+
## Advanced Usage
|
|
159
177
|
|
|
160
|
-
###
|
|
178
|
+
### Custom Workgroup Configuration
|
|
161
179
|
|
|
162
180
|
```javascript
|
|
163
181
|
await GpuComputed.computed({
|
|
164
182
|
code: '...',
|
|
165
183
|
data: {...},
|
|
166
|
-
workgroupCount: [4, 4], // 16
|
|
167
|
-
workgroupSize: [16, 16], //
|
|
184
|
+
workgroupCount: [4, 4], // 16 workgroups
|
|
185
|
+
workgroupSize: [16, 16], // 256 threads per workgroup
|
|
168
186
|
});
|
|
169
187
|
```
|
|
170
188
|
|
|
171
|
-
###
|
|
189
|
+
### Synchronizing Data Back to CPU
|
|
172
190
|
|
|
173
191
|
```javascript
|
|
174
192
|
const results = await GpuComputed.computed({
|
|
175
193
|
code: '...',
|
|
176
194
|
data: {...},
|
|
177
|
-
synchronize: ['output'], //
|
|
195
|
+
synchronize: ['output'], // Specify buffers to synchronize
|
|
178
196
|
workgroupCount: [1]
|
|
179
197
|
});
|
|
180
198
|
|
|
181
|
-
// results
|
|
199
|
+
// results contains synchronized data
|
|
182
200
|
```
|
|
183
201
|
|
|
184
|
-
###
|
|
202
|
+
### Callback Function
|
|
185
203
|
|
|
186
204
|
```javascript
|
|
187
205
|
await GpuComputed.computed({
|
|
@@ -189,32 +207,32 @@ await GpuComputed.computed({
|
|
|
189
207
|
data: {...},
|
|
190
208
|
workgroupCount: [1],
|
|
191
209
|
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
192
|
-
console.log('
|
|
210
|
+
console.log('Computation completed', results);
|
|
193
211
|
}
|
|
194
212
|
});
|
|
195
213
|
```
|
|
196
214
|
|
|
197
|
-
##
|
|
215
|
+
## Browser Support
|
|
198
216
|
|
|
199
217
|
- Chrome 113+
|
|
200
218
|
- Edge 113+
|
|
201
|
-
- Firefox (
|
|
202
|
-
- Safari (
|
|
219
|
+
- Firefox (partial support)
|
|
220
|
+
- Safari (partial support)
|
|
203
221
|
|
|
204
|
-
|
|
222
|
+
Ensure the browser supports the WebGPU API.
|
|
205
223
|
|
|
206
|
-
##
|
|
224
|
+
## Example Project
|
|
207
225
|
|
|
208
226
|
```js
|
|
209
227
|
import { GpuComputed } from "webgpu-computed"
|
|
210
228
|
|
|
211
|
-
// 1.
|
|
212
|
-
console.log('
|
|
229
|
+
// 1. Initialize WebGPU
|
|
230
|
+
console.log('Initializing WebGPU...');
|
|
213
231
|
await GpuComputed.init();
|
|
214
|
-
console.log('WebGPU
|
|
232
|
+
console.log('WebGPU initialized successfully');
|
|
215
233
|
|
|
216
|
-
// 2.
|
|
217
|
-
console.log('\n===
|
|
234
|
+
// 2. Simple array computation example
|
|
235
|
+
console.log('\n=== Simple Array Computation ===');
|
|
218
236
|
const simpleData = {
|
|
219
237
|
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
220
238
|
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
@@ -232,10 +250,10 @@ await GpuComputed.computed({
|
|
|
232
250
|
synchronize: ['output']
|
|
233
251
|
});
|
|
234
252
|
|
|
235
|
-
console.log('
|
|
253
|
+
console.log('Simple computation result:', simpleResults[0]); // [1.5, 3.5, 5.5, 7.5]
|
|
236
254
|
|
|
237
|
-
// 3.
|
|
238
|
-
console.log('\n===
|
|
255
|
+
// 3. Complex data structure example (struct)
|
|
256
|
+
console.log('\n=== Complex Data Structure Computation ===');
|
|
239
257
|
const complexData = {
|
|
240
258
|
particles: [
|
|
241
259
|
{ position: [1.0, 2.0, 3.0], velocity: [0.1, 0.2, 0.3], mass: 1.0 },
|
|
@@ -260,25 +278,25 @@ await GpuComputed.computed({
|
|
|
260
278
|
synchronize: ['output']
|
|
261
279
|
});
|
|
262
280
|
|
|
263
|
-
console.log('
|
|
281
|
+
console.log('Complex computation result:', complexResults[0]);
|
|
264
282
|
|
|
265
|
-
// 4.
|
|
266
|
-
console.log('\n===
|
|
283
|
+
// 4. Using built-in WGSL functions example
|
|
284
|
+
console.log('\n=== Using Built-in WGSL Functions ===');
|
|
267
285
|
const wgslFunData = {
|
|
268
286
|
points: [
|
|
269
287
|
{
|
|
270
|
-
x: 1.0, y: 0.0,
|
|
288
|
+
x: 1.0, y: 0.0, z: 0.0
|
|
271
289
|
},
|
|
272
290
|
{
|
|
273
|
-
x: 0.0, y: 1.0,
|
|
291
|
+
x: 0.0, y: 1.0, z: 0.0
|
|
274
292
|
},
|
|
275
293
|
{
|
|
276
|
-
x: -1.0, y: 0.0,
|
|
294
|
+
x: -1.0, y: 0.0, z: 0.0
|
|
277
295
|
}
|
|
278
296
|
],
|
|
279
297
|
obbCenter: [0.0, 0.0, 0.0],
|
|
280
298
|
obbHalfSize: [2.0, 2.0, 2.0],
|
|
281
|
-
obbRotation: [0.0, 0.0, 0.0, 1.0], //
|
|
299
|
+
obbRotation: [0.0, 0.0, 0.0, 1.0], // Unit quaternion, no rotation
|
|
282
300
|
results: new Array(3).fill(0)
|
|
283
301
|
};
|
|
284
302
|
|
|
@@ -299,14 +317,14 @@ await GpuComputed.computed({
|
|
|
299
317
|
code: wgslFunCode,
|
|
300
318
|
data: wgslFunData,
|
|
301
319
|
workgroupCount: [1],
|
|
302
|
-
beforeCodes: [WGSL_Fun.quat_rotate, WGSL_Fun.point_in_obb, /**
|
|
320
|
+
beforeCodes: [WGSL_Fun.quat_rotate, WGSL_Fun.point_in_obb, /** Add your own function code */],
|
|
303
321
|
synchronize: ['results']
|
|
304
322
|
});
|
|
305
323
|
|
|
306
|
-
console.log('OBB
|
|
324
|
+
console.log('OBB detection result:', wgslFunResults[0]); // [1, 1, 1] All points are inside the OBB
|
|
307
325
|
|
|
308
|
-
// 5.
|
|
309
|
-
console.log('\n===
|
|
326
|
+
// 5. Custom workgroup configuration example
|
|
327
|
+
console.log('\n=== Custom Workgroup Configuration ===');
|
|
310
328
|
const largeData = {
|
|
311
329
|
largeArray: new Array(1024).fill(0).map((_, i) => i * 1.0),
|
|
312
330
|
output: new Array(1024).fill(0)
|
|
@@ -319,15 +337,15 @@ await GpuComputed.computed({
|
|
|
319
337
|
const largeResults = await GpuComputed.computed({
|
|
320
338
|
code: largeCode,
|
|
321
339
|
data: largeData,
|
|
322
|
-
workgroupCount: [32], // 32
|
|
323
|
-
workgroupSize: [32, 1, 1], //
|
|
340
|
+
workgroupCount: [32], // 32 workgroups
|
|
341
|
+
workgroupSize: [32, 1, 1], // 32 threads per workgroup, total 1024 threads
|
|
324
342
|
synchronize: ['output']
|
|
325
343
|
});
|
|
326
344
|
|
|
327
|
-
console.log('
|
|
345
|
+
console.log('Large array computation result (first 10):', largeResults[0].slice(0, 10));
|
|
328
346
|
|
|
329
|
-
// 6.
|
|
330
|
-
console.log('\n===
|
|
347
|
+
// 6. Using callback function example
|
|
348
|
+
console.log('\n=== Using Callback Function ===');
|
|
331
349
|
const callbackData = {
|
|
332
350
|
values: [10.0, 20.0, 30.0],
|
|
333
351
|
squares: new Array(3).fill(0)
|
|
@@ -343,12 +361,12 @@ await GpuComputed.computed({
|
|
|
343
361
|
workgroupCount: [1],
|
|
344
362
|
synchronize: ['squares'],
|
|
345
363
|
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
346
|
-
console.log('
|
|
364
|
+
console.log('Callback triggered, square computation result:', results[0]); // [100, 400, 900]
|
|
347
365
|
}
|
|
348
366
|
});
|
|
349
367
|
|
|
350
|
-
// 7.
|
|
351
|
-
console.log('\n===
|
|
368
|
+
// 7. Multi-dimensional workgroup example
|
|
369
|
+
console.log('\n=== Multi-dimensional Workgroup ===');
|
|
352
370
|
const matrixData = {
|
|
353
371
|
matrixA: new Array(16).fill(0).map((_, i) => i * 1.0),
|
|
354
372
|
matrixB: new Array(16).fill(0).map((_, i) => (i + 1) * 1.0),
|
|
@@ -365,16 +383,19 @@ await GpuComputed.computed({
|
|
|
365
383
|
const matrixResults = await GpuComputed.computed({
|
|
366
384
|
code: matrixCode,
|
|
367
385
|
data: matrixData,
|
|
368
|
-
workgroupCount: [4, 4], // 4x4
|
|
369
|
-
workgroupSize: [1, 1, 1], //
|
|
386
|
+
workgroupCount: [4, 4], // 4x4 workgroup grid
|
|
387
|
+
workgroupSize: [1, 1, 1], // 1 thread per workgroup
|
|
370
388
|
synchronize: ['result']
|
|
371
389
|
});
|
|
372
390
|
|
|
373
|
-
console.log('
|
|
391
|
+
console.log('Matrix computation result:', matrixResults[0]);
|
|
374
392
|
|
|
375
|
-
console.log('\
|
|
393
|
+
console.log('\nAll feature examples completed!');
|
|
376
394
|
```
|
|
377
395
|
|
|
378
|
-
##
|
|
396
|
+
## License
|
|
397
|
+
|
|
398
|
+
ISC License
|
|
399
|
+
|
|
400
|
+
---
|
|
379
401
|
|
|
380
|
-
ISC License
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webgpu-computed",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "对webgpu的封装,处理了繁琐的前置工作,只关注wgsl本身逻辑",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
8
|
},
|
|
9
9
|
"keywords": [
|
|
10
|
-
"webgpu"
|
|
10
|
+
"webgpu", "computed", "web", "js"
|
|
11
11
|
],
|
|
12
12
|
"author": "夏过初秋",
|
|
13
13
|
"license": "ISC"
|