How to Draw Your First Point with WebGL: A Step‑by‑Step Hello World

This article walks a front‑end beginner through the fundamentals of WebGL, explaining canvas basics, hardware vs software acceleration, and providing a complete Hello World example with HTML, shader code, and JavaScript to render a single red point on a green canvas.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
How to Draw Your First Point with WebGL: A Step‑by‑Step Hello World

Hardware vs Software Acceleration

WebGL provides hardware‑accelerated 3D rendering for the HTML5 <canvas> element. Hardware acceleration means the GPU executes drawing commands, while software acceleration runs the same commands on the CPU.

What is Canvas

The <canvas> element is a drawable area in HTML5. Historically images were displayed with <img> or Flash, but Canvas gives a programmable drawing surface that WebGL can accelerate.

Hello World!

The author, a front‑end novice, creates a minimal WebGL program that draws a single red point on a green canvas, illustrating the rendering pipeline from vertex to fragment shader.

Write HTML Code

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <title>Hello World, WebGL!</title>
    </head>
    <body onload="main()">
        <canvas id="webgl" width="800" height="800">Please use a browser that support "canvas".</canvas>
        <script type="text/javascript" src="Helloworld.js"></script>
        <script type="text/javascript" src="Helloworld-Shaders.js"></script>
    </body>
</html>

Write Shader Code

// Vertex shader
var VERT_SHADER_SRC = `
void main()
{
   gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
   gl_PointSize = 50.0;
}
`;
// Fragment shader
var FRAG_SHADER_SRC = `
void main()
{
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

Write JS Code

// Get WebGL context (compatible with various browsers)
function getWebGLContext(canvas, opt_attribs) {
  var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
  var context = null;
  for (var i = 0; i < names.length; ++i) {
    try { context = canvas.getContext(names[i], opt_attribs); } catch (e) {}
    if (context) break;
  }
  return context;
}

// Initialize shaders
function initShaders(gl, vshader, fshader) {
  var program = createProgram(gl, vshader, fshader);
  if (!program) { console.log('Failed to create program'); return false; }
  gl.useProgram(program);
  gl.program = program;
  return true;
}

function createProgram(gl, vshader, fshader) {
  var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
  var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
  if (!vertexShader || !fragmentShader) return null;
  var program = gl.createProgram();
  if (!program) return null;
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!linked) {
    console.log('Failed to link program: ' + gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
    gl.deleteShader(fragmentShader);
    gl.deleteShader(vertexShader);
    return null;
  }
  return program;
}

function loadShader(gl, type, source) {
  var shader = gl.createShader(type);
  if (!shader) { console.log('unable to create shader'); return null; }
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (!compiled) {
    console.log('Failed to compile shader: ' + gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

function main() {
  var canvas = document.getElementById('webgl');
  if (!canvas) { console.log('Failed to retrieve the <canvas> element'); return; }
  var gl = getWebGLContext(canvas);
  if (!gl) { console.log('Failed to get the rendering context for WebGL'); return; }
  if (!initShaders(gl, VERT_SHADER_SRC, FRAG_SHADER_SRC)) { console.log('Failed to initialize shaders.'); return; }
  gl.clearColor(0.0, 1.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.POINTS, 0, 1);
}

Execution Flow

Obtain the <canvas> element.

Call getWebGLContext() to acquire a WebGL rendering context.

Initialize shaders by creating, loading, compiling, and linking them into a program.

Set the canvas clear color and clear the color buffer.

Issue drawArrays(gl.POINTS, 0, 1) to render a single point.

Shader Initialization Process

Create a shader object with createShader() (vertex or fragment).

Load the source code via shaderSource().

Compile the shader with compileShader().

Create a program object using createProgram().

Attach both compiled shaders to the program with attachShader().

Link the program using linkProgram().

Activate the program in the current context with useProgram().

Conclusion

With these steps the author has built a complete, minimal WebGL pipeline that draws a single pixel, demonstrating how Canvas, shaders, and JavaScript cooperate to achieve hardware‑accelerated graphics in the browser.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendGraphicsJavaScriptCanvasWebGLShader
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.