WebGL can draw three basic shapes: points, lines, and triangles. All other shapes are assembled from these three basic shapes.

The following examples use the GLSL knowledge.

Shader code

  • Gl_Position: built-in variable to set vertex coordinates.
  • Gl_PointSize: Built-in variable used to set vertex size.
  • Gl_FragColor: Built-in variable used to set pixel color.
  • Gl_FragCoord: Built-in variable, slice coordinate, unit pixel
  • Precision: Precision setting qualifier. After precision is set with this qualifier, the precision will be used for all subsequent data types unless set separately.
  • Vec2:2-dimensional vector.
  • Vec4: a 4-dimensional vector.
  • Vector operations
    • Vec2 (x, y) * 2.0 = vec(x * 2.0, y * 2.0).
    • Vec2 * vec2: vec2(x1, y1) * vec2(x2, y2) = vec2(x1 * x2, y1 * y2).
  • Attribute: Declare vertex – related data in a vertex shader.
  • Uniform: Declare non-vertex data (such as light position data, direction data, matrix data) in shaders.
  • Distance: Computes the distance between vertices.
  • Discard: Discard a slice.

GLSL language in JS program – how to connect shader program

  • CreateShader: Creates a shader object
  • ShaderSource: provides shaderSource code
  • CompileShader: Compiles shader objects
  • CreateProgram: Create shader program
  • AttachShader: Binds the shader object
  • LinkProgram: link shader program
  • UseProgram: Enables the shader program

How do YOU pass data to shaders in JS

  • GetAttribLocation: Finds the shaderattributeVariable address.
  • GetUniformLocation: Finds the shaderuniformVariable address.
  • VertexAttrib2f:attributeThe variable passes two floating point numbers.
  • Uniform4f:uniformThe variable passes four floating point numbers.

Graphing function

  • DrawArrays (type,start,count): Draw with the specified primitives.typeThere are mainly the following types.startSpecifies the point from which to draw.countSpecifies how many points will be used to draw.
    • Gl. POINTS: Draws a series of POINTS.
    • 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.
    • Gl.lines: Draws a series of individual line segments. Every two points serve as endpoints, and line segments are not connected.
    • Gl. TRIANGLE_STRIP: Draw a triangle strip.
    • Gl. TRIANGLE_FAN: Draw a triangle fan.
    • TRIANGLES: Using a series of TRIANGLES. Every three points are the vertices.

1. Draw square point graph

<canvas id="canvas" width="500" height="500"></canvas>
Copy the code

Here is the shader language. It is usually written as a single js code. Of course, it can also be written as a string in JS code. The center of the square is 0.5,0.5, the upper left corner is the origin of the coordinates, and the lower right corner is 1.0,1.0,

  • Vertex shader

<script type="shader-source" id="vertexShader">
void main(){
    // The position of the vertex
  	gl_Position = vec4(0.0.0.0.0.0.1.0);
    // The pixel size of the vertex
  	gl_PointSize = 40.0;
}
</script>
Copy the code
  • Chip shader
<script type="shader-source" id="fragmentShader">
// The data type is low precision floating point
precision lowp float;
void main(){
    // Sets the color of the chip shader
    gl_FragColor = vec4(1.0.0.0.0.0.1.0);
}
</script>
Copy the code
  • javascriptCode section
/ / get the canvas
let canvas = document.getElementById('canvas');
// Get the drawing context
let gl = canvas.getContext('webgl');
// Create a shader program
initShader(gl);
// Set the clear color to black.
gl.clearColor(0.0.0.1.0);
/ / clear screen
gl.clear(gl.COLOR_BUFFER_BIT);
// Draw a point.
gl.drawArrays(gl.POINTS, 0.1);
// Declare the initialization shader function
function initShader(gl){
    // Create a fixed-point shader
    const vertexShaderSource = document.querySelector('#vertexShader').innerText;
    // Create a slice shader
    const fragmentShaderSource = document.querySelector('#fragmentShader').innerText;
    // Create a vertex shader object
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    // Create a slice shader object
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    // Introduce vertex, slice shader source code
    gl.shaderSource(vertexShader,vertexShaderSource);
    gl.shaderSource(fragmentShader,fragmentShaderSource);
    // Build vertex and slice shaders
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);

    // Create program object program
    const program = gl.createProgram();
    // Attach vertex shaders and slice shaders to program
    gl.attachShader(program,vertexShader);
    gl.attachShader(program,fragmentShader);
    / / link to the program
    gl.linkProgram(program);
    / / using the program
    gl.useProgram(program);
    // Return program object
    return program;
}
Copy the code

2. Draw circular point graph

The dots are drawn using two built-in functions distance and discard. Distance is used to calculate the distance between two vertex coordinates. The discard function is used to discard unwanted slices.

  • Vertex shader

<script type="shader-source" id="vertexShader">
void main(){
    // The position of the vertex
  	gl_Position = vec4(0.0.0.0.0.0.1.0);
    // The pixel size of the vertex
  	gl_PointSize = 40.0;
}
</script>
Copy the code
  • Chip shader
<script type="shader-source" id="fragmentShader">
// The data type is low precision floating point
precision lowp float;
void main(){
    //gl_PointCoord is a built-in variable that indicates that the maximum value of gl_PointCoord is (1.0,1.0)
    //gl_FragColor is also a built-in variable that represents the color value of the pixel corresponding to the vertex coordinates
    // Calculate the distance between the vertex coordinates and the specified point (0.5,0.5),
    float r = distance(gl_PointCoord, vec2(0.5.0.5));
    // Set the chip according to the distance
    if(r < 0.5) {// The radius of the square area is less than 0.5 from the geometric center, and the pixel color is set to red
        gl_FragColor = vec4(1.0.0.0.0.0.1.0);
    }else {
        // Drop the segment clipping if the radius of the square area is greater than or equal to 0.5 from the geometric center:
        discard;
    }
}
</script>
Copy the code
  • javascriptCode section

This part of the code is the same as drawing the square point graph.

Here is a comparison of images cropped to a circle using gl_pointCoord and an uncropped square.

3. Dynamically draw points

Add points dynamically by user’s click.

  • Vertex shader

<script type="shader-source" id="vertexShader">
// Float is set to medium precision
precision mediump float;
// Accept the coordinates (X, Y) of the point passed by JavaScript.
attribute vec2 a_Position;
// Accept the canvas size.
attribute vec2 a_Screen_Size;
void main(){
    // Convert the canvas coordinate value to the range of [-1.0, 1.0].
    vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0;
    // Canvas's Y coordinate is opposite to the device coordinate.
    position = position * vec2(1.0, -1.0);
    // Final vertex coordinates.
    gl_Position = vec4(position, 0.0.1.0);
    // The size of the dot.
    gl_PointSize = 10.0;
}
</script>
Copy the code
  • Chip shader
<script type="shader-source" id="fragmentShader">
// Float is set to medium precision
precision mediump float;
// a global variable to receive colors from JavaScript.
uniform vec4 u_Color;
void main(){
    // Process the colors to the GLSL range [0, 1].
    vec4 color = u_Color / vec4(255.255.255.1);
    gl_FragColor = color;
}
</script>
Copy the code
  • javascriptCode section
/ / get the canvas
let canvas = document.getElementById('canvas');
// Get the drawing context
let gl = canvas.getContext('webgl');
// Create a shader program
let program = initShader(gl);
// Gets the position of the variable a_Position in the vertex shader.
let a_Position = gl.getAttribLocation(program, 'a_Position');
// Gets the position of the variable a_Screen_Size in the vertex shader.
let a_Screen_Size = gl.getAttribLocation(program, 'a_Screen_Size');

// Get the position of the variable u_Color in the slice shader.
let u_Color = gl.getUniformLocation(program, 'u_Color');
// Pass the canvas size information to the vertex shader's a_Screen_Size.
gl.vertexAttrib2f(a_Screen_Size, canvas.width, canvas.height);
// Declare the initialization shader function
function initShader(gl){
    // Create a fixed-point shader
    const vertexShaderSource = document.querySelector('#vertexShader').innerText;
    // Create a slice shader
    const fragmentShaderSource = document.querySelector('#fragmentShader').innerText;
    // Create a vertex shader object
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    // Create a slice shader object
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    // Introduce vertex, slice shader source code
    gl.shaderSource(vertexShader,vertexShaderSource);
    gl.shaderSource(fragmentShader,fragmentShaderSource);
    // Build vertex and slice shaders
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);

    // Create program object program
    const program = gl.createProgram();
    // Attach vertex shaders and slice shaders to program
    gl.attachShader(program,vertexShader);
    gl.attachShader(program,fragmentShader);
    / / link to the program
    gl.linkProgram(program);
    / / using the program
    gl.useProgram(program);
    // Return program object
    return program;
}

// The container that stores the vertex information of the area
let points = [];

canvas.addEventListener('click'.e= > {
    let x = e.pageX;
    let y = e.pageY;
    let color = randomColor();
    // Store the coordinates and colors of the new point.
    points.push({ x: x, y: y, color: color })
    render(gl);
})
// Draw the function
function render(gl) {
    // Clear the screen
    gl.clear(gl.COLOR_BUFFER_BIT);
    for (let i = 0; i < points.length; i++) {
        let color = points[i].color;
        // Pass color information to the slice shader
        gl.uniform4f(u_Color, color.r, color.g, color.b, color.a);
        Pass coordinate information to the vertex shader.
        gl.vertexAttrib2f(a_Position, points[i].x, points[i].y);
        // Draw points.
        gl.drawArrays(gl.POINTS, 0.1); }}var random = Math.random;
function randomColor() {
    return {
        r: random() * 255.g: random() * 255.b: random() * 255.a: random() * 1
    };
}
// Set the screen clear color to black.
gl.clearColor(0.0.0.1.0);
/ / to draw
render(gl);
Copy the code

4, gradient

  • Vertex shader
<script type="shader-source" id="vertexShader">
void main(){
    gl_Position = vec4(0.0.0.0.0.0.1.0);
    gl_PointSize = 100.0;
}
</script>
Copy the code
  • Chip shader
<script type="shader-source" id="fragmentShader">
void main(){
    // Set the pixel value of the slice according to the x coordinate of the slice
    // The element is gradually changed along the x direction
    gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0.0.0.0.0.1.0);
}
</script>
Copy the code
  • javascriptCode section This section of code is the same as the code used to draw the square point graph.

5. Color partitioning

  • Vertex shader
<script type="shader-source" id="vertexShader">
void main(){
    gl_Position = vec4(0.0.0.0.0.0.1.0);
    gl_PointSize = 200.0;
}
</script>
Copy the code
  • Chip shader
<script type="shader-source" id="fragmentShader">
void main(){
    // Set the pixel value of the slice according to the x coordinate of the slice
    if(gl_FragCoord.x < 200.0) {// Defaults to the original canvas color
    }
    else if (gl_FragCoord.x < 250.0) {
        // canvas set the pixel value between [0,300) on the canvas
        gl_FragColor = vec4(1.0.0.0.0.0.1.0);
    } else if (gl_FragCoord.x <= 300.0) {

        // canvas Pixel values between (300,400) are set to green
        gl_FragColor = vec4(0.0.1.0.0.0.1.0);
    } else {
        // Canvas Pixel values between (400,500) are set to blue
        gl_FragColor = vec4(0.0.0.0.1.0.1.0);
    }
}
</script>
Copy the code
  • javascriptCode section This section of code is the same as the code used to draw the square point graph.

reference

WebGL Zero Basic Tutorial (Guo Longbang); Introduction to WebGL and practice