WGSL basics
Here in this step, we will learn the basics of WebGPU Shading Language (WGSL). WGSL is designed to be a simple and efficient language that can be easily compiled to SPIR-V1 or other intermediate representations. The syntax of WGSL is similar to Rust2, C, Typescript or GLSL, making it easy to learn for developers who are already familiar with those languages. However, there are some key differences between WGSL and other shading languages that you should be aware of. The syntax of WGSL was the most controversial part of the WebGPU API, and it was changed multiple times during the development of the API 3. The final syntax is a compromise between the different stakeholders, and it is designed to be easy to read and write, while still being efficient to compile and execute. Debugging and profiling tools are still in development for browsers and they are expected to be available in the near future. So, here we don't have any interactive editor to run each code snippet, but you can try them in your local environment by setting up the WebGPU API and the necessary pipeline to run the shader code.
Table of contents:
- Plain Types
- Variable Declaration
- Vectors
- Matrices
- Arrays
- Entry Points
- Shader Attributes
- Flow Control
- Built-in Functions
i32
: 32 bit signed integeru32
: 32 bit unsigned integerf32
: 32 bit floating point numberbool
: boolean valuef16
: 16 bit floating point number (f16 extention should be enabled 4 )
Note that in a function declaration, the return type is specified after the ->
symbol.
WGSL supports 3 types of vectors: vec2
, vec3
, and vec4
. These are used to represent 2, 3, and 4 component vectors respectively.
You can access the components of a vector using the following syntax:
Note that v1, v2, and v3 will all have the value 2.0 as they are accessing the second component of the vector.
Swizzling is a feature that allows you to access the components of a vector in a specific order. For example, if you have a vec4
and you want to access the x
and y
components, you can do so using the following syntax:
Note: there is a proposal to allow swizzling on the left side of an assignment, but it is not yet supported in WGSL. 5
WGSL supports many types of matrices, such as mat2x2
, mat3x4
, mat4x4
, etc. These are used to represent 2x2, 3x4, 4x4 matrices, respectively.
You can access the components of a matrix using the following syntax:
WGSL supports arrays of any type, including other arrays. The difference between an array and a vector is that an array has a fixed size, while a vector has a fixed number of components.
Note: As of version 1.0, WGSL cannot retrieve the length of a fixed-size array.
WGSL also supports runtime arrays, which are arrays whose size is determined during program execution. These arrays can only be declared at the root scope of the shader with storage buffer resources and are the only arrays that can be specified without a predefined size. The size of a runtime array can be determined using the arrayLength
function.
An entry point is a function that is called by the host application to start the execution of the shader. It is either a @vertex
, @fragment
, or @compute
function.
Shader attributes are used to specify the input and output of a shader. They start with the @
symbol.
Inter-stage communication is done using the @location
attribute. It is used to specify the location of an input or output variable in the shader.
In the example above, the @location
attribute is used to specify the location of the color
attribute in the VertexOutput
struct and the uv
attribute in the FragmentInput
struct.
The @builtin
attribute is used to specify built-in attributes that are provided by the WebGPU API 6.
WGSL supports the some of the common flow control statements. the syntax is similar to Rust or C.
-
if
statement -
for
loop -
while
loop -
loop
statement -
switch
statement -
continue
statement -
continuing
block -
discard
statement
There are many built-in functions in WGSL that can be used to perform common operations 7. Some of the most commonly used functions are:
abs(x)
: Returns the absolute value ofx
.ceil(x)
: Returns the smallest integer greater than or equal tox
.clamp(x, min, max)
: Clampsx
to the range[min, max]
.cos(x)
: Returns the cosine ofx
.sin(x)
: Returns the sine ofx
.cross(a, b)
: Returns the cross product ofa
andb
.degrees(x)
: Convertsx
from radians to degrees.length(x)
: Returns the length ofx
from the origin.smoothstep(edge0, edge1, x)
: Returns a smooth interpolation betweenedge0
andedge1
based onx
.
We will Learn more about these functions in the next steps.
- Ninomiya, K., Jones, B., & Jim, B. (2024). WebGPU W3C Working Draft. w3c. https://www.w3.org/TR/2024/WD-webgpu-20240626/
- https://youtu.be/3mfvZ-mdtZQ?si=gbse6seu9xXVIOpu
-
https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html ↩
-
A brief explaination about the WGSL syntax by Corentin Wallez, Tech lead of WebGPU at Google and co-chair of the respective w3c working group https://youtu.be/RR4FZ9L4AF4?si=p0SeIxFEDVNCkdNp&t=2806 (46:47) ↩
-
https://github.com/gpuweb/gpuweb/discussions/3478#discussioncomment-3738911 ↩