I would actually just recommend diving into THREE.js.
It's truly one of the best documented and most "obvious" codebases out there. If all you've got is a solid understanding of JS, you can just start hacking up something nontrivial on THREE.js and you'll come out of it knowing most of WebGL.
And in doing so you'll eventually realize that even WebGL itself is quite "high level" -- there is a _huge_ amount of abstraction that you take for granted in the browser.
> you can just start hacking up something nontrivial on THREE.js and you'll come out of it knowing most of WebGL.
Sorry, but this is wildly untrue. I don't really know where to begin, but you wouldn't even need to touch shaders to accomplish that, so no, you wouldn't know most of WebGL. THREE.js is very much a thick abstraction over WebGL.
> And in doing so you'll eventually realize that even WebGL itself is quite "high level" -- there is a _huge_ amount of abstraction that you take for granted in the browser.
Also not accurate. WebGL is a -very- thin wrapper over OpenGL ES, which is itself as low level as you can go without stepping into something like Vulkan. There's almost no abstraction.
This is true. From experience I can say that the core experience of using WebGL in JS is very similar to using OpenGL ES in C.
That being said, WebGL and the browser do a little more work for you than the GL API does in C, things you'd otherwise need a helper library for. In particular, there's no shared library or header file hell, context creation is easy, image import is easy, and JS will handle memory allocation for you. It eliminates a lot of the annoying stuff needed to get to writing the actual GL code, though you still have to go through the state machine hell of GL itself :)
While true, only beginners actually use raw GL calls, even in C.
Anyone with experience quickly builds up their mini-engine to handle loading shaders, images, fonts, models, handling everything together for each model, in a mini scene graph way, handling driver and GPU specific bugs...
If you don't need to touch shaders, then you're doing something trivial, like drawing models with a camera.
Once you dip your toes into even something like alpha transparency, or z fighting, depth buffer precision, or texture upload hitches, you start to unpack the shader pipeline under the hood. Which THREE.js makes it super easy to do, because it's much more of a broad library than it is a thick one.
> Also not accurate. WebGL is a -very- thin wrapper over OpenGL ES
Conceptually it seems thin, but it's all a lie. WebGL's most awesome feature is that for simple cases you don't realize how much of a lie this is.
In practice, there is shader recompilation, sentinel rewrites and caching, sync fences, format decodes, a full-blown message queue protocol to a render thread, automatic frame flipping and composition, CPU rendering, and the end of the pipe isn't even necessarily OpenGL at all!
But I agree it appears very thin until you actually look at what's happening (or are forced to due to leaky abstractions).
One of the best resources I've read on this is WebGL Insights:
I'd argue that THREE.js is more of a graphics engine by itself. It makes a lot of choices for you (typical forward renderer, classic wasteful cubemap shadow map rather than doing any frustum culling). People confuse it with a "light-weight wrapper" probably because of the generic name and ".js" suffix but don't get confused. You'll learn as much about WebGL as you will using Unity.
I really enjoy THREE.js, but I don't think it gives you the same level of understanding of WebGL that this link does. This is like taking a course on how OpenGL works in the browser.
That being said, the amount of code needed to make a hello world in WebGL2, not including learning GLSL, is a bit daunting, and if you showed this tutorial to me first, I might not have gotten interested in doing any 3D coding in the browser. The Three.js WebGL abstraction library makes the task much less daunting and gives you some force multipliers that WebGL does not, it makes a lot of assumptions for you, and still gives you a fair amount of control over the action.
It's truly one of the best documented and most "obvious" codebases out there. If all you've got is a solid understanding of JS, you can just start hacking up something nontrivial on THREE.js and you'll come out of it knowing most of WebGL.
And in doing so you'll eventually realize that even WebGL itself is quite "high level" -- there is a _huge_ amount of abstraction that you take for granted in the browser.