webgpu-computed 0.0.7 → 0.0.9
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/README.en.md +496 -0
- package/README.md +359 -250
- package/package.json +6 -4
- package/src/App.vue.d.ts +2 -0
- package/src/build.d.ts +3 -0
- package/src/index.js +321 -187
- package/src/main.d.ts +0 -0
- package/src/pages/GpuComputedExample.d.ts +1 -0
- package/src/pages/Index.vue.d.ts +2 -0
- package/src/router/index.d.ts +2 -0
- package/src/utils/GpuComputed.d.ts +108 -0
- package/src/utils/WGSL_Fun.d.ts +2 -0
- package/src/utils/include.d.ts +1 -0
- package/README.zh-CN.md +0 -385
- package/src/index.d.ts +0 -77
package/README.md
CHANGED
|
@@ -1,72 +1,76 @@
|
|
|
1
|
-
🌐 Read this in other languages:
|
|
2
|
-
- [简体中文](/webgpu-computed/README.md)
|
|
3
|
-
|
|
4
1
|
# webgpu-computed
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
🌐 其他语言版本:
|
|
4
|
+
- [English](./README.en.md)
|
|
5
|
+
|
|
6
|
+
一个简化的 WebGPU 计算库,封装了繁琐的初始化和缓冲区管理,让开发者专注于 WGSL 着色器逻辑。
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 特性
|
|
9
9
|
|
|
10
|
-
- 🚀
|
|
11
|
-
- 📦
|
|
12
|
-
- 🔧
|
|
13
|
-
- ⚡
|
|
14
|
-
- 📚
|
|
15
|
-
- ✅
|
|
10
|
+
- 🚀 简化的 WebGPU 初始化
|
|
11
|
+
- 📦 自动缓冲区管理和布局计算
|
|
12
|
+
- 🔧 支持复杂数据结构(向量、矩阵)
|
|
13
|
+
- ⚡ 高性能 GPU 计算
|
|
14
|
+
- 📚 内置常用 WGSL 函数
|
|
15
|
+
- ✅ 支持 Node.js 环境
|
|
16
|
+
- 🛠️ TypeScript 支持
|
|
17
|
+
- 📖 详细的中文文档和示例
|
|
16
18
|
|
|
17
|
-
##
|
|
19
|
+
## 安装
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
22
|
npm install webgpu-computed
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
##
|
|
25
|
+
## 快速开始
|
|
24
26
|
|
|
25
|
-
### 1.
|
|
27
|
+
### 1. 初始化 WebGPU
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
在使用任何计算功能之前,需要初始化 WebGPU 环境:
|
|
28
30
|
|
|
29
31
|
```javascript
|
|
30
32
|
import { GpuComputed } from 'webgpu-computed';
|
|
31
33
|
|
|
32
|
-
//
|
|
34
|
+
// 初始化 WebGPU
|
|
33
35
|
await GpuComputed.init();
|
|
34
|
-
|
|
35
|
-
//
|
|
36
|
+
|
|
37
|
+
// 在 Node.js 环境中使用后,请调用:
|
|
38
|
+
// GpuComputed.destroy()
|
|
36
39
|
```
|
|
37
40
|
|
|
38
|
-
### 2.
|
|
41
|
+
### 2. 执行简单计算
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
以下是一个简单的向量加法示例:
|
|
41
44
|
|
|
42
45
|
```javascript
|
|
43
46
|
import { GpuComputed } from 'webgpu-computed';
|
|
44
47
|
|
|
45
|
-
//
|
|
48
|
+
// 准备数据
|
|
46
49
|
const data = {
|
|
47
50
|
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
48
51
|
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
49
|
-
output: new Array(4).fill(0) //
|
|
52
|
+
output: new Array(4).fill(0) // 输出缓冲区
|
|
50
53
|
};
|
|
51
54
|
|
|
52
|
-
// WGSL
|
|
55
|
+
// WGSL 计算代码
|
|
53
56
|
const code = `
|
|
54
57
|
output[index] = inputA[index] + inputB[index];
|
|
55
58
|
`;
|
|
56
59
|
|
|
57
|
-
//
|
|
58
|
-
|
|
60
|
+
// 执行计算
|
|
61
|
+
GpuComputed.computed({
|
|
59
62
|
code,
|
|
60
63
|
data,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
console.log(results); // [[1.5, 3.5, 5.5, 7.5]]
|
|
64
|
+
synchronize: ["output"], // 需要返回的数据字段
|
|
65
|
+
workgroupCount: [1] // 工作组数量
|
|
66
|
+
}).then(results => {
|
|
67
|
+
console.log(results); // [[1.5, 3.5, 5.5, 7.5]]
|
|
68
|
+
})
|
|
65
69
|
```
|
|
66
70
|
|
|
67
|
-
### 3.
|
|
71
|
+
### 3. 使用复杂数据结构
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
该库支持向量和矩阵类型:
|
|
70
74
|
|
|
71
75
|
```javascript
|
|
72
76
|
const data = {
|
|
@@ -82,67 +86,169 @@ const code = `
|
|
|
82
86
|
output[index].vel = positions[index].vel * 2.0;
|
|
83
87
|
`;
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
// 执行计算
|
|
90
|
+
GpuComputed.computed({
|
|
86
91
|
code,
|
|
87
92
|
data,
|
|
88
|
-
|
|
93
|
+
synchronize: ["output"], // 需要返回的数据字段
|
|
94
|
+
workgroupCount: [1] // 工作组数量
|
|
95
|
+
}).then(results => {
|
|
96
|
+
console.log(results); // [[1.100000023841858,2.200000047683716,3.299999952316284,0,0.20000000298023224,0.4000000059604645,0.6000000238418579,0,4.400000095367432,5.5,6.599999904632568,0,0.800000011920929,1,1.2000000476837158,0]]
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 4. 手动创建 GpuComputed 实例
|
|
101
|
+
|
|
102
|
+
如果您需要更精细的控制,可以直接创建 GpuComputed 实例:
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
import { GpuComputed } from 'webgpu-computed';
|
|
106
|
+
|
|
107
|
+
// 1. 定义数据模板
|
|
108
|
+
const template = {
|
|
109
|
+
inputA: [] as number[],
|
|
110
|
+
inputB: [] as number[],
|
|
111
|
+
output: [] as number[]
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// 2. 创建实例
|
|
115
|
+
const gpuComputed = new GpuComputed(template, {
|
|
116
|
+
code: `
|
|
117
|
+
output[index] = inputA[index] + inputB[index];
|
|
118
|
+
`,
|
|
119
|
+
workgroupSize: [32, 1, 1] // 可选:自定义工作组大小
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// 3. 初始化管线
|
|
123
|
+
await gpuComputed.initPipeline();
|
|
124
|
+
|
|
125
|
+
// 4. 准备数据
|
|
126
|
+
const data = {
|
|
127
|
+
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
128
|
+
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
129
|
+
output: new Array(4).fill(0)
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// 5. 创建绑定组
|
|
133
|
+
const bindGroup = gpuComputed.createBindGroup(data);
|
|
134
|
+
|
|
135
|
+
// 6. 执行计算
|
|
136
|
+
const results = await gpuComputed.computed(bindGroup, [1], ['output']);
|
|
137
|
+
|
|
138
|
+
console.log(results[0]); // [1.5, 3.5, 5.5, 7.5]
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### 使用结构体数据
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
// 定义结构体模板
|
|
145
|
+
const structTemplate = {
|
|
146
|
+
particles: {
|
|
147
|
+
layout: [
|
|
148
|
+
{ name: 'position', type: 'vec3' },
|
|
149
|
+
{ name: 'velocity', type: 'vec3' },
|
|
150
|
+
{ name: 'mass', type: 'f32' }
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
output: {
|
|
154
|
+
layout: [
|
|
155
|
+
{ name: 'position', type: 'vec3' },
|
|
156
|
+
{ name: 'velocity', type: 'vec3' },
|
|
157
|
+
{ name: 'mass', type: 'f32' }
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const gpuComputed = new GpuComputed(structTemplate, {
|
|
163
|
+
code: `
|
|
164
|
+
output[index].position = particles[index].position + particles[index].velocity;
|
|
165
|
+
output[index].velocity = particles[index].velocity * 2.0;
|
|
166
|
+
output[index].mass = particles[index].mass * 1.5;
|
|
167
|
+
`
|
|
89
168
|
});
|
|
169
|
+
|
|
170
|
+
await gpuComputed.initPipeline();
|
|
171
|
+
|
|
172
|
+
const data = {
|
|
173
|
+
particles: [
|
|
174
|
+
{ position: [1, 2, 3], velocity: [0.1, 0.2, 0.3], mass: 1.0 },
|
|
175
|
+
{ position: [4, 5, 6], velocity: [0.4, 0.5, 0.6], mass: 2.0 }
|
|
176
|
+
],
|
|
177
|
+
output: [
|
|
178
|
+
{ position: [0, 0, 0], velocity: [0, 0, 0], mass: 0 },
|
|
179
|
+
{ position: [0, 0, 0], velocity: [0, 0, 0], mass: 0 }
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const bindGroup = gpuComputed.createBindGroup(data);
|
|
184
|
+
const results = await gpuComputed.computed(bindGroup, [1], ['output']);
|
|
185
|
+
|
|
186
|
+
console.log(results[0]); // 映射后的数据
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### 数据映射
|
|
190
|
+
|
|
191
|
+
当使用结构体时,可以使用 `dataMap` 方法将结果映射回原始结构:
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
const mappedData = gpuComputed.dataMap(results[0], 'output');
|
|
195
|
+
console.log(mappedData); // 返回结构化的对象数组
|
|
90
196
|
```
|
|
91
197
|
|
|
92
|
-
## API
|
|
198
|
+
## API 参考
|
|
93
199
|
|
|
94
|
-
### GpuComputed
|
|
200
|
+
### GpuComputed 类
|
|
95
201
|
|
|
96
|
-
####
|
|
202
|
+
#### 静态方法
|
|
97
203
|
|
|
98
204
|
##### `GpuComputed.init()`
|
|
99
205
|
|
|
100
|
-
|
|
206
|
+
初始化 WebGPU 环境。必须在使用其他功能之前调用。
|
|
101
207
|
|
|
102
|
-
|
|
208
|
+
**返回值**: `Promise<void>`
|
|
103
209
|
|
|
104
|
-
|
|
210
|
+
**抛出异常**: 如果浏览器不支持 WebGPU 或获取适配器/设备失败
|
|
105
211
|
|
|
106
212
|
##### `GpuComputed.computed(options)`
|
|
107
213
|
|
|
108
|
-
|
|
214
|
+
执行 GPU 计算任务。
|
|
109
215
|
|
|
110
|
-
|
|
216
|
+
**参数**:
|
|
111
217
|
|
|
112
|
-
- `code` (string): WGSL
|
|
113
|
-
- `data` (object):
|
|
114
|
-
- `workgroupCount` (array):
|
|
115
|
-
- `workgroupSize` (array,
|
|
116
|
-
- `globalInvocationIdName` (string,
|
|
117
|
-
- `workgroupIndexName` (string,
|
|
118
|
-
- `synchronize` (array,
|
|
119
|
-
- `beforeCodes` (array,
|
|
120
|
-
- `onSuccess` (function,
|
|
218
|
+
- `code` (string): WGSL 计算代码
|
|
219
|
+
- `data` (object): 输入/输出数据对象
|
|
220
|
+
- `workgroupCount` (array): 工作组数量 [x, y?, z?]
|
|
221
|
+
- `workgroupSize` (array, 可选): 工作组大小,默认 [32, 1, 1]
|
|
222
|
+
- `globalInvocationIdName` (string, 可选): 全局调用 ID 变量名,默认 "grid"
|
|
223
|
+
- `workgroupIndexName` (string, 可选): 工作组索引变量名,默认 "index"
|
|
224
|
+
- `synchronize` (array, 可选): 需要同步回 CPU 的缓冲区名称数组
|
|
225
|
+
- `beforeCodes` (array, 可选): 计算函数之前的 WGSL 代码片段
|
|
226
|
+
- `onSuccess` (function, 可选): 成功回调函数
|
|
121
227
|
|
|
122
|
-
|
|
228
|
+
**返回值**: `Promise<Array<Float32Array>>` - 同步缓冲区的数据
|
|
123
229
|
|
|
124
|
-
###
|
|
230
|
+
### 数据类型
|
|
125
231
|
|
|
126
|
-
|
|
232
|
+
支持以下 WGSL 类型:
|
|
127
233
|
|
|
128
|
-
- `f32`:
|
|
129
|
-
- `vec2`: 2D
|
|
130
|
-
- `vec3`: 3D
|
|
131
|
-
- `vec4`: 4D
|
|
132
|
-
- `mat3x3`: 3x3
|
|
133
|
-
- `mat4x4`: 4x4
|
|
234
|
+
- `f32`: 单精度浮点数
|
|
235
|
+
- `vec2`: 2D 向量
|
|
236
|
+
- `vec3`: 3D 向量
|
|
237
|
+
- `vec4`: 4D 向量
|
|
238
|
+
- `mat3x3`: 3x3 矩阵
|
|
239
|
+
- `mat4x4`: 4x4 矩阵
|
|
134
240
|
|
|
135
|
-
###
|
|
241
|
+
### 内置 WGSL 函数
|
|
136
242
|
|
|
137
|
-
|
|
243
|
+
该库提供了一些常用的 WGSL 辅助函数:
|
|
138
244
|
|
|
139
|
-
####
|
|
245
|
+
#### 四元数旋转
|
|
140
246
|
|
|
141
247
|
```wgsl
|
|
142
248
|
fn quat_rotate(q: vec4<f32>, v: vec3<f32>) -> vec3<f32>
|
|
143
249
|
```
|
|
144
250
|
|
|
145
|
-
|
|
251
|
+
使用示例:
|
|
146
252
|
|
|
147
253
|
```javascript
|
|
148
254
|
import { WGSL_Fun } from 'webgpu-computed';
|
|
@@ -154,39 +260,39 @@ await GpuComputed.computed({
|
|
|
154
260
|
})
|
|
155
261
|
```
|
|
156
262
|
|
|
157
|
-
####
|
|
263
|
+
#### 点在 OBB 中的检测
|
|
158
264
|
|
|
159
265
|
```wgsl
|
|
160
266
|
fn point_in_obb(point: vec3<f32>, center: vec3<f32>, halfSize: vec3<f32>, quat: vec4<f32>) -> bool
|
|
161
267
|
```
|
|
162
268
|
|
|
163
|
-
##
|
|
269
|
+
## 高级用法
|
|
164
270
|
|
|
165
|
-
###
|
|
271
|
+
### 自定义工作组配置
|
|
166
272
|
|
|
167
273
|
```javascript
|
|
168
274
|
await GpuComputed.computed({
|
|
169
275
|
code: '...',
|
|
170
276
|
data: {...},
|
|
171
|
-
workgroupCount: [4, 4], // 16
|
|
172
|
-
workgroupSize: [16, 16], // 256
|
|
277
|
+
workgroupCount: [4, 4], // 16 个工作组
|
|
278
|
+
workgroupSize: [16, 16], // 每个工作组 256 个线程
|
|
173
279
|
});
|
|
174
280
|
```
|
|
175
281
|
|
|
176
|
-
###
|
|
282
|
+
### 将数据同步回 CPU
|
|
177
283
|
|
|
178
284
|
```javascript
|
|
179
285
|
const results = await GpuComputed.computed({
|
|
180
286
|
code: '...',
|
|
181
287
|
data: {...},
|
|
182
|
-
synchronize: ['output'], //
|
|
288
|
+
synchronize: ['output'], // 指定要同步的缓冲区
|
|
183
289
|
workgroupCount: [1]
|
|
184
290
|
});
|
|
185
291
|
|
|
186
|
-
// results
|
|
292
|
+
// results 包含同步的数据
|
|
187
293
|
```
|
|
188
294
|
|
|
189
|
-
###
|
|
295
|
+
### 回调函数
|
|
190
296
|
|
|
191
297
|
```javascript
|
|
192
298
|
await GpuComputed.computed({
|
|
@@ -194,195 +300,198 @@ await GpuComputed.computed({
|
|
|
194
300
|
data: {...},
|
|
195
301
|
workgroupCount: [1],
|
|
196
302
|
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
197
|
-
console.log('
|
|
303
|
+
console.log('计算完成', results);
|
|
198
304
|
}
|
|
199
305
|
});
|
|
200
306
|
```
|
|
201
307
|
|
|
202
|
-
##
|
|
308
|
+
## 示例项目
|
|
203
309
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
- Safari (partial support)
|
|
310
|
+
```js
|
|
311
|
+
import { GpuComputed } from "webgpu-computed"
|
|
312
|
+
import * as WGSL_Fun from "webgpu-computed"
|
|
208
313
|
|
|
209
|
-
|
|
314
|
+
// 1. 初始化 WebGPU
|
|
315
|
+
console.log('初始化 WebGPU...');
|
|
316
|
+
await GpuComputed.init();
|
|
317
|
+
console.log('WebGPU 初始化成功');
|
|
318
|
+
|
|
319
|
+
// 2. 简单数组计算示例
|
|
320
|
+
console.log('\n=== 简单数组计算 ===');
|
|
321
|
+
const simpleData = {
|
|
322
|
+
inputA: [1.0, 2.0, 3.0, 4.0],
|
|
323
|
+
inputB: [0.5, 1.5, 2.5, 3.5],
|
|
324
|
+
output: new Array(4).fill(0)
|
|
325
|
+
};
|
|
210
326
|
|
|
211
|
-
|
|
327
|
+
const simpleCode = `
|
|
328
|
+
output[index] = inputA[index] + inputB[index];
|
|
329
|
+
`;
|
|
212
330
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
code: complexCode,
|
|
263
|
-
data: complexData,
|
|
264
|
-
workgroupCount: [1],
|
|
265
|
-
synchronize: ['output']
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
console.log('Complex computation result:', complexResults[0]);
|
|
269
|
-
|
|
270
|
-
// 4. Using built-in WGSL functions example
|
|
271
|
-
console.log('\n=== Using Built-in WGSL Functions ===');
|
|
272
|
-
const wgslFunData = {
|
|
273
|
-
points: [
|
|
274
|
-
{
|
|
275
|
-
x: 1.0, y: 0.0, z: 0.0
|
|
276
|
-
},
|
|
277
|
-
{
|
|
278
|
-
x: 0.0, y: 1.0, z: 0.0
|
|
279
|
-
},
|
|
280
|
-
{
|
|
281
|
-
x: -1.0, y: 0.0, z: 0.0
|
|
282
|
-
}
|
|
283
|
-
],
|
|
284
|
-
obbCenter: [0.0, 0.0, 0.0],
|
|
285
|
-
obbHalfSize: [2.0, 2.0, 2.0],
|
|
286
|
-
obbRotation: [0.0, 0.0, 0.0, 1.0], // Unit quaternion, no rotation
|
|
287
|
-
results: new Array(3).fill(0)
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const wgslFunCode = `
|
|
291
|
-
let point = vec3(points[index].x, points[index].y, points[index].z);
|
|
292
|
-
let center = vec3<f32>(obbCenter[0], obbCenter[1], obbCenter[2]);
|
|
293
|
-
let halfSize = vec3<f32>(obbHalfSize[0], obbHalfSize[1], obbHalfSize[2]);
|
|
294
|
-
let quat = vec4<f32>(obbRotation[0], obbRotation[1], obbRotation[2], obbRotation[3]);
|
|
295
|
-
|
|
296
|
-
if (point_in_obb(point, center, halfSize, quat)) {
|
|
297
|
-
results[index] = 1.0;
|
|
298
|
-
} else {
|
|
299
|
-
results[index] = 0.0;
|
|
300
|
-
}
|
|
301
|
-
`;
|
|
302
|
-
|
|
303
|
-
const wgslFunResults = await GpuComputed.computed({
|
|
304
|
-
code: wgslFunCode,
|
|
305
|
-
data: wgslFunData,
|
|
306
|
-
workgroupCount: [1],
|
|
307
|
-
beforeCodes: [WGSL_Fun.quat_rotate, WGSL_Fun.point_in_obb, /** Add your own function code */],
|
|
308
|
-
synchronize: ['results']
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
console.log('OBB detection result:', wgslFunResults[0]); // [1, 1, 1] All points are inside the OBB
|
|
312
|
-
|
|
313
|
-
// 5. Custom workgroup configuration example
|
|
314
|
-
console.log('\n=== Custom Workgroup Configuration ===');
|
|
315
|
-
const largeData = {
|
|
316
|
-
largeArray: new Array(1024).fill(0).map((_, i) => i * 1.0),
|
|
317
|
-
output: new Array(1024).fill(0)
|
|
318
|
-
};
|
|
319
|
-
|
|
320
|
-
const largeCode = `
|
|
321
|
-
output[index] = largeArray[index] * 2.0;
|
|
322
|
-
`;
|
|
323
|
-
|
|
324
|
-
const largeResults = await GpuComputed.computed({
|
|
325
|
-
code: largeCode,
|
|
326
|
-
data: largeData,
|
|
327
|
-
workgroupCount: [32], // 32 workgroups
|
|
328
|
-
workgroupSize: [32, 1, 1], // 32 threads per workgroup, total 1024 threads
|
|
329
|
-
synchronize: ['output']
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
console.log('Large array computation result (first 10):', largeResults[0].slice(0, 10));
|
|
333
|
-
|
|
334
|
-
// 6. Using callback function example
|
|
335
|
-
console.log('\n=== Using Callback Function ===');
|
|
336
|
-
const callbackData = {
|
|
337
|
-
values: [10.0, 20.0, 30.0],
|
|
338
|
-
squares: new Array(3).fill(0)
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
const callbackCode = `
|
|
342
|
-
squares[index] = values[index] * values[index];
|
|
343
|
-
`;
|
|
344
|
-
|
|
345
|
-
await GpuComputed.computed({
|
|
346
|
-
code: callbackCode,
|
|
347
|
-
data: callbackData,
|
|
348
|
-
workgroupCount: [1],
|
|
349
|
-
synchronize: ['squares'],
|
|
350
|
-
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
351
|
-
console.log('Callback triggered, square computation result:', results[0]); // [100, 400, 900]
|
|
331
|
+
const simpleResults = await GpuComputed.computed({
|
|
332
|
+
code: simpleCode,
|
|
333
|
+
data: simpleData,
|
|
334
|
+
workgroupCount: [1],
|
|
335
|
+
synchronize: ['output']
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
console.log('简单计算结果:', simpleResults[0]); // [1.5, 3.5, 5.5, 7.5]
|
|
339
|
+
|
|
340
|
+
// 3. 复杂数据结构示例(结构体)
|
|
341
|
+
console.log('\n=== 复杂数据结构计算 ===');
|
|
342
|
+
const complexData = {
|
|
343
|
+
particles: [
|
|
344
|
+
{ position: [1.0, 2.0, 3.0], velocity: [0.1, 0.2, 0.3], mass: 1.0 },
|
|
345
|
+
{ position: [4.0, 5.0, 6.0], velocity: [0.4, 0.5, 0.6], mass: 2.0 }
|
|
346
|
+
],
|
|
347
|
+
output: [
|
|
348
|
+
{ position: [0, 0, 0], velocity: [0, 0, 0], mass: 0 },
|
|
349
|
+
{ position: [0, 0, 0], velocity: [0, 0, 0], mass: 0 }
|
|
350
|
+
]
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const complexCode = `
|
|
354
|
+
output[index].position = particles[index].position + particles[index].velocity;
|
|
355
|
+
output[index].velocity = particles[index].velocity * 2.0;
|
|
356
|
+
output[index].mass = particles[index].mass * 1.5;
|
|
357
|
+
`;
|
|
358
|
+
|
|
359
|
+
const complexResults = await GpuComputed.computed({
|
|
360
|
+
code: complexCode,
|
|
361
|
+
data: complexData,
|
|
362
|
+
workgroupCount: [1],
|
|
363
|
+
synchronize: ['output']
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
console.log('复杂计算结果:', complexResults[0]);
|
|
367
|
+
|
|
368
|
+
// 4. 使用内置 WGSL 函数示例
|
|
369
|
+
console.log('\n=== 使用内置 WGSL 函数 ===');
|
|
370
|
+
const wgslFunData = {
|
|
371
|
+
points: [
|
|
372
|
+
{
|
|
373
|
+
x: 1.0, y: 0.0, z: 0.0
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
x: 0.0, y: 1.0, z: 0.0
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
x: -1.0, y: 0.0, z: 0.0
|
|
352
380
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
+
],
|
|
382
|
+
obbCenter: [0.0, 0.0, 0.0],
|
|
383
|
+
obbHalfSize: [2.0, 2.0, 2.0],
|
|
384
|
+
obbRotation: [0.0, 0.0, 0.0, 1.0], // 单位四元数,无旋转
|
|
385
|
+
results: new Array(3).fill(0)
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
const wgslFunCode = `
|
|
389
|
+
let point = vec3(points[index].x, points[index].y, points[index].z);
|
|
390
|
+
let center = vec3<f32>(obbCenter[0], obbCenter[1], obbCenter[2]);
|
|
391
|
+
let halfSize = vec3<f32>(obbHalfSize[0], obbHalfSize[1], obbHalfSize[2]);
|
|
392
|
+
let quat = vec4<f32>(obbRotation[0], obbRotation[1], obbRotation[2], obbRotation[3]);
|
|
393
|
+
|
|
394
|
+
if (point_in_obb(point, center, halfSize, quat)) {
|
|
395
|
+
results[index] = 1.0;
|
|
396
|
+
} else {
|
|
397
|
+
results[index] = 0.0;
|
|
398
|
+
}
|
|
399
|
+
`;
|
|
400
|
+
|
|
401
|
+
const wgslFunResults = await GpuComputed.computed({
|
|
402
|
+
code: wgslFunCode,
|
|
403
|
+
data: wgslFunData,
|
|
404
|
+
workgroupCount: [1],
|
|
405
|
+
beforeCodes: [WGSL_Fun.quat_rotate, WGSL_Fun.point_in_obb, /** 可添加自己的函数代码 */],
|
|
406
|
+
synchronize: ['results']
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
console.log('OBB 检测结果:', wgslFunResults[0]); // [1, 1, 1] 所有点都在 OBB 内
|
|
410
|
+
|
|
411
|
+
// 5. 自定义工作组配置示例
|
|
412
|
+
console.log('\n=== 自定义工作组配置 ===');
|
|
413
|
+
const largeData = {
|
|
414
|
+
largeArray: new Array(1024).fill(0).map((_, i) => i * 1.0),
|
|
415
|
+
output: new Array(1024).fill(0)
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const largeCode = `
|
|
419
|
+
output[index] = largeArray[index] * 2.0;
|
|
420
|
+
`;
|
|
421
|
+
|
|
422
|
+
const largeResults = await GpuComputed.computed({
|
|
423
|
+
code: largeCode,
|
|
424
|
+
data: largeData,
|
|
425
|
+
workgroupCount: [32], // 32 个工作组
|
|
426
|
+
workgroupSize: [32, 1, 1], // 每个工作组 32 个线程,总共 1024 个线程
|
|
427
|
+
synchronize: ['output']
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
console.log('大数组计算结果 (前 10 个):', largeResults[0].slice(0, 10));
|
|
431
|
+
|
|
432
|
+
// 6. 使用回调函数示例
|
|
433
|
+
console.log('\n=== 使用回调函数 ===');
|
|
434
|
+
const callbackData = {
|
|
435
|
+
values: [10.0, 20.0, 30.0],
|
|
436
|
+
squares: new Array(3).fill(0)
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
const callbackCode = `
|
|
440
|
+
squares[index] = values[index] * values[index];
|
|
441
|
+
`;
|
|
442
|
+
|
|
443
|
+
await GpuComputed.computed({
|
|
444
|
+
code: callbackCode,
|
|
445
|
+
data: callbackData,
|
|
446
|
+
workgroupCount: [1],
|
|
447
|
+
synchronize: ['squares'],
|
|
448
|
+
onSuccess: ({ code, bufferInfoList, results }) => {
|
|
449
|
+
console.log('回调触发,平方计算结果:', results[0]); // [100, 400, 900]
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
// 7. 多维工作组示例
|
|
454
|
+
console.log('\n=== 多维工作组 ===');
|
|
455
|
+
const matrixData = {
|
|
456
|
+
matrixA: new Array(16).fill(0).map((_, i) => i * 1.0),
|
|
457
|
+
matrixB: new Array(16).fill(0).map((_, i) => (i + 1) * 1.0),
|
|
458
|
+
result: new Array(16).fill(0)
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
const matrixCode = `
|
|
462
|
+
let x = index % 4u;
|
|
463
|
+
let y = index / 4u;
|
|
464
|
+
let idx = y * 4u + x;
|
|
465
|
+
result[idx] = matrixA[idx] + matrixB[idx];
|
|
466
|
+
`;
|
|
467
|
+
|
|
468
|
+
const matrixResults = await GpuComputed.computed({
|
|
469
|
+
code: matrixCode,
|
|
470
|
+
data: matrixData,
|
|
471
|
+
workgroupCount: [4, 4], // 4x4 工作组网格
|
|
472
|
+
workgroupSize: [1, 1, 1], // 每个工作组 1 个线程
|
|
473
|
+
synchronize: ['result']
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
console.log('矩阵计算结果:', matrixResults[0]);
|
|
477
|
+
|
|
478
|
+
console.log('\n所有功能示例完成!');
|
|
381
479
|
```
|
|
382
480
|
|
|
383
|
-
##
|
|
481
|
+
## 浏览器支持
|
|
384
482
|
|
|
385
|
-
|
|
483
|
+
- Chrome 113+
|
|
484
|
+
- Edge 113+
|
|
485
|
+
- Firefox (部分支持)
|
|
486
|
+
- Safari (部分支持)
|
|
487
|
+
|
|
488
|
+
确保浏览器支持 WebGPU API。
|
|
489
|
+
|
|
490
|
+
## 贡献
|
|
386
491
|
|
|
387
|
-
|
|
492
|
+
欢迎提交 Issue 和 Pull Request!
|
|
493
|
+
|
|
494
|
+
## 许可证
|
|
495
|
+
|
|
496
|
+
ISC License
|
|
388
497
|
|