dahart 6 years ago

> This is because OpenGL is at its essence a 2D API.

I know @greggman has made this argument strongly and repeatedly. He’s not wrong, and he’s definitely an authority on the subject, he’s done amazing, amazing things for WebGL. But I keep bumping into this argument and I find the strict insistence on the 2d part exceeding the argument’s usefulness.

It’s useful to know that you’re on your own to handle projections and matrices. They aren’t built-in to the fixed function pipeline the way they used to be. It’s useful to be able to think of WebGL as a rasterization engine, and it’s useful to understand how the pieces fit together.

It’s not useful to claim that WebGL isn’t 3d at all ever, or to stick firmly to that interpretation. WebGL does have support for 3d coordinates, 3d textures, 3d matrices, and it’s main function is to present 3d graphics. Say what you want about having to roll your own transforms, there is absolutely 3d support and 3d intent designed into WebGL.

If you really want to insist that WebGL is a 2d API only, then get the Khronos Group to say that. Currently the WebGL page says: “WebGL is a cross-platform, royalty-free web standard for a low-level 3D graphics API based on OpenGL ES, exposed to ECMAScript via the HTML5 Canvas element.” Appeal to them to change the wording to 2d. As long as Khronos calls it 3d, then it’s 3d. Trying to convince people otherwise on the internet can never work.

  • westoncb 6 years ago

    After working with OpenGL for many years and then moving to higher-level systems more recently (e.g. three.js), I found a useful way of viewing the 'essence' of the API: moving data around. It's not so much a '3D graphics API' as it is a wrapper for interacting with a a GPU.

    (A notable exception is shader code, which is largely doing custom geometric or pixel transformations. But the rest of it is pretty much an API for moving blocks of data in and out of the GPU.)

    I think this is important to know, because the common perception is that OpenGL, as an API for creating 3D graphics, would give you primitives for talking about 3D objects/spaces—which for the most part it doesn't, aside from essentially utility classes (e.g. vectors/matrices for working with 3D spaces). In consideration of that, it's a pretty awful experience if you're interested in describing 3D scenes, as opposed to developing new rendering techniques or optimizing old ones or whatever.

    So instead, it's an API well-suited to building actual 3D graphics APIs on top—scene graphs, game engines, etc. My understanding is that Vulkan/Metal take this to a further extreme, and I see it commonly mentioned in that context—but it's true of OpenGL too!

    It should be more common to warn beginners: learn OpenGL so that you can understand the underpinnings of some other system you will eventually use to describe 3D graphics—but this isn't the endpoint, don't build all your games or whatever directly on OpenGL. You will have so much more fun with a good scene graph.

    • MaxBarraclough 6 years ago

      > It's not so much a '3D graphics API' as it is a wrapper for interacting with a a GPU.

      Mandatory link to Zed Shaw's blog post on the difference between an 'indirection layer' and an 'abstraction layer'.

      Abstraction is used to reduce complexity. Indirection is used to reduce coupling or dependence.

      * https://zedshaw.com/archive/indirection-is-not-abstraction/

      • westoncb 6 years ago

        Hmm, but I didn't say it was an indirection layer nor an abstraction layer...

        • MaxBarraclough 6 years ago

          If I'm understanding you and Zed correctly, you pretty much did, you just didn't use Zed's terminology.

          As you say, the intent of modern graphics APIs like Vulkan isn't to spare the graphics programmer the hard work of writing low-level code. Instead the intent is to provide a minimal indirection layer which does just enough work to let graphics code work on any vendor's hardware, whilst preserving the graphics programmer's ability to do low-level cleverness.

          So game-engines and scenegraph systems are in the business of abstraction, but graphics APIs are in the business of indirection.

          • westoncb 6 years ago

            Okay, I see your point. But indirection only enters the picture once you introduce the possibility of multiple graphics cards which are being communicated with the same API—and I agree, that is an example of indirection.

            However, it's not the role I was attempting to highlight. I was considering the role of OpenGL/WebGL in relation to a single graphics card: if you consider that situation, the API is still necessary and what it's doing is neither (much) abstraction nor indirection. Instead, it's main task is essentially conversion: the graphics card needs data in one format, javascript programs assemble their data in another (I'm using data very loosely here; I mean to include even the program source, since it's in a 'format' we can just give directly to a GPU).

            That said, even something like Vulkan does abstract a bit, and once you bring in the possibility of multiple cards, the value of its role as an indirection layer becomes clear.

    • dahart 6 years ago

      > I found a useful way of viewing the ‘essence’ of the API: moving data around. It’s not so much a ‘3D graphics API’ as it is a wrapper for interacting with a GPU.

      It is very true that most of the WebGL functions just move data in & out of the GPU, but to me this feels similar to saying that WebGL is a 2D API. The thing is, all APIs essentially move data around, if we break it down. It feels maybe too reductionist. But it depends on your goal, right?

      For a student who wants to know how WebGL works, it is helpful to break down WebGL into components: move data into GPU, rasterize into buffer, view or optionally copy data out. Where’s the 3d? You get support for 3d data & operations, but (unlike OpenGL 1) you now have to design your 3d->2d projection yourself.

      For everyone else, for people who want to know what WebGL is for or why it was built, and for people to want to know how to make 3d graphics, it’s not that helpful to say that WebGL is 2d or that it moves data around. It’s more helpful to know that WebGL is the API you need, if your goal is 3d graphics in a browser.

      In any case, it’s problematic to insist that either interpretation is the complete picture, or that one of them is wrong, agreed?

      > So instead, it’s an API well-suited to building actual 3D graphics APIs on top—scene graphs, game engines, etc.

      Or, OpenGL/Vulkan/Metal/WebGL are actual APIs for 3D that are good for building scene graph APIs and game engine APIs on top of? These 3d graphics APIs intentionally don’t provide scenes graphs, for very good reasons. That would compromise their generality and speed.

      • westoncb 6 years ago

        > The thing is, all APIs essentially move data around

        Technically true, but misleading to bring up. OpenGL is different because the primitives in it are explicitly about collections of data of specific types. Whereas an API that was 'about' 3D graphics would offer primitives related to the shape, position, and other aspects of the appearance of 3D forms and how they change in time.

        > It’s more helpful to know that WebGL is the API you need, if your goal is 3d graphics in a browser.

        I disagree. I think for almost everyone's needs, the API they need is something more like three.js. If you are writing a new scene graph or whatever, then WebGL is what you're looking for.

        More importantly though, it's about managing expectations of new users: yes, you can use OpenGL/WebGL to create moving 3D pictures—but it's going to be a linguistically awkward, and yet (potentially) performant, way of doing it.

        > These 3d graphics APIs intentionally don’t provide scenes graphs, for very good reasons. That would compromise their generality and speed.

        To be clear, I am not saying that OpenGL, Vulkan, etc. should provide scene graphs. I'm saying they are essentially hardware access layers with some special utilities for doing graphics stuff. They need to exist, and they should not be doing irrelevant things like providing scene graphs.

        • dahart 6 years ago

          > OpenGL is different because the primitives in it are explicitly about collections of data of specific types.

          Different than what? Three.js? OpenCV? Firebase? Instagram? All of these can be described as being explicitly about collections of data of specific types. This isn’t differentiating, you’re still describing all APIs.

          > Whereas an API that was ‘about’ 3D graphics would offer primitives related to the shape, position, and other aspects of the appearance of 3D forms and how they change in time.

          That is what WebGL provides. You’re trying to split a hair that doesn’t exist. I realize you’re trying to talk about the difference between immediate mode and retained state graphics APIs. Both are “about” 3D, and retained mode is not more 3D or more “about” 3D than immediate mode.

          I’d argue the other way around. Three.js is built on top of WebGL, it doesn’t do 3d graphics without WebGL, and the only thing it adds is retained mode state, i.e., a specific type of data. Three.js doesn’t do it’s own drawing, and it doesn’t add any 3D to WebGL that wasn’t already there, it only adds management of some host side memory so it can call WebGL on the same data repeatedly. By your own metric, three.js is less “about” 3d than WebGL.

          Anyway, none of this really relates to the original point. Saying that WebGL is about data is neither supporting the argument that WebGL is about 2D graphics nor refuting the argument that WebGL is about 3D graphics.

          > To be clear, I am not saying that OpenGL, Vulkan, etc. should provide scene graphs.

          Right. They shouldn’t because their purpose is 2D or 3D drawing in any form, not management of a node graph or scheduling of draw calls.

          • westoncb 6 years ago

            > All of these can be described as being explicitly about collections of data of specific types. This isn’t differentiating, you’re still describing all APIs.

            Maybe my usage of 'explicit' was unclear. Here is an example of a primitive which is explicitly about storing/moving collections of data, independent of what that data is used for: glBufferData, glClearBufferfv, glGetBufferParameteriv, glMapBufferRange. Firebase and OpenCV I could maybe see having explicit data constructs; Instagram sounds hugely unlikely. And saying that three.js is explicitly about moving data around is ridiculous: it's core is about 3d graphics concepts, like coordinate systems, geometries, materials, and cameras. The only time where it talks about raw data in the same way are a small number of classes that need to be extremely efficient, so they compromise and break the abstraction to WebGL, making reference to its primitives.

            > Three.js is built on top of WebGL, it doesn’t do 3d graphics without WebGL

            Not at all true. It's architected to be independent of WebGL. When you use it you can construct a WebGLRenderer or a CanvasRenderer and get 3D graphics with either (obviously WebGLRenderer is going to be far more efficient since it uses the GPU, but it is in no way 'more 3d').

            > Saying that WebGL is about data is neither supporting the argument that WebGL is about 2D graphics nor refuting the argument that WebGL is about 3D graphics.

            I should have clarified the connection: I saw the argument that it's about 2D graphics is being one way of getting at a more significant point: it's not really about 3D graphics as much as people typically think. Which was my shared point.

  • w1nt3rmu4e 6 years ago

    > This is because OpenGL is at its essence a 2D API. The vertex shader accepts something as input and it produces 2D vertices in device coordinates (-1 to 1) as output.

    And the same can be said for every other GPU API. That's what rasterization is. You take a bunch of input and put out a 2D texture. It's necessarily 2D because screens are 2D.

    Luckily, first class support for matrices, 4D vectors, mipmaps, lighting (well, at least insofar as lighting is math), etc make it well suited for creating the illusion of 3D.

    I get paid to work with OpenGL -- and, somewhat uniquely, 2D OpenGL. I'm confident in saying that while OpenGL might suffice for a 2D game engine and yes, might allow you to skip over a little bit of the math, it is terrible as a 2D UI engine.

    GPU APIs are first and foremost for rendering 3D scenes. You can certainly use them for 2D but how well suited they are to that is dramatically dependent on what the use case is.

    • pjmlp 6 years ago

      Sadly OpenGL as 2D UI is Google's answer for anyone that wants to do 2D rendering from the NDK.

      Which means everyone ends up writing their own little library on top of OpenGL, or increasing their APK size bringing in SDL, Cocos2D, ....

      Or if 2D rendering performance isn't a constraint, calling via JNI the Canvas API, which happens to use Skia for its native methods, but isn't exposed as NDK API.

    • earenndil 6 years ago

      Do you think other gpu apis (vulkan, metal, direct3d) are better suited for 2d?

      • pjmlp 6 years ago

        Direct3D alone not, but DirectX as a whole yes.

        Same applies to Metal.

        OpenGL suffers from "go fish libraries" mentality, where we only get a way to put pixels on the GPU and nothing else.

        While Metal, DirectX, LibCGNM, NVN, GX, GX2 provide a complete framework around their APIs.

        You get a way to do math, shader loading, dealing with fonts, textures, materials, scene descriptions, mesh loading, shader management.

        If I had a penny for every OpenGL tutorial that teaches how to manually load, compile and link shaders, or which libraries I am supposed to hunt down, I would be enjoying some nice vacations.

  • Jasper_ 6 years ago

    I think it can be a helpful way to think about it for some beginners, but yeah, it's not strictly true. I'd say "the goal of 3D APIs is to display 3D images on your 2D screen", and that means that, at the far end of the pipeline, after you've projected and flattened everything, you have 2D concepts: triangle rasterization and fragment shaders operate entirely in 2D, for instance. The only remaining "3D"-esque thing, which is perspective-correct attribute interpolation, happens in screen space.

    • andrewmcwatters 6 years ago

      That's cute but it's also about as relevant as saying cooking is just chemistry. You're not wrong but you're also ignoring the artistry, taste, tradition, image, class, and every other aspect of cooking.

      If at the end of the day cooking is chemistry, well then serve me up some atoms.

      • vidarh 6 years ago

        The point kinda is that Webgl is closer to the chemistry than the cooking: It's a fairly low level API. It doesn't offer you a scene graph or otherwise let your work with 3D objects. It doesn't care if the vertex shader input is 3d coordinates, or anything else. It doesn't handle the camera for you, and so on.

        It offers you the essential elements you need to compose 3d abstractions (or you can use it for something else), or for a library to run on top of. Or you can choose to use it directly, but then you are in effect cooking with a chemistry set.

      • Jasper_ 6 years ago

        All I'm saying is that it's a way of thinking about it. It clearly helped the author think about "rasterized 2D screen-space triangles" rather than "something something 3D". They clearly had some misconception and "WebGL is a 2D API" helped clear it up.

        I'm not saying it's the one true way to think about 3D graphics APIs, or that it's wrong or right.

  • shawn 6 years ago

    For a pretty amazing example of the 3D work you can do with WebGL, see N64 VR with Javascript https://medium.com/webmr/n64-vr-with-javascript-e188de42ced5

    • tzahola 6 years ago

      How does this connect to the parent comment??

      • shawn 6 years ago

        If WebGL were a 2D API, it would have made it impossible to do this kind of work. Also VR in general.

        • skolemtotem 6 years ago

          It would always be possible to project a 3D world onto a 2D plane in any 2D graphics API, which is exactly what the projection matrix does in OpenGL.

          • Animats 6 years ago

            The projection matrix transforms the 3D world into a 3D world in screen space. Two of the dimensions are the screen coordinates, and the third is depth into the screen. The depth is used for Z-buffering (hiding the stuff in back), and for fog and focus effects.

            • seandougall 6 years ago

              Depth in OpenGL is a separate 2D buffer. You can use it to approximate the effects of 3D space, but it’s still fundamentally a set of 2D operations.

              Of course, it’s all fundamentally just bits on a heap, so past a certain point the argument becomes academic.

            • skolemtotem 6 years ago

              That, I sort-of agree with. Layering isn't unique to 3D, so it's debatable whether the incorporation of a depth buffer makes OpenGL a 3D API.

              • Animats 6 years ago

                It's not layering. It's depth. The depth buffer will work for cases where two objects cross in Z. Unlike the painter's algorithm.

  • vvanders 6 years ago

    I would agree if it wasn't for the perspective corrected interpolation that happens in the w/z component for vertex properties[1].

    You're not going to get that in a 2D rasterization API without doing a per-pixel calculation of each rasterized pixel(due to non-linearity) which would defeat the point of a 2D API.

    [1] https://stackoverflow.com/questions/24441631/how-exactly-doe...

    • kevingadd 6 years ago

      You get that in plenty of 2D environments though. If you do a perspective warp in Photoshop you can get it, and CSS transforms (for HTML content!) will do it if you rotate around the x or y axes.

      • vvanders 6 years ago

        That's because all of those are a perspective projection that flattens a 3 dimensional frustum into a 2 dimensional plane.

        It's kind of like saying that your eyes can't see things in 3 dimensions because all of the light is focused only on the back plane of your retina.

  • echevil 6 years ago

    That's the kind of argument I would simply discard, and it is only a matter of interpretation and can provide no benefit whatsoever..

AKluge 6 years ago

No, WebGL is not a 2D API. Neither is its predecessor, OpenGL. This comment from the article is particularly misleading.

> OpenGL is at its essence a 2D API. The vertex shader accepts something as input and it produces 2D vertices in device coordinates (-1 to 1) as output.

This, and some of the comments in this thread, perhaps stem from a misunderstanding of the projection matrices. The projection that you do yourself is a projection from a large, arbitrary, 3D space to a small 3D space where x, y, and z are restricted to [-1, 1]. These are the device coordinates (http://www.vizitsolutions.com/portfolio/webgl/normalizedDevi...). The hardware is very good at projecting this small 3D space onto the screen.

Indeed, it is possible to write a 3D program entirely within the device coordinates. This example draws two triangles, without any projection, where one is clearly behind the other. http://www.vizitsolutions.com/portfolio/webgl/translationMat... Drag the slider to see one triangle move behind the other.

Even this is a simplified explanation. There are a lot more details here, including all the math: http://www.songho.ca/opengl/gl_projectionmatrix.html This shows why the output from a vertex shader, gl_position, is a vec4. It is definitely not a 2D value.

That said, yes, WebGL is great :)

  • ajross 6 years ago

    I think the point was that the OpenGL framebuffer is ultimately a 2D space. Whatever your input data and computation model, at the end of the data the output from your computation goes into a set of arrays with two index coordinates. That's a fairly specious point, maybe, but it's not wrong.

    • jmts 6 years ago

      But surely since the memory that the frame buffer is encoded into is 1D, OpenGL is really one-dimensional. /s

      Sure, the frame buffer is 2D in the end - it has to be, in order to display on a standard computer monitor - but surely the fact that OpenGL is able to natively handle point data as 3D-homogeneous coordinates, and support for techniques like depth buffering out of the box counts for more than any argument that only really amounts to "after it is finished doing all its work you just have a 2D image".

    • jonbronson 6 years ago

      Sure, ultimately most rendering is about producing 2D images as output. But the whole OpenGL pipeline is designed around taking 3D data, and providing abstractions to enable that rendering. Rasterization and depth sorting are only one piece of the rendering pipeline. Of course it's also possible to drop the z coordinates, or use orthogonal projections, to use OpenGL in a purely 2D way. Plenty of applications do that, but that doesn't make the API 2D. It just makes the use case 2D.

zerr 6 years ago

Is WebGL here to stay? As Apple deprecated OpenGL...

  • mcpherrinm 6 years ago

    WebGL is already implemented on top of DirectX on Windows using ANGLE: https://en.wikipedia.org/wiki/ANGLE_(software)

    As a result, operating system support isn't really relevant to browser support, since ANGLE will eventually be able to target metal or vulkan on Mac os

    • zerr 6 years ago

      What about OpenGL? Is it worth learning now?

      • megaman22 6 years ago

        Depends on your target platform and what you're doing. On Windows? Learning DirectX will be more bang for your buck. Apple? Then Metal is probably the way to go, if you need low-level control and performance. Vulkan if you want crossplatform low-level control. If you don't care so much about the nitty gritty details and want to get things done quickly, Unreal or Unity is probably more rewarding.

        One of the difficulties with OpenGL is that it's awfully fragmented and there are many ways to do things that have evolved over time. Learning resources are consequently spread around, and it's really easy to learn suboptimal obsolete ways of doing things.

      • Bekwnn 6 years ago

        Graphics apis are similar in their fundamentals. Dont bother fretting about which to learn. Instead make sure you understand how the systems transfer and process data between the CPU and GPU.

      • pjmlp 6 years ago

        You should learn 3D in general, and then the platform APIs.

        Contrary to popular belief, OpenGL wasn't never the universal 3D API outside the PC world.

        Games consoles and some embedded stuff always favoured their own.

        Also the APIs are very low level.

        So when you finish doing a scenegraph, font, texture, materials, math, shader management, physics, frame management, UI, Mesh loader, the actual conversion of triangles into pixels is a tiny portion of the overall code.

        • zerr 6 years ago

          I meant for the person who is more or less knowledgeable in 3D in general but needs to use a specific API to actually put some pixels on the screen. And also career-wise, would it make sense to become an "OpenGL programmer" nowadays? (or product-wise - should we do it in OpenGL when we care about long-term support?). Again, I want something like OpenGL level, i.e. don't care about Vulkan like low-level control.

          • pjmlp 6 years ago

            OpenGL still has lots of steam in it and 4.6 was recently released, so it isn't going away anytime soon.

            Even on mobile devices, Vulkan is hardly being embraced by Android developers, because it requires Android 7 or later, while being an optional API, which implies a tiny portion of their customer base.

            So very few devices support it, to the point Google doesn't think it is worthwhile to display on Android dashboards.

            https://developer.android.com/about/dashboards/

            http://vulkan.gpuinfo.org/vulkansupport.php#android_devices

            AMD is also busy trying to cater CAD vendors to adopt Vulkan, with initiatives like V-EZ.

            https://gpuopen.com/v-ez-brings-easy-mode-vulkan/

            However, if you want to be an engine developer, probably it would be better to have Vulkan knowledge than the APIs that everyone else already knows.

            Some guys at Khronos sessions (check their YouTube) stated they would favor candidates in interviews in such cases.

            For product development, I am a bit fan of middleware where each API is just a tick box away, though.

      • skolemtotem 6 years ago

        Yes! I'd suggest learning OpenGL, then Metal, then Vulkan/DX12, which is how I'd rank them from high to low level.

        • Teknoman117 6 years ago

          Specifically I'd suggest sticking to OpenGL 4.x and ES 3.x when learning OpenGL. Even OpenGL 4.4+ brought a lot of changes that should be used instead of what existed before (bindless resources, texture/buffer storage, persistently mapped buffers, etc.)

        • zerr 6 years ago

          I'd prefer to stay at OpenGL level. Maybe some kind of standardized high-level API pops up on top of Vulkan/Metal, for those who don't want to go that low-level.

          • skolemtotem 6 years ago

            Metal is actually not that bad to live in. Vulkan, on the other hand, is micromanagement hell. I definitely agree with the people saying that it's for "building your own OpenGL".

            • pjmlp 6 years ago

              Worse, because they took the extensions concept and took them a step further.

              Every couple of weeks there is a new version, and each card supports a certain minor version.

              https://vulkan.gpuinfo.org

      • tzahola 6 years ago

        Just learn the fundamentals in a platform-agnostic way and you’ll be set for life:

        - 3D geometry (lines, planes, implicit and parametric surfaces)

        - basic splines (Bezier, Hermite, maybe NURBS)

        - matrix transformations

        - rotation via quaternions

        - projective 3D geometry

        - shading (diffuse, Phong, etc)

        - advanced tricks (shadows, reflections, etc)

        Once you nail down these topics, the rest is just learning the specific API quirks (memory model, synchronization, etc), be it OpenGL, Metal, DirectX, Vulkan, or whatever comes next in ten years.

  • Animats 6 years ago

    That might not happen. Microsoft deprecated OpenGL over a decade ago, but they still have to support it. Apple only has about 10% market share in desktops and laptops. They don't want to make the "Not available on Mac" problem worse.

    • pjmlp 6 years ago

      On Windows OpenGL is only supported on legacy Win32 apps.

      Microsoft ported Angle to UWP and last time I bothered to check it wasn't part of desktop bridge.

  • bas 6 years ago

    I’m guessing that Safari’s WebGL implemtation is Metal-based.

    • muizelaar 6 years ago

      It's not. It currently still uses OpenGL.

pandaman 6 years ago

I have not used OpenGL much and don't know if you can actually output 2D device coordinates, but I am sure it supports the same format the hardware uses natively - 4D device coordinates.

With the 4D device coords it can do things, which make no sense in 2D: clipping against view frustum (e.g. how do you clip against the front plane in 2D?) and perspective mapping.