diff --git a/toc.hanson b/toc.hanson
index b7001c150..de0172b59 100644
--- a/toc.hanson
+++ b/toc.hanson
@@ -12,6 +12,7 @@
'webgpu-textures-external-video.md',
'webgpu-cube-maps.md',
'webgpu-storage-textures.md',
+ 'webgpu-multisampling.md',
],
},
'webgpu-constants.md',
@@ -20,7 +21,6 @@
'webgpu-copying-data.md',
'webgpu-limits-and-features.md',
'webgpu-timing.md',
- 'webgpu-multisampling.md',
'webgpu-wgsl.md',
'webgpu-how-it-works.md',
],
diff --git a/webgpu/lessons/resources/antialias-4x.svg b/webgpu/lessons/resources/antialias-4x.svg
new file mode 100644
index 000000000..aced11a89
--- /dev/null
+++ b/webgpu/lessons/resources/antialias-4x.svg
@@ -0,0 +1,113 @@
+
+
+
diff --git a/webgpu/lessons/resources/antialias-multisample-4.svg b/webgpu/lessons/resources/antialias-multisample-4.svg
new file mode 100644
index 000000000..0eb1366e2
--- /dev/null
+++ b/webgpu/lessons/resources/antialias-multisample-4.svg
@@ -0,0 +1,90 @@
+
+
+
diff --git a/webgpu/lessons/webgpu-multisampling.md b/webgpu/lessons/webgpu-multisampling.md
index 4a510f111..9e40bc294 100644
--- a/webgpu/lessons/webgpu-multisampling.md
+++ b/webgpu/lessons/webgpu-multisampling.md
@@ -55,18 +55,36 @@ so there is no need for anti-aliasing. All 4 pixels are red.
Drawing 4 red pixels instead of 1 pixel is a waste of time.
The GPU called our fragment shader 4 times. Fragment shaders can be fairly large and do a lots
-of work so we'd like to call them as few times as possible.
+of work so we'd like to call them as few times as possible. Even when the triangle crosses 3 pixels
+we get this
-This is where multisampling comes in. We create a special "multisampled texture".
-When we draw a triangle to a multisampled texture, if
-all 4 pixels are inside the triangle then the GPU just calls our fragment shader once and stores the result
-in all 4 pixels. If only some of those 4 pixels are inside the triangle the GPU still only calls
-our fragment shader once but it only writes the result to the pixels that are inside the triangle.
-This means using a multisampled texture is up to 4x faster than our 4x resolution solution above.
+
+
+
+
+Above, with 4x rendering and the triangle covering 3 pixels' centers, the fragment shader is called 3 times.
+We then bilinear filter the result.
+
+This is where multisampling is more efficient. We create a special "multisample texture".
+When we draw a triangle to a multisample texture, If any of the 4 *samples*
+are inside the triangle, the GPU calls our fragment shader one time, it then writes
+the result in only those *samples* that are inside the triangle.
+
+
+
+
+
+Above, with multisampled rendering and the triangle covering 3 *samples*, the fragment shader is called only 1 time.
+We then *resolve* the result. The process would be similar if the triangle covered all 4 sample points. The fragment
+shader would only be called once but its result would be written to all 4 samples.
+
+Notice that, unlike the 4x rendering where the CPU checked if the centers of the 4 pixels were inside the triangle,
+with multisampled rendering the GPU checks "sample positions" which are not in the center. These un-centered
+sample positions apparently result in better anti-aliasing for most situations.
## How to use multisampling.
-So how do we use a multisampling? We do it via 3 basic steps
+So how do we use multisampling? We do it via 3 basic steps
1. Set our pipeline to render to a multisample texture
2. Create a multisample texture the same size as the final texture.
@@ -190,16 +208,11 @@ Some things to note:
* Multisampling does not use a grid
- Above we mentioned manually rendering to a 4x resolution texture and using bilinear filtering
- to our desired size but that is not exactly what multisampling does.
-
- Multisampling actually uses offsets like this for the 4 points it tests for inside/outside
- of the triangle
+ As pointed out above, multisampling does not happen on a grid. For sampleCount = 4
+ the sample locations are like this.
- This is even more interesting for other count settings.
-
count: 2
@@ -212,12 +225,12 @@ Some things to note:
- WebGPU does currently only supports a count of 4 but the point is, multisampling is not a grid.
+ **WebGPU does currently only supports a count of 4**
* You can optionally run the fragment shader on each multisampled pixel
- Above we said that the fragment shader only runs once for every 2x2 pixels in the multisampled
- texture. It runs it once and then it stores the result in the pixels that were actually inside
+ Above we said that the fragment shader only runs once for every 4 samples in the multisample
+ texture. It runs it once and then it stores the result in the samples that were actually inside
the triangle. This is why it's faster than rendering at 4x the resolution.
In [the article on inter-stage variables](webgpu-inter-stage-variables.html#a-interpolate)
@@ -239,12 +252,18 @@ Some things to note:
## What about inside a triangle?
-Multisampling only handles the edges of triangles so what about when we're drawing with a texture, there
-may be contrasty colors next to each other inside the triangle. Don't we want anti-aliasing there too?
+Multisampling generally only helps the edges of triangles. Since it's only calling the fragment
+shader once, when all sample positions are inside the triangle we just get the same result of the fragment shader
+written to all samples, which means the result will be no different than if we were not multisampling.
+
+In the example above, since we were drawing solid red, there's clearly nothing wrong.
+What about when we're sampling from with a texture, there may be contrasty colors next to each other inside the triangle.
+Don't we want each sample's color to come from a different place in the texture?
+
Inside the triangle we use [mipmaps and filtering](webgpu-textures.html) to pick the appropriate color
so anti-aliasing may be less important inside a triangle. On the other hand, this can also be a problem
-with certain rendering techniques which is why there are other solutions to
-anti-aliasing.
+with certain rendering techniques which is why there are other solutions to anti-aliasing and also possibly
+why you can use `@interpolate(..., sample)` if you want to do per sample processing.
## Multisampling is not the only solution for anti-aliasing.