After grokking the basics of WebGL I was stuck at where to go next. I could draw triangles, and I could give them perspective... but I didn't know how to combine them into something bigger. The Sketchpunk series was really good at showing how to build it into a library and make real projects.
I used that knowledge to make this minecraft-y thing: https://github.com/mrspeaker/webgl2-voxels (which I especially love as it doesn't use any compilation/build steps - just native modules and plain ol' javascript!).
People panicked at first about the GL Apocalypse when Apple decided to use Metal instead of Vulcan.
But here's the way I look at it: OpenGL was created to abstract over graphics hardware and operating systems both at once, and yet was intended to be high-level enough that it could be called out to directly by application developers (including game developers).
It was what people needed at the time, but I think it was trying to do too many things in a single layer of abstraction, and these days it isn't doing a great job at any of them. It's known for being slow. Most people don't write it directly anymore; they use a game engine or library and only write shaders directly. It performs inconsistently between OSes.
Whereas Vulcan, and even more so Metal, are decidedly lower-level. They abstract over the hardware and that's about it. This enables the higher-level libraries and engines that people were already using to be more fine-tuned and performant while still allowing graphics hardware to remain a commodity.
In this context WebGL is interesting because it's also an abstraction over Vulcan/Metal/DirectX, while remaining lower-level than most of those other libraries and engines. It's really very much like we've split the OpenGL layer in two and ended up with one layer focused on performance within a given OS, and another layer focused on providing a modern, ergonomic API across all systems.
All in all, I think this is a pretty good way for things to have progressed.
The real benefits of DirectX 12, Vulkan, and Metal were that they let the API designers drop cruft and add new features. This was more significant for OpenGL->Vulkan and OpenGL->Metal than it was for DirectX 11->12 because OpenGL had more cruft and so much more surface area to get wrong.
I'd still hesitate to say that Vulkan, DirectX, and Metal are lower level in any meaningful way. Most of the work the driver does/did, like shader/pipeline state compilation or command submission, is still there. Vulkan and DirectX just tie the driver's hands a bit, for better or worse inversely proportional to how good the driver stack is/was. Calling Vulkan lower-level than OpenGL is a bit like calling Java lower level than Javascript. We're still a long way from being able to shoot ourselves in the foot like we can with C.
Unless you're using the more modern features of Metal like argument buffers and manual resource tracking, Metal is closer to late-stage OpenGL than it is to Vulkan or DirectX. Otherwise, they're about the same.
I agree about the split between performance vs ergonomics, but it's a bit more complicated than that. Conceptually, the lower-level APIs expose functionality that make graphics programming much, much easier for large scale rendering engines. It's not just about performance. Most of the initial boilerplate amortizes away behind an abstraction layer anyway. What's exposed in web apis is still many years behind the state of the art in the native space. However, when it comes to just drawing a triangle with the techniques of 2010, personally I have a lot of hope for WebGPU. Besides functionality, the ergonomics problem of native apis are primarily down to tooling. Large game studios and engine devs can afford to invest in infrastructure that small hobbyists/indie devs can't.
Yes, every HN graphics thread has a group of people that complain that Vulkan isn't used everywhere. Most of them have not written any Vulkan because many HN graphics threads complain about the amount of boilerplate required to get a triangle onscreen in higher level APIs like OpenGL. I can't find a Vulkan C API hello triangle that is less than 1000 LOC, although Vulkan-hpp reduces that significantly, and many of the examples are OpenGL size.
The complexity that Vulkan introduces is not just the extra code, it's a substantial rethink of the mental model of graphics that involves a lot more precision about things like synchronization, and baking of device state. Those who argue "Vulkan requires more boilerplate" are missing the point, imho.
Or to put that same idea differently: If you treat the extra code required as “boilerplate”, then you’re unlikely to get much of a benefit from switching to Vulkan.
The issue is that OpenGL isn't going to get any new versions, so if you're trying to be forward looking there's only Vulkan even if you don't need the delta that you get performance-wise between that and GL.
Its a little surprising there's no real movement for an API that is closer to ES3 in difficulty that targets Vulkan and Metal underneath. I guess maybe webgpu will be that thing eventually.
I don't use Vulkan because I'm sick of paying for API upgrades.
I can run pretty much the same software on my desktop today as on my now-dead 2008 laptop.
On the CPU.
But the GPU is capped at OpenGL 2. What's the point of being a software enthusiast if the software is tied to the most expensive piece of hardware in the box?
I bet! I'm fortunate enough to understand the concept of shaders, and how GPUs work generally, so at least that's one concept I don't have to learn. The APIs, however, are another beast altogether.
Shameless plug: If you're interested in building a complete engine, I published a book on WebGL 2, where readers go from the very basics all the way up to building a minimalistic rendering engine (THREE.js like) and use it to render a virtual 3D car showroom.
For someone who wants to get started messing around with webgl I would recommend http://regl.party/. I found it easier to work with webgl by learning about the concepts from tutorials like https://webglfundamentals.org/ but then use regl for my actual coding, because you still need to understand the way webgl works but the API regl exposes is much more ergonomic.
It's been a while since I touched WebGL, but this site was the most informative one I found, and is what I based most of my code on: https://webglfundamentals.org/
Thanks for the heads up. I actually did look at that reference, and in particular, the WebGL State Diagram is fantastic. Unfortunately, it still uses some helper libraries that, for me, obscure the core APIs. That said, WebGL Fundamentals is definitely going to be one of my references going forward.
After that 90% of the articles only use code to compile shaders. The rest is raw.
At some point you have stop using raw OpenGL/WebGL. The point becomes to show how to apply the concepts, not focus on minutia of setting up things that were covered before.
AFAICT every article links to the articles it depends on and they all lead back to the issues that were already covered. Did you read the linked prerequisites or did you expected every article to have 10s or 100s of pages of repeated explanation?
This is no different than reading a book. If you jump to chapter 14 you can't complain it's not re-covering topics that were covered in chapters 1 through 13.
I actually think the other resources, including WebGL fundamentals, are really great. But whenever I tried reading them, they just didn't click for me.
I don't mind organizing the code. I just want the barebones in the beginning. I see that WebGL fundamentals, for example, uses a webgl-utils library, which is what tripped me up, even though it's only used for one small utility.
I do recommend writing some DSA-like helpers for OpenGL, its global state is annoying to wrangle and not that meaningful to the actual GPU. The tricky part of OpenGL is understanding when something is a bad API accident and when something is actually meaningful.
Texture bindings are a good example of something that came about mostly by accident, as they didn't want to break legacy code. So we went from "the texture" to "the current texture", and then had to introduce "the active texture" once multi sampling entered the picture.
100% agreed that I'll be writing abstractions as the program grows. But without understanding the underlying APIs, I don't know which abstractions to write.
As another commenter asked: what does "DSA-like helpers" mean in this case?
Ah, so for "DSA-like helpers" you're suggesting additional helpers that will take care of binding the given object, making manipulations, and unbinding it?
Yep. Though it's a lot trickier than just bind/unbind, e.g. if you have a VAO bound, you need to unbind the VAO before binding a vertex buffer, or else you might have overwritten the VAO's vertex buffer binding slot. And I've encountered many, many similar cases like that and edge cases, especially around framebuffer management.
After grokking the basics of WebGL I was stuck at where to go next. I could draw triangles, and I could give them perspective... but I didn't know how to combine them into something bigger. The Sketchpunk series was really good at showing how to build it into a library and make real projects.
I used that knowledge to make this minecraft-y thing: https://github.com/mrspeaker/webgl2-voxels (which I especially love as it doesn't use any compilation/build steps - just native modules and plain ol' javascript!).