@@ -7,7 +7,7 @@ This article is about storage buffers and continues where the
7
7
8
8
Storage buffers are similar to uniform buffers in many ways.
9
9
If all we did was change ` UNIFORM ` to ` STORAGE ` in our JavaScript
10
- and ` var<uniform> ` to ` var<storage, read> ` in our WGSL the examples
10
+ and ` var<uniform> ` to ` var<storage, read> ` in our WGSL, the examples
11
11
on the previous page would just work.
12
12
13
13
In fact, here are the differences, without renaming variables to have more
@@ -39,7 +39,7 @@ and in our WSGL
39
39
@group(0) @binding(1) var<storage, read> otherStruct: OtherStruct;
40
40
```
41
41
42
- And with no other changes it works, just like before
42
+ And with no other changes it works, just like before.
43
43
44
44
{{{example url="../webgpu-simple-triangle-storage-split-minimal-changes.html"}}}
45
45
@@ -61,19 +61,19 @@ The major differences between uniform buffers and storage buffers are:
61
61
* The minimum maximum size of a uniform buffer is 64k
62
62
* The minimum maximum size of a storage buffer is 128meg
63
63
64
- By minimum maximum, there is a maximum size a buffer of certain type
65
- can be. For uniform buffers that maximum size is at least 64k.
66
- For storage buffers it's at least 128meg. We'll cover limits in
64
+ By minimum maximum, there is a maximum size a buffer of a certain type
65
+ can be. For uniform buffers, the maximum size is at least 64k.
66
+ For storage buffers, it's at least 128meg. We'll cover limits in
67
67
[ another article] ( webgpu-limits-and-features.html ) .
68
68
69
- 3 . Storage buffers can be read/write, Uniform buffers are read-only
69
+ 3 . Storage buffers can be read/write, Uniform buffers are read-only.
70
70
71
71
We saw an example of writing to a storage buffer in the compute shader
72
72
example in [ the first article] ( webgpu-fundamentals.html ) .
73
73
74
74
## <a id =" a-instancing " ></a >Instancing with Storage Buffers
75
75
76
- Given the first 2 points above, lets take our last example and change it
76
+ Given the first 2 points above, let's take our last example and change it
77
77
to draw all 100 triangles in a single draw call. This is a use-case that
78
78
* might* fit storage buffers. I say might because again, WebGPU is similar
79
79
to other programming languages. There are many ways to achieve the same thing.
@@ -82,9 +82,9 @@ has multiple ways we can achieve it. When it comes to drawing triangles,
82
82
all that WebGPU cares about is we return a value for ` builtin(position) ` from
83
83
the vertex shader and return a color/value for ` location(0) ` from the fragment shader.[ ^ colorAttachments ]
84
84
85
- [ ^ colorAttachments ] : We can have multiple color attachments and then we'll need to return more colors/value for ` location(1) ` , ` location(2) ` , etc..
85
+ [ ^ colorAttachments ] : We can have multiple color attachments and then we'll need to return more colors/values for ` location(1) ` , ` location(2) ` , etc. ..
86
86
87
- The first thing we'll do is change our storage declarations to a runtime sized
87
+ The first thing we'll do is change our storage declarations to runtime- sized
88
88
arrays.
89
89
90
90
``` wgsl
@@ -94,7 +94,7 @@ arrays.
94
94
+@group(0) @binding(1) var<storage, read> otherStructs: array<OtherStruct>;
95
95
```
96
96
97
- Then we'll change the shader to use these values
97
+ Then we'll change the shader to use these values.
98
98
99
99
``` wgsl
100
100
@vertex fn vs(
@@ -118,11 +118,11 @@ Then we'll change the shader to use these values
118
118
We added a new parameter to our vertex shader called
119
119
` instanceIndex ` and gave it the ` @builtin(instance_index) ` attribute
120
120
which means it gets its value from WebGPU for each "instance" drawn.
121
- When we call ` draw ` we can pass a second argument for * number of instances*
121
+ When we call ` draw ` , we can pass a second argument for * number of instances*
122
122
and for each instance drawn, the number of the instance being processed
123
123
will be passed to our function.
124
124
125
- Using ` instanceIndex ` we can get specific struct elements from our arrays
125
+ Using ` instanceIndex ` , we can get specific struct elements from our arrays
126
126
of structs.
127
127
128
128
We also need to get the color from the correct array element and use
@@ -133,7 +133,7 @@ would be more common to look up the color in the vertex shader and just pass
133
133
the color.
134
134
135
135
To do this we'll use another struct like we did in
136
- [ the article on inter-stage variables] ( webgpu-inter-stage-variables.html )
136
+ [ the article on inter-stage variables] ( webgpu-inter-stage-variables.html ) .
137
137
138
138
``` wgsl
139
139
+struct VSOutput {
@@ -174,7 +174,7 @@ To do this we'll use another struct like we did in
174
174
175
175
Now that we've modified our WGSL shaders, let's update the JavaScript.
176
176
177
- Here's the setup
177
+ Here's the setup.
178
178
179
179
``` js
180
180
const kNumObjects = 100 ;
@@ -296,11 +296,11 @@ and `instance_index` set to 0 ~ kNumObjects - 1
296
296
297
297
We managed to draw all 100 triangles, each with a different scale, color, and
298
298
offset, with a single draw call. For situations where you want to draw lots
299
- of instances of the same object this is one way to do it.
299
+ of instances of the same object, this is one way to do it.
300
300
301
301
## Using storage buffers for vertex data
302
302
303
- Until this point we've used a hard coded triangle directly in our shader.
303
+ Until this point, we've used a hard- coded triangle directly in our shader.
304
304
One use case of storage buffers is to store vertex data. Just like we indexed
305
305
the current storage buffers by ` instance_index ` in our example above, we could
306
306
index another storage buffer with ` vertex_index ` to get vertex data.
@@ -356,8 +356,8 @@ struct VSOutput {
356
356
}
357
357
```
358
358
359
- Now we need to setup one more storage buffer with some vertex data.
360
- First lets make a function to generate some vertex data. Lets make a circle.
359
+ Now we need to set up one more storage buffer with some vertex data.
360
+ First, let's make a function to generate some vertex data. Let's make a circle.
361
361
<a id =" a-create-circle " ></a >
362
362
363
363
``` js
@@ -411,11 +411,11 @@ function createCircleVertices({
411
411
}
412
412
```
413
413
414
- The code above makes a circle from triangles like this
414
+ The code above makes a circle from triangles like this.
415
415
416
416
<div class =" webgpu_center " ><div class =" center " ><div data-diagram =" circle " style =" width : 300px ;" ></div ></div ></div >
417
417
418
- So we can use that to fill a storage buffer with the vertices for a circle
418
+ So we can use that to fill a storage buffer with the vertices for a circle.
419
419
420
420
``` js
421
421
// setup a storage buffer with vertex data
@@ -445,7 +445,7 @@ And then we need to add it to our bind group.
445
445
});
446
446
```
447
447
448
- and finally at render time we need to ask to render all the vertices in the circle.
448
+ and finally, at render time, we need to ask to render all the vertices in the circle.
449
449
450
450
``` js
451
451
- pass .draw (3 , kNumObjects); // call our vertex shader 3 times for several instances
@@ -470,11 +470,11 @@ we could have just as easily used no struct and just directly used a `vec2f`.
470
470
@group(0) @binding(2) var<storage, read> pos: vec2f;
471
471
```
472
472
473
- But, by making it a struct it would arguably be easier to add per-vertex
473
+ But, by making it a struct, it would arguably be easier to add per-vertex
474
474
data later?
475
475
476
476
Passing in vertices via storage buffers is gaining popularity.
477
- I'm told though that some older devices it's slower than the * classic* way
477
+ I'm told though that for some older devices, it's slower than the * classic* way
478
478
which we'll cover next in an article on [ vertex buffers] ( webgpu-vertex-buffers.html ) .
479
479
480
480
<!-- keep this at the bottom of the article -->
0 commit comments