> WebGPU or WebGL are also more straightforward and a good starting point.
WebGL and WebGPU also show some of the difference in how rendering libraries have evolved. They used to be all "stateful" global state like OpenGL/OpenGL ES. WebGL followed that model as it was simple and needed for the time, but could have bugs if correct flags weren't set.
WebGPU and other newer rendering libraries (Vulkan, Metal, and Direct3D 12) are more "modern" in that they have almost no global state. They are also more raw and lower level and take a bit more to grok.
This is one of the best overviews of the differences between WebGL/WebGPU but also is similar to how OpenGL to Vulkan, Metal, and Direct3D 12 evolved.
https://webgpufundamentals.org/webgpu/lessons/webgpu-from-we...
> The biggest difference is WebGL is a stateful API and WebGPU is not. By that I mean in WebGL there is a bunch of global state. Which textures are currently bound, which buffers are currently bound, what the current program is, what the blending, depth, and stencil settings are. You set those states by calling various API functions like `gl.bindBuffer`, `gl.enable`, `gl.blendFunc`, etc…, and they stay what you set them globally until you change them to something else.
> By contrast, In WebGPU there is almost no global state. Instead, there are the concepts of a pipeline or render pipeline and a render pass which together effectively contain most of the state that was global in WebGL. Which textures, which attributes, which buffers, and all the various other settings. Any settings you don’t set have default values. You can’t modify a pipeline. Instead, you create them and after that they are immutable. If you want different settings you need to create another pipeline. render passes do have some state, but that state is local to the render pass.
> The second-biggest difference is that WebGPU is lower level than WebGL. In WebGL many things connect by names. For example, you declare a uniform in GLSL and you look up its location
> `loc = gl.getUniformLocation(program, 'nameOfUniform')`;
> Another example is varyings, in a vertex shader you use `varying vec2 v_texcoord` or `out vec2 v_texcoord` and in the fragment shader you declare the corresponding varying naming it `v_texcoord`. The good part of this is if you mistype the name you’ll get an error.
> WebGPU, on the other hand, everything is entirely connected by index or byte offset. You don’t create individual uniforms like WebGL, instead you declare uniform blocks (a structure that declares your uniforms). It’s then up to you to make sure you manually organize the data you pass to the shader to match that structure.
> Note: WebGL2 has the same concept, known as Uniform Blocks, but WebGL2 also had the concept of uniforms by name. And, even though individual fields in a WebGL2 Uniform Block needed to be set via byte offsets, (a) you could query WebGL2 for those offsets and (b) you could still look up the block locations themselves by name.
> In WebGPU on the other hand EVERYTHING is by byte offset or index (often called ‘location’) and there is no API to query them. That means it’s entirely up to you to keep those locations in sync and to manually compute byte offsets.
For a time, supporting four rendering engines did cause lots of work for game engines, much more integration and abstraction.
As OpenGL support fades at least one will drop off. I will miss it as I do still love OpenGL/WebGL. OpenGL and OpenGL ES / WebGL in particular opened up mobile/web gaming in ways never before possible. Prior to that you had Director (3D), Flash (Papervision/Away3D/etc), Silverlight and more recently `<canvas>`. Canvas is great for smaller games but you need raw power for rendering 3d and WebGL (almost a direct port of OpenGL ES) brought that and engines like three.js use that well. Mobile gaming became the biggest gaming market due to OpenGL ES and web games took a leap on WebGL, also apps, interactives and tools became faster rendered.
With GL, in many cases the global state is more simple, but to take advantage of GPUs and rendering lower level the innovations were needed. The naming to index/position based for instance is lower level and can also end up in bugs just as the global state in GL could. The benefit is performance and cleaner global state.
It is probably a good idea to learn OpenGL/WebGL as some of the concept in WebGPU/newer engines will be more clear, much of it was simpler with naming.