WebGL2 Fundamentals
webgl2fundamentals.org
webgl2fundamentals.org
When you've exhausted this and are looking for next steps to try, I recommend this youtube series by Sketchpunk Labs: https://www.youtube.com/watch?v=LtFujAtKM5I&list=PLMinhigDWz...
I'm not trying to be snarky or say WebGL sucks (I have very little experience with it), I'm just wondering why the design choices have culminated into such an API?
You need:
1. A way to send opaque data to the GPU (this is a buffer)
2. A way to programmatically transform that data (this is a shader)
3. A way to specify input parameters to those transforms not found in the data (a uniform)
4. A way to decompose that opaque data into tangible (an attribute)
With not much more code, you can go from that to something like e.g. http://magcius.github.io/pbrtview/ using the same exact primitives. This is an example of a custom WebGL2 engine (not using three.js) in action. Leaf through https://github.com/magcius/pbrtview/blob/gh-pages/src/models... and you'll still see the same createBuffer, bufferData, drawArrays. There's not much more that I added on top.
The truth is that it doesn't really make sense to make the "render one triangle" easier since it only makes sense to use OpenGL if you are going to go deep on how it works, so accelerating the first two days down to one day isn't going to make a huge impact on the learning curve (compared with other apis where cutting the first two days to one would be a huge deal).
[0] https://www.amazon.com/Real-Time-Rendering-Third-Tomas-Akeni... [1] https://www.amazon.com/Math-Primer-Graphics-Game-Development...
I also read a ton of presentations and papers. Highly recommend the famous PBR SIGGRAPH course notes [0], especially the intro to light & physics by Naty Hoffman. GPU-Driven Rendering Pipelines [1] is another recent goodie.
[0] http://blog.selfshadow.com/publications/s2013-shading-course... [1] http://advances.realtimerendering.com/s2015/aaltonenhaar_sig...
Back when less template code was needed, we had fixed function pipelines that couldn't run shader code, and we were bound by all kinds of assumptions & limits. The APIs basically assumed you were doing perspective projection of textured triangles with Phong shading using point lights, for example. The APIs these days assume far less about what you want to do, and allow far more customization, at the expense of more setup function calls.
That said, getting started really is a total nightmare, and there's lots of room for acknowledging that most people only have one of several basic pipelines. There's no reason we couldn't have some easy default setups in addition to all the flexibility. API designers would probably argue that templates are not in their purview, but it sure would be nice if GPU interfaces took a step or two in the ease of use direction.
While every other 3D API has support for math, textures, models, shaders, fonts, basic scene graph, GL leaves to the developers to hunt for 3rd party libraries.
Khronos tried to change that by creating an SDK page, listing endorsed libraries, but it has not been updated in ages.
A lot of the verbosity is typically hidden in helper functions or libraries. I've used twgl.js (https://twgljs.org/), and it's much less code (and less potential for stupid mistakes in the boilerplate) than the pure WebGL API.
There are still many concepts to understand, there is no way around it. You're mostly writing programs that are executed on the GPU itself, and you need to understand the limitations of that to write WebGL code.
There are higher-level abstractions on top of WebGL you can use, if you don't want or need the low-level access WebGL gives you.
Good example about this issue is CSS. I have a bit strong opinion about this but I really think that fact that we cannot polyfill flexbox / grid layouts is "proof" that this technology is not good enough and lower level API would be better option (and current CSS model maybe built on top of that).
Direct texel lookups and the expanded texture formats has been amazing for using WebGL 2 for GPGPU purposes.
My personal favorite is the Canada Banknote[2]
https://en.wikipedia.org/wiki/Nunavut
Fascinating.
Unfortunately neither Safari or Edge support WebGL2 by default yet.
It might be supported, but fast is it not.
My Asus, LG, Nokia and Samsung devices don't have any hiccups with OpenGL ES 3.x games, however most WebGL demos are janky on them.
AFAIK Three.js is still missing standard optimizations that are taken for granted in a "real" engine, like batching and occlusion culling, and some optimizations it does support are scarcely used due to poor tooling. Pre-baked lighting and compressed textures are technically supported but there's no easy workflow to pre-generate the necessary data.
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.
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 :)
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...
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:
https://github.com/WebGLInsights/WebGLInsights.github.io/rel...
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.
Use native code and native APIs like OpenGL or Vulkan.
How is that an argument for more lenient rather than more extreme measures?
Do you really think the WebGL runtimes are safe and don't leak data through a side channel, possibly combined with the running JavaScript code? To make matters worse, the hardware is opague, running unknown firmware.
If that is not available, and you still really need the result of that piece of code, fetch the code, compile it and run it.
Code distribution has inherent dangers and cannot be safely made extremely effortless and comfortable. Accounting can be bothersome, but is necessary for code.
Also, It is important to keep the number of authorized sources of code to a system small.
If you insist on using that horrible language, you can deliver a webapp that runs in a JavaScript runtime through the OS package manager. That ensures proper accounting for the users.
What happens when the "authorized code source" doesn't agree with my program?
When your authorized source of code doesn't agree with a program then there is a problem, either with your source or with the program. There are too many parameters to describe all scenarios. For example, if distros refuse to provide a certain program, then you most likely are better off without it, if Apple doesn't let you install a program on your iphone, then you picked the wrong gatekeeper. Apple is a tyrant and puts its interests above yours. If you enter their garden you are on your own and I care very little for the problems there.
I'm not saying that code delivery is optimal like it is in the most popular distributions. But the Web is not the solution.
Speed is not the only metric.
I want to decide what is "good for me", I want things fast and on any platform from my phone to laptop to car to TV.
Luckily we have choices, and I choose to use the web. You can use a browser that disabled all of this, as long as your gatekeeper allows you to.
If you use Google Chrome with auto updates, for example, you've made Google an authorized source of code for your system. More general, your browser developer gets to decide for you what technologies your browser supports by default.
Most OS' facilitate automatic or semiautomatic update mechanism. Then the organization who develops these updates and sends them to you is a source of code, that is authorized by you by virtue of you installing the OS.
A gatekeeper is a good thing if you have the last say. So you choose one that works in your interest and you decide whats good for you when you disagree. And you do have gatekeepers that work, but they work in your interest and for you so you don't notice nor complain.
Not having any gatekeeper means basically letting run any code on your machine. I detailed before why that is a bad idea from the security perspective and for it's other consequences.
Unexpected tangents can be excellent, but generic ones are predictable, and the predictable is the enemy of the curious.
Second, the hardware is opague and runs unknown firmware. What lies sill in there? What will in future lie in there?
Third, how do these hardware components interact? Do they create vulnerabilities in connection with each other? Maybe side leaks that wouldn't be there otherwise?
Fourth, there are arguments for rejecting these Web technologies that are orthogonal to their security. These Web technologies lead to an ecosystem of unreviewed code that is outside of the direct and indirect control of the user, shifting power to the developers, ultimately leading to centralization.
When the OS designers get a good spec about the GPU instruction sets, memory architecture, MMU, and IO-MMU, and the OS designers can be the ones in charge of programming these to be consistent with existing OS protections, then we might start to approach an equivalence with CPUs. Then and only then, we can start worrying about subtle, modern risks like errata where the GPU hardware deviates from the idealized spec or where side-channel attacks take the wind out of our sails.
Right now, we have something much closer to the GPU being another computer with an opaque and proprietary OS and a higher-level "managed code" runtime that accepts jobs defined in a mystery ISA by a proprietary compiler suite embedded inside the "graphics driver" in our own computer. We have to have blind faith that there is any data protection as well as that there aren't any code-injection flaws that would allow malicious data and "shader" code to hijack the GPU and its bus interface to compromise the host computer.