webgl

  • Webgl needs canvas
  • MDN link
Webgl coordinate system
  • Webgl is 3d, so it uses a 3D coordinate system (Cartesian coordinate system) with x, Y and Z axes
  • The x axis horizontalFrom left to right,The y axis verticalFrom bottom to top,The Z axis is vertically tilted, from top left to bottom right, the three-axis intersection is the origin
  • The maximum value is 1.0, the minimum value is -1.0, the part beyond is not displayed, the type is float, where the z-axis controls the depth
  • Webgl coordinate system is different from Canvas coordinate system, the former needs to be mapped to the latter, and the mapping is as follows:

canvas

  • The canvas
  • Create a canvas tag using the canvas tag
  • Js gets, and then uses getContext to get the context
  • Use the API on the context object to draw

getContext

  • details
  • Get context
  • Two parameters (contextType contextAttributes)
  • ContextType is a string
    • '2d'Create a 2D context object
    • 'webgl'Create a WebGL context object (3D)
    • 'bitmaprenderer'Create the context in which to place the image
  • ContextAttributes is an optional parameter of type Object
  • Return value: Normally returns a context object,Return null on failure
  • Features: The content written inside the tag is displayed only when the browser is not compatible with canvas
  • The origin of the Canvas coordinate system is in the upper left corner
  • Only one type of context can exist in the same scope, otherwise an error will be reported
let canvas = document.querySelector("#canvas");
let ctx = canvas.getContext("2d");
Copy the code

2 d context

Commonly used attributes
  • fillStyleSet the color,
    • The value is string and stored in the cache
Commonly used method
  • fillRectSet the rectangle whose color is the most recent fillStyle
    • Four values, distance to the left, distance above the distance, width, height, type number

Gl Context (3D)

Commonly used attributes
Commonly used method
  • clearColorSet clear color
    • Four values: all of float, rGBA
  • clearRemove the canvas
    • A parameter,(gl is the context of GL, and other variables can be used)
      • Gl.color_buffer_bit Specifies the depth buffer
      • Gl.depth_buffer_bit Specifies the color cache
      • Gl.stencil_buffer_bit Specifies the template buffer
    • Returned value: None
    • If the clear color is not set earlier, the default is white
  • drawArraysDraw a graph,link
    • No return value
    • Three parameters (mode, first, count)
      • Mode specifies how to draw and receive constant symbols, as follows:
        • Gl. POINTS Draws a series of POINTS
        • Gl. LINES Draws a series of individual line segments. Every two points serve as endpoints, and line segments are not connected.
        • Gl.line_strip Draws a line. That is, draw a series of line segments with the top point connecting the next.
        • Gl.line_loop Draws a coil. That is, draw a series of line segments, with the top point joining the next, and the last point joining the first point.
        • Use gl.TRIANGLES to draw a series of TRIANGLES. Every three points are the vertices.
        • Gl. TRIANGLE_STRIP Draws a triangle strip
        • Gl. TRIANGLE_FAN Draws a triangular fan
        • Note: If mode is not one of these values, gl.INVALID_ENUM will be raised.
      • first
        • The type is an integer that specifies the point from which to draw.
        • Note: A negative value throws a gl.INVALID_VALUE exception
      • count
        • An integer that specifies how many vertices to draw. (In fact, the vertex shader is executed count times when this method is called.)
  • getAttribLocationObtain the attribute variable storage address
    • Two parameters
      • Shaders that have been created (program objects containing vertex shaders and slice shaders)
      • Attribute The name of the declared variable (type string)
    • The return value:
      • If the value is greater than or equal to 0, it indicates the storage address of the variable
      • Less than 0 indicates that the variable does not exist or is named with a gl_ or webgl_ prefix
  • vertexAttrib3fThe vertex position is transferred to the attribute variable, which is called assignment
    • Four parameters
      • The first argument is the location of the obtained attribute variable. The last three are coordinate positions (x,y,z)(float type).
      • It is said that it is best to use four homogeneous coordinates to represent three dimensions, but here three values are used, so the fourth value will be represented as 1.0 by default
  • vertexAttrib4fThe fifth parameter is the w coordinate. In fact, there are not only 4f, but also 2f and 1f. The number of f means that you need to pass several coordinates

shader

  • CDN links
  • There are two types, vertex shaders and slice shaders
  • In common:
    • Both are stored as strings and then used by calling methods
    • The contents of the string must have a main function, and do not give main a custom argument, and the void before main means that it can not return a value
    • And internal functions need to be placed inside some specification content, which is analyzed below

Vertex shader

  • A vertex that describes the position of a vertex can be understood as each top
  • Vertex shaders need to convert vertex coordinates throughgl_PositionSave the processed vertices (representing vertex positions),A type of vec4, this variable must be written
  • The gl_PointSize variable is an optional variable of type float and represents the point size in pixels, which defaults to 1.0 if not written

Fragment shader (fragment shader)

  • After the vertex shader processing is complete, draw the colors and textures
  • A pixel is a pixel displayed on the screen, which can be interpreted as containing the pixel’s position, color, and other information
  • Copy the color of the dot togl_FragColorVariable, which controls the final display color of this pixel on the display,Must want to writeVec4, also known as RGBA color
Vec4 method
  • There are four arguments, all floating point
  • Function: Returns a VEC4 object
  • Be careful (always confused): This method only handles four parameters, not only coordinates, it can also handle RGBA colors
Homogeneous coordinates
  • Consists of four parameters, (x,y,z,w), which are equivalent to three dimensional coordinates (x/w,y/w,z/w).
  • becauseThe homogeneous coordinates are four dimensions, and its characteristic is that if w is 1.0, it is equivalent to three-dimensional, so it is often used to represent the three-dimensional coordinates of vertices (benefit: improved accuracy).
  • Note :0<= w <=1.0
Storage qualifier
  • There are two types of storage qualifiers: attribute and Uniform, which declare variables
  • Declaration method:Store the qualifier type variable name
  • In the shader, we need to pass location information from JS to vertex shaders. There are two ways to do this: Attribute variables and uniform variables. Which variable is used depends on the data being transferred
The attribute variables
  • The attribute variable transmits data related to vertices
  • Use steps:
    • What attribute variable is in the vertex shader
    • Assign the attribute variable to the gl_Position variable
    • Transfer data to the attribute variable.
  • Example:
  // Slice shaders are used in the same way as vertex shaders
   const vsSource = ` attribute vec4 aVertexPosition; void main() { gl_Position = aVertexPosition; } `;
Copy the code
Uniform variable
  • Uniform variables transfer data that is the same for all vertices (or independent of vertices)
Demo (some methods not yet understood)
<! DOCTYPEhtml>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        width: 100vw;
        height: 100vh;
      }
    </style>
  </head>

  <body>
    <canvas id="canvas">Are not compatible</canvas>
  </body>
</html>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/gl-matrix-min.js"></script>
<script>
  // Mat4 is used in the following, because it depends on the matrix library, and the matrix library has been updated to put mat4 on the glMatrix, so we manually save it globally
  const mat4 = glMatrix.mat4;
  const canvas = document.querySelector("#canvas");
  canvas.width = document.body.clientWidth;
  canvas.height = document.body.clientHeight;
  const gl = canvas.getContext("webgl");
</script>
<script>
  // Vertex shader
  const vsSource = ` attribute vec4 aVertexPosition; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; void main() { gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; } `;
  // Chip shader
  // The veC method accepts four values, which can be called the homogeneous coordinate is four dimensional, and is widely used in 3d graphics systems. If the last value is 1.0 then the first three parameters are the coordinate points
  const fsSource = Void main() {gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } `;
  // Create a shader of the specified type, upload the source code, and compile it
  function loadShader(gl, type, source) {
    // Create a shader
    const shader = gl.createShader(type);
    // Send the source code to the shader
    gl.shaderSource(shader, source);
    // The shader gets the source code and starts compiling
    gl.compileShader(shader);
    // Call getShaderParameter, specifying the shader and the value to check, gl.pile_status. If an error is returned, the compilation failed
    if(! gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {// If the compile fails, get the log with getShaderInfoLog and print it
      alert(
        "An error occurred compiling the shaders: " +
          gl.getShaderInfoLog(shader)
      );
      // Delete the shader using deleteShader after output, and return null
      gl.deleteShader(shader);
      return null;
    }
    // The compiled shader is returned
    return shader;
  }
  // Initialize the shader program so that WebGL knows how to draw our data
  function initShaderProgram(gl, vsSource, fsSource) {
    const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
    const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
    // Create a shader program
    const shaderProgram = gl.createProgram();
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);
    // Failed to create, alert
    if(! gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Unable to initialize the shader program: " +
          gl.getProgramInfoLog(shaderProgram)
      );
      return null;
    }
    return shaderProgram;
  }
  const shaderProgram = initShaderProgram(gl, vsSource, fsSource);

  //
  const programInfo = {
    program: shaderProgram,
    attribLocations: {
      vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),},uniformLocations: {
      projectionMatrix: gl.getUniformLocation(
        shaderProgram,
        "uProjectionMatrix"
      ),
      modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"),}};// Before drawing, create buffer, store vertices, and return
  function initBuffers(gl) {
    // Get the buffer object with createBuffer
    const positionBuffer = gl.createBuffer();
    // Bind the context with bindBuffer
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    // Create an array of vertices (float type)
    var vertices = [
      1.0.1.0.0.0, -1.0.1.0.0.0.1.0, -1.0.0.0, -1.0, -1.0.0.0,];// Create vertex objects with bufferData
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

    return {
      position: positionBuffer,
    };
  }
  / / first introduce the tool library at https://cdn.jsdelivr.net/npm/[email protected]/gl-matrix-min.js
  / / reference https://github.com/mdn/sprints/issues/2817 mat4 error problem
  function drawScene(gl, programInfo, buffers) {
    // Set the clear color
    gl.clearColor(0.0.0.0.0.0.1.0);
    // Clear the depth buffer
    / / article: https://blog.csdn.net/dizia/article/details/80156765
    gl.clearDepth(1.0);
    // Enable deep testing
    gl.enable(gl.DEPTH_TEST);
    // mask the depth buffer
    gl.depthFunc(gl.LEQUAL);
    // Clear the canvas
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    // Calculate the Angle
    const fieldOfView = (45 * Math.PI) / 180; // in radians
    const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const zNear = 0.1;
    const zFar = 100.0;
    const projectionMatrix = mat4.create();
    mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar);

    const modelViewMatrix = mat4.create();
    mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0.0.0, -6.0]);

    {
      const numComponents = 3;
      const type = gl.FLOAT;
      const normalize = false;
      const stride = 0;
      const offset = 0;
      gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
      gl.vertexAttribPointer(
        programInfo.attribLocations.vertexPosition,
        numComponents,
        type,
        normalize,
        stride,
        offset
      );
      gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
    }

    gl.useProgram(programInfo.program);

    gl.uniformMatrix4fv(
      programInfo.uniformLocations.projectionMatrix,
      false,
      projectionMatrix
    );
    gl.uniformMatrix4fv(
      programInfo.uniformLocations.modelViewMatrix,
      false,
      modelViewMatrix
    );

    {
      const offset = 0;
      const vertexCount = 4;
      gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);
    }
  }
  drawScene(gl, programInfo, initBuffers(gl));
</script>
Copy the code

》》》》》47 pages