> if you are using gl.enable(gl.BLEND) in your core render loop, you have basically already failed.
> if you are using gl.enable(gl.BLEND) in your core render loop, you have basically already failed.
That latter issue is a real problem, because it makes the frame a lot harder to refactor. One of the biggest stumbling blocks for any new graphics programmer that started on OpenGL is implementing something like a Z-prepass or a shadow map, where you have the same object drawing to two passes, because the GL state machine makes it very easy to accidentally depend on some hidden piece of state you didn't know you were using.
The right answer is to have a state tracker that knows the current state, and some combination of object/pass/material know the state intended to switch to.
And gl.BLEND is the easy case. Things like VAOs and FBOs are dangerous to have bound latently, because of GL's brutal bind-to-modify API design. Bind-to-modify was optionally dropped when EXT_direct_state_access was added, but that never made its way to GLES/WebGL, unfortunately.
For other things, specifically WebGL may need to run expensive input validation which might also trigger at more or less random places.
Also: it's very easy to forget one tiny state change out of dozens, which then mess up rendering in more or less subtle ways, not just for the rest of the frame, but the rest of the application lifetime.
If you want to change blending for each draw call you can change the blending function or just return suitable alpha values from the fragment shader.
The GPU underneath looks a lot more like Vulkan than it does like OpenGL. Changing state should, in general, not require communicating with the GPU at all, that happens once you draw stuff (or do other operations like compiling shaders or creating textures).