@@ -18,6 +18,33 @@ type BoidsOptions = {
18
18
cohesionStrength : number ;
19
19
} ;
20
20
21
+ const Parameters = struct ( {
22
+ separationDistance : f32 ,
23
+ separationStrength : f32 ,
24
+ alignmentDistance : f32 ,
25
+ alignmentStrength : f32 ,
26
+ cohesionDistance : f32 ,
27
+ cohesionStrength : f32 ,
28
+ } ) ;
29
+
30
+ const TriangleData = struct ( {
31
+ position : vec2f ,
32
+ velocity : vec2f ,
33
+ } ) ;
34
+
35
+ const TriangleDataArray = ( n : number ) => arrayOf ( TriangleData , n ) ;
36
+
37
+ const renderBindGroupLayout = tgpu . bindGroupLayout ( {
38
+ trianglePos : { storage : TriangleDataArray } ,
39
+ colorPalette : { uniform : vec3f } ,
40
+ } ) ;
41
+
42
+ const computeBindGroupLayout = tgpu . bindGroupLayout ( {
43
+ currentTrianglePos : { storage : TriangleDataArray } ,
44
+ nextTrianglePos : { storage : TriangleDataArray , access : 'mutable' } ,
45
+ params : { uniform : Parameters } ,
46
+ } ) ;
47
+
21
48
const colorPresets = {
22
49
plumTree : vec3f ( 1.0 , 2.0 , 1.0 ) ,
23
50
jeans : vec3f ( 2.0 , 1.5 , 1.0 ) ,
@@ -69,28 +96,20 @@ export function ComputeBoids() {
69
96
) ;
70
97
71
98
const ref = useWebGPU ( ( { context, device, presentationFormat } ) => {
99
+ const root = tgpu . initFromDevice ( { device } ) ;
100
+
72
101
context . configure ( {
73
102
device,
74
103
format : presentationFormat ,
75
104
alphaMode : "premultiplied" ,
76
105
} ) ;
77
106
78
- const params = struct ( {
79
- separationDistance : f32 ,
80
- separationStrength : f32 ,
81
- alignmentDistance : f32 ,
82
- alignmentStrength : f32 ,
83
- cohesionDistance : f32 ,
84
- cohesionStrength : f32 ,
85
- } ) ;
86
-
87
- const paramsBuffer = tgpu
88
- . createBuffer ( params , presets . default )
89
- . $device ( device )
90
- . $usage ( tgpu . Storage ) ;
107
+ const paramsBuffer = root
108
+ . createBuffer ( Parameters , presets . default )
109
+ . $usage ( "uniform" ) ;
91
110
92
111
const triangleSize = 0.03 ;
93
- const triangleVertexBuffer = tgpu
112
+ const triangleVertexBuffer = root
94
113
. createBuffer ( arrayOf ( f32 , 6 ) , [
95
114
0.0 ,
96
115
triangleSize ,
@@ -99,42 +118,33 @@ export function ComputeBoids() {
99
118
triangleSize / 2 ,
100
119
- triangleSize / 2 ,
101
120
] )
102
- . $device ( device )
103
- . $usage ( tgpu . Vertex ) ;
121
+ . $usage ( "vertex" ) ;
104
122
105
123
const triangleAmount = 1000 ;
106
- const triangleInfoStruct = struct ( {
107
- position : vec2f ,
108
- velocity : vec2f ,
109
- } ) ;
110
124
const trianglePosBuffers = Array . from ( { length : 2 } , ( ) =>
111
- tgpu
112
- . createBuffer ( arrayOf ( triangleInfoStruct , triangleAmount ) )
113
- . $device ( device )
114
- . $usage ( tgpu . Storage , tgpu . Uniform ) ,
125
+ root . createBuffer ( TriangleDataArray ( triangleAmount ) ) . $usage ( "storage" )
115
126
) ;
116
127
117
128
randomizePositions . current = ( ) => {
118
129
const positions = Array . from ( { length : triangleAmount } , ( ) => ( {
119
130
position : vec2f ( Math . random ( ) * 2 - 1 , Math . random ( ) * 2 - 1 ) ,
120
131
velocity : vec2f ( Math . random ( ) * 0.1 - 0.05 , Math . random ( ) * 0.1 - 0.05 ) ,
121
132
} ) ) ;
122
- tgpu . write ( trianglePosBuffers [ 0 ] , positions ) ;
123
- tgpu . write ( trianglePosBuffers [ 1 ] , positions ) ;
133
+ trianglePosBuffers [ 0 ] . write ( positions ) ;
134
+ trianglePosBuffers [ 1 ] . write ( positions ) ;
124
135
} ;
125
136
randomizePositions . current ( ) ;
126
137
127
- const colorPaletteBuffer = tgpu
138
+ const colorPaletteBuffer = root
128
139
. createBuffer ( vec3f , colorPresets . plumTree )
129
- . $device ( device )
130
- . $usage ( tgpu . Uniform ) ;
140
+ . $usage ( "uniform" ) ;
131
141
132
142
updateColorPreset . current = ( newColorPreset : ColorPresets ) => {
133
- tgpu . write ( colorPaletteBuffer , colorPresets [ newColorPreset ] ) ;
143
+ colorPaletteBuffer . write ( colorPresets [ newColorPreset ] ) ;
134
144
} ;
135
145
136
146
updateParams . current = ( newOptions : BoidsOptions ) => {
137
- tgpu . write ( paramsBuffer , newOptions ) ;
147
+ paramsBuffer . write ( newOptions ) ;
138
148
} ;
139
149
140
150
const renderModule = device . createShaderModule ( {
@@ -146,7 +156,9 @@ export function ComputeBoids() {
146
156
} ) ;
147
157
148
158
const pipeline = device . createRenderPipeline ( {
149
- layout : "auto" ,
159
+ layout : device . createPipelineLayout ( {
160
+ bindGroupLayouts : [ root . unwrap ( renderBindGroupLayout ) ] ,
161
+ } ) ,
150
162
vertex : {
151
163
module : renderModule ,
152
164
buffers : [
@@ -176,55 +188,26 @@ export function ComputeBoids() {
176
188
} ) ;
177
189
178
190
const computePipeline = device . createComputePipeline ( {
179
- layout : "auto" ,
191
+ layout : device . createPipelineLayout ( {
192
+ bindGroupLayouts : [ root . unwrap ( computeBindGroupLayout ) ] ,
193
+ } ) ,
180
194
compute : {
181
195
module : computeModule ,
182
196
} ,
183
197
} ) ;
184
198
185
199
const renderBindGroups = [ 0 , 1 ] . map ( ( idx ) =>
186
- device . createBindGroup ( {
187
- layout : pipeline . getBindGroupLayout ( 0 ) ,
188
- entries : [
189
- {
190
- binding : 0 ,
191
- resource : {
192
- buffer : trianglePosBuffers [ idx ] . buffer ,
193
- } ,
194
- } ,
195
- {
196
- binding : 1 ,
197
- resource : {
198
- buffer : colorPaletteBuffer . buffer ,
199
- } ,
200
- } ,
201
- ] ,
200
+ renderBindGroupLayout . populate ( {
201
+ trianglePos : trianglePosBuffers [ idx ] ,
202
+ colorPalette : colorPaletteBuffer ,
202
203
} ) ,
203
204
) ;
204
205
205
206
const computeBindGroups = [ 0 , 1 ] . map ( ( idx ) =>
206
- device . createBindGroup ( {
207
- layout : computePipeline . getBindGroupLayout ( 0 ) ,
208
- entries : [
209
- {
210
- binding : 0 ,
211
- resource : {
212
- buffer : trianglePosBuffers [ idx ] . buffer ,
213
- } ,
214
- } ,
215
- {
216
- binding : 1 ,
217
- resource : {
218
- buffer : trianglePosBuffers [ 1 - idx ] . buffer ,
219
- } ,
220
- } ,
221
- {
222
- binding : 2 ,
223
- resource : {
224
- buffer : paramsBuffer . buffer ,
225
- } ,
226
- } ,
227
- ] ,
207
+ computeBindGroupLayout . populate ( {
208
+ currentTrianglePos : trianglePosBuffers [ idx ] ,
209
+ nextTrianglePos : trianglePosBuffers [ 1 - idx ] ,
210
+ params : paramsBuffer ,
228
211
} ) ,
229
212
) ;
230
213
@@ -251,7 +234,7 @@ export function ComputeBoids() {
251
234
computePass . setPipeline ( computePipeline ) ;
252
235
computePass . setBindGroup (
253
236
0 ,
254
- even ? computeBindGroups [ 0 ] : computeBindGroups [ 1 ] ,
237
+ root . unwrap ( even ? computeBindGroups [ 0 ] : computeBindGroups [ 1 ] )
255
238
) ;
256
239
computePass . dispatchWorkgroups ( triangleAmount ) ;
257
240
computePass . end ( ) ;
@@ -261,7 +244,7 @@ export function ComputeBoids() {
261
244
passEncoder . setVertexBuffer ( 0 , triangleVertexBuffer . buffer ) ;
262
245
passEncoder . setBindGroup (
263
246
0 ,
264
- even ? renderBindGroups [ 1 ] : renderBindGroups [ 0 ] ,
247
+ root . unwrap ( even ? renderBindGroups [ 1 ] : renderBindGroups [ 0 ] )
265
248
) ;
266
249
passEncoder . draw ( 3 , triangleAmount ) ;
267
250
passEncoder . end ( ) ;
0 commit comments