With WebGL drawing, you have to deal with memory and GPU, and really control every detail of the graphics output.

First, the most basic concept of WebGL

2. WebGL draws graphics

  1. createWebGLContext;
  2. createWebGLProgram;
  3. Storing data in a buffer;
  4. Read buffer data toGPU
  5. GPUperformWebGLProgram, output results.

1. Create WebGL context

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
Copy the code

2. Create WebGL applications

Create a WebGLProgram object for the GPU to eventually run the shader program.

  1. Writing shaders

    Shaders are snippets of code written in the GLSL programming language.

    // Vertex shader: is responsible for processing the vertex information of the graph.
     const vertex = ` attribute vec2 position; Void main() {gl_PointSize = 1.0; Gl_Position = vec4(position, 1.0, 1.0); } `;
     // Pixel shader: is responsible for processing the pixel information of the graph.
     const fragment = ` precision mediump float; Void main() {gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); } `;
    Copy the code

    When I’m drawing,WebGLThe geometric information of graph is described by vertex and element.

    • Vertex: The vertex of a geometric figure.

      Vertex Shader: Handles the Vertex information of a graph. You can change the vertex information, such as point coordinates, normal direction, material, etc., so as to draw the shape or size of the graph.

    • Primions: graphic units that WebGL can directly process (other non-primions must eventually be converted to primions before they can be processed by WebGL). Points, lines, triangles, etc. are determined by WebGL’s drawing mode.

      Fragment Shader: Is responsible for processing the pixel information of the graph. Color the pixels in the specified pixel (handles the rasterized pixel information).

      Rasterization process: The process by which WebGL extracts pixels from vertex shaders and primitives to execute code on the pixel shaders.

  2. createshaderobject
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertex);
    gl.compileShader(vertexShader);
     
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragment);
    gl.compileShader(fragmentShader);
    Copy the code
  3. createWebGLProgramobject
    // Add the shader object and link it to the WebGL context object.
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    Copy the code
  4. To enable theWebGLProgramobject
    gl.useProgram(program);
    Copy the code

3. Save the data to the buffer

WebGL’s coordinate system is a right-handed coordinate system.

Data used by WebGL needs to be defined in type arrays.

  1. Use type arrays to define vertices (defaultFloat32ArrayTyped array)
    const points = new Float32Array([-1, -1.0.1.1, -1,]);Copy the code
  2. Writes the defined data to the WebGL cache

    A, create a cache object; B, bind to the current operation object; C, write the current data to the cache object.

    const bufferId = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
    gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
    Copy the code

4. Read the buffer data to the GPU

const vPosition = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false.0.0);
gl.enableVertexAttribArray(vPosition);
Copy the code

5. Execute the shader program to complete the drawing

gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);
Copy the code

No matter how many pixels there are in the graph, the shader program will be executed simultaneously on the GPU.

The role of vertex shaders

  1. throughgl_PositionSet vertices;
    // Reduce the perimeter of the triangle by half
    const vertex = ` attribute vec2 position; Void main() {gl_PointSize = 1.0; Gl_Position = vec4(position * 0.5, 1.0, 1.0); } `;
    Copy the code
  2. By definingvaryingVariable to pass data to the chip shader.
    // Pass the data to the chip shader via the variable VARYING
    const vertex = ` attribute vec2 position; varying vec3 color; Void main() {gl_PointSize = 1.0; Color = vec3(0.5 + position *0.5, 0.0); Gl_Position = vec4(position * 0.5, 1.0, 1.0); } `;
    Copy the code

4. WebGL drawing procedure diagram

Five, the other

For exchange learning only. demo

<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Triangles in WebGL</title>
</head>

<body>
  <canvas></canvas>

  <script>
    // 1. Create WebGL context
    const canvas = document.querySelector('canvas');
    const gl = canvas.getContext('webgl');

    // 2. Create a WebGL program: a WebGLProgram object that gives the GPU the program that eventually runs the shader.
    // Vertex shader: is responsible for processing the vertex information of the graph.
    const vertex = ` attribute vec2 position; varying vec3 color; Void main() {gl_PointSize = 1.0; // Linear interpolation: let the color of the pixels gradient evenly. Color = vec3(0.5 + position * 0.5, 0.0); Gl_Position = vec4(position * 0.5, 1.0, 1.0); } `;
    // Create a shader object
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertex);
    gl.compileShader(vertexShader);

    // Pixel shader: is responsible for processing the pixel information of the graph.
    const fragment = ` precision mediump float; varying vec3 color; Void main() {// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); Gl_FragColor = vec4 (color, 1.0); } `;
    // Create a shader object
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragment);
    gl.compileShader(fragmentShader);

    // Create the WebGLProgram object: Add the Shader object and link it to the WebGL context object.
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);

    // Enable the WebGLProgram object
    gl.useProgram(program);

    // 3. Save the data to the buffer
    // Define vertices with arrays of type (default Float32Array typed array)
    const points = new Float32Array([-1, -1.0.1.1, -1,]);// Write the defined data to the WebGL cache: Create a cache object "bind to the current operation object" to write the current data to the cache object.
    const bufferId = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
    gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);

    // 4. Read buffer data to GPU: Get position variable address in vertex shader "set variable length and type" activate variable.
    const vPosition = gl.getAttribLocation(program, 'position');
    gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false.0.0);
    gl.enableVertexAttribArray(vPosition);

    // 5. Execute the shader program to complete the drawing
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);
  </script>
</body>

</html>
Copy the code