Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8805533
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T01:53:32+00:00 2026-06-14T01:53:32+00:00

According to HTML5 Rocks , WebGL is actually a 2D API, not a 3D

  • 0

According to HTML5 Rocks, WebGL is actually a 2D API, not a 3D API. Why do they say that, and what does it mean?

We can specify X, Y, Z coordinates in WebGL vertex shaders and fragment shaders. I can’t understand the difference between a 2D and 3D graphics API. Could you explain why they say this is a 2D API?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T01:53:33+00:00Added an answer on June 14, 2026 at 1:53 am

    WebGL is a rasteration API not a 3D api. You have to provide it with projected coordinates. This many ways it is no different than Canvas. It’s just faster. Let’s compare.

    Here’s 3D in Canvas

    const cubeVertices = [
      -1, -1, -1,
       1, -1, -1,
       1,  1, -1,
      -1,  1, -1,
      -1, -1,  1,
       1, -1,  1,
       1,  1,  1,
      -1,  1,  1,
    ];
    const indices = [
      0, 1,
      1, 2,
      2, 3,
      3, 0,
      4, 5,
      5, 6,
      6, 7,
      7, 4,
      0, 4,
      1, 5,
      2, 6,
      3, 7,
    ];
    
    const canvas = document.querySelector("#c");
    const ctx = canvas.getContext("2d");
    
    function render(time) {
      time *= 0.001;
    
      const scale = 2;
    
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.save();
      ctx.translate(canvas.width / 2, canvas.height / 2);
      ctx.scale(canvas.width / scale, -canvas.height / scale);
      ctx.lineWidth = scale / canvas.width;
      ctx.strokeStyle = "black";
    
      const fieldOfView = Math.PI * 0.25;
      const aspect = canvas.width / canvas.height;
      const projection = m4.perspective(fieldOfView, aspect, 1, 500);
      const radius = 5;
      const eye = [
          Math.sin(time) * radius,
          2,
          Math.cos(time) * radius];
      const target = [0, 0, 0];
      const up = [0, 1, 0];
      const camera = m4.lookAt(eye, target, up);
      const view = m4.inverse(camera);
    
      const worldViewProjection = m4.multiply(projection, view);
    
      drawLines(cubeVertices, indices, worldViewProjection);
      ctx.restore();
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    function drawLines(cubeVertices, indices, worldViewProjection) {
      ctx.beginPath();
      //
      // transform points from 3D to 2D.
      //
      const points = [];
      for (let ii = 0; ii < cubeVertices.length; ii += 3) {
        points.push(m4.transformPoint(
          worldViewProjection,
          cubeVertices.slice(ii, ii + 3)));
      }
      for (let ii = 0; ii < indices.length; ii += 2) {
        var p0 = points[indices[ii + 0]];
        var p1 = points[indices[ii + 1]];
        ctx.moveTo(p0[0], p0[1]);
        ctx.lineTo(p1[0], p1[1]);
      }
      ctx.stroke();
    }
    canvas { border: 1px solid red; }
    <!-- just a math lib -->
    <script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
    <canvas id="c"></canvas>

    and here’s the same 3D in WebGL

    const cubeVertices = [
      -1, -1, -1,
       1, -1, -1,
       1,  1, -1,
      -1,  1, -1,
      -1, -1,  1,
       1, -1,  1,
       1,  1,  1,
      -1,  1,  1,
    ];
    const indices = [
      0, 1,
      1, 2,
      2, 3,
      3, 0,
      4, 5,
      5, 6,
      6, 7,
      7, 4,
      0, 4,
      1, 5,
      2, 6,
      3, 7,
    ];
    
    const canvas = document.querySelector('#c');
    const gl = canvas.getContext('webgl');
    
    const vs = `
    attribute vec4 a_position;
    uniform mat4 u_worldViewProjection;
    
    void main() {
        //
        // transform points from 3D to 2D.
        //
        gl_Position = u_worldViewProjection * a_position;
    }
    `;
    
    const fs = `
    void main() {
       gl_FragColor = vec4(0,0,0,1);
    }
    `;
    
    const program = webglUtils.createProgramFromSources(
        gl, [vs, fs]);
    gl.useProgram(program);
    
    const positionLoc = gl.getAttribLocation(program, "a_position");
    const worldViewProjectionLoc =
        gl.getUniformLocation(program, "u_worldViewProjection");
    
    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array(cubeVertices),
        gl.STATIC_DRAW);
    gl.enableVertexAttribArray(positionLoc);
    gl.vertexAttribPointer(positionLoc, 3, gl.FLOAT, false, 0, 0);
    
    const buffer2 = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer2);
    gl.bufferData(
        gl.ELEMENT_ARRAY_BUFFER,
        new Uint16Array(indices),
        gl.STATIC_DRAW);
    
    function render(time) {
      time *= 0.001;
    
      const scale = 4;
    
      const fieldOfView = Math.PI * 0.25;
      const aspect = canvas.width / canvas.height;
      const projection = m4.perspective(fieldOfView, aspect, 0.0001, 500);
      const radius = 5;
      const eye = [
          Math.sin(time) * radius,
          2,
          Math.cos(time) * radius];
      const target = [0, 0, 0];
      const up = [0, 1, 0];
      const camera = m4.lookAt(eye, target, up);
      const view = m4.inverse(camera);
    
      const worldViewProjection = m4.multiply(projection, view);
      gl.uniformMatrix4fv(
          worldViewProjectionLoc, false, worldViewProjection);
    
      gl.drawElements(gl.LINES, indices.length, gl.UNSIGNED_SHORT, 0);
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    canvas { border: 1px solid red; }
    <!-- just a math lib -->
    <script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
    <script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
    <canvas id="c"></canvas>

    The only difference between the Canvas one and the WebGL one is in Canvas I did the projection in JavaScript and in WebGL I did the projection in the shader. In both cases the code I wrote did the projection.

    In the Canvas version that code is:

    m4.transformPoint(
        worldViewProjection,
        cubeVertices.slice(ii, ii + 3));
    

    In the WebGL version that code is:

    gl_Position = u_worldViewProjection * a_position
    

    The API itself only rasterizes. I have to supply the projection code in either case. There is nothing in WebGL that does 3D. There is just a rasterization api and 2 functions, the vertex shader, and fragment shader, both written in GLSL, that I have to supply that run very fast and include a math library. I still have to provide the code to do the 3D to the API in both cases.

    WebGL is **NOT* a 3D API

    I believe it’s important to point this out. There are various versions of OpenGL. The original OpenGL from 1993 was a 3D api. You gave it 3D data, you told it what colors to make things, you told it about various lights. You gave it a model matrix and a projection matrix and it drew 3D for you.

    OpenGL ES 2.0 and WebGL got rid of all of that. They provide a rasterization API and shaders and let you program the hardware. But it’s up to you to write all the projections. You have to compute projected coordinates from 3D. You have compute lighting equations, and colors and all the rest.

    This makes WebGL and OpenGL ES 2.0 arguably much harder than the old fixed function OpenGL but at the same time it makes them massively more flexible. If you’re comfortable doing all those conversions and math or if you don’t mind learning it then jump in and do it. If you aren’t comfortable doing all then then there are plenty of WebGL 3D libraries that will do it for you.

    To you who claim WebGL is a 3D library let’s try a thought game.

    Here’s a physics library, box2d.js. You give it shapes, masses, and forces and it computes physics for you. If all it really was was a math library and you had to supply all the physics equations yourself would you still call it a physics library? Something called a physics library has to supply the physics knowledge or else it’s not a physics library. Similarly, something called a 3D library has to supply the 3D knowledge or else it’s not a 3D library.

    OpenGL 1.0 was a 3D library. You gave it 3D positions, vertex colors, lights and it drew 3D for you. You needed no 3D knowledge. WebGL on the other hand does not provide any 3D knowledge. You have to know how to do 3D projections, you have to know how to sample textures, you have to know how to do lighting calculations. It’s no longer a 3D library, it’s just a rasterization API. Calling it a 3D library is a lie and a disservice to those actually looking for a 3D library, ie, a library the provides 3D.

    Calling it a 2D library might be hyperbole but calling it a 3D library is wrong.

    Here’s another article about it.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've built a custom HTML5 audio player using jQUery according to the guide found
http://www.frostjedi.com/terra/scripts/demo/jquery02.html According to this link elements can be moved around by doing $('#container1').append($('#container2')). Unfortunately,
I understand that according to the HTML specification, it's invalid to add custom attributes
According to http://lipas.uwasa.fi/~ts/info/proctips.html#orrules , you can make basic or rules in .procmailrc with something
According to the specification on http://dev.w3.org/html5/2dcontext/#dom-context-2d-globalcompositeoperation , the lighter composition is A plus B.
According to: http://developer.android.com/sdk/android-2.0-highlights.html Android 2.0 should support the HTML5 video element. I haven't been
I'm testing HTML5 offline application. To do that, I'm stopping my local web server
I recently bought an iPod so that I could test my own HTML5 games
Does anyone know any projects/demo etc that could show me the following, clicking on
According to W3Schools and Pluralsight's HTML5 course, the <embed> tag is new to HTML5.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.