Presumably support for this will be added later. Fortunately you can combine components in vector constructors, such as
vec4<f32>(someVec2, z, w), as well as repeating components, such as
vec4<f32>(f) being equivalent to
vec4<f32>(f, f, f, f).
Some vector/scalar overloads missing
Some overloads are missing compared to GLSL, which may trip you up when porting GLSL. It's usually easy to work around with a bit of extra code though.
For example addition
+ can be used to add
vec3 + float and return a vec3 with the float added to every component. However the less-than
< operator only accepts vectors with the same number of components on both sides. So if you write
someVec3 < someFloat, you'll get a syntax error and have to change it to
someVec3 < vec3<f32>(someFloat).
Similarly several built-in functions currently require the same vector types for all parameters, such as
pow(a, b) and
clamp(x, a, b). So in GLSL you may have been able to write
clamp(someVec2, 0.0, 1.0); in WGSL that will have to be
clamp(someVec2, vec2<f32>(0.0), vec2<f32>(1.0)).
Odds and ends
WGSL doesn't aim to be compatible with GLSL. The syntax departure is good evidence of how this was a clean-slate redesign of a modern shader language. So don't assume the way something worked in GLSL will transfer across to WGSL.
Two minor examples of this are the WGSL
% operator works slightly differently to the GLSL
mod function (one uses
trunc, the other
atan(y, x) in GLSL is called
atan2(y, x) in WGSL. There are probably several more examples. They're generally easy to work around if you refer to both specifications to see how each work.
WGSL has a great syntax, apparently moving in a much more Rust-like direction compared to GLSL's C-like syntax. It is more powerful but also much more verbose, with every last detail of your shader having to be spelled out. However having worked with WGSL a fair bit now, I think the verbosity is actually a feature. "Explicit is better than implicit" is a good language design principle that WGSL follows. WebGL code often ends up feeling kind of vague, even though the specification does explain how everything works, which I think is down to a lot of implicitness in its design. I don't get that feeling with WebGPU - it's always clear exactly what it is doing, because you have to specify it yourself to every last detail.
The main downside of WGSL is basically that it's a young technology. It's a workable minimum viable product, but it lacks things you can take for granted in pretty much every other language, like a
+= operator. Once you get used to these limitations it's easy to just type your way around them, and surely with time the gaps will be filled in.
WGSL also still has some things that are mysterious to me. It's not entirely clear to me why
[[block]] needs to be there, along with
var<uniform>. Searching the specification can be hard work: search terms often produce dozens of results across the entire document. You have to be prepared to do a bit of trawling, and if you're really serious, think about just sitting down and reading it start to finish. It will still be great to have proper developer documentation for WGSL that is more readable than the spec - this blog post is just a band-aid for the time being and hopefully will help some other intrepid WebGPU developers along the way. But for those of us working with it already, it's an exciting technology with a lot of promise, and I'm looking forwards to working with it more in future!