1. An overview of the

In the last tutorial, WebGL Easy Tutorial part 1: The First Simple Example, I got a basic idea of the programmable rendering pipeline in WebGL through a drawing point example. In the previous example of drawing a point, the position of the point, the size of the point, the color of the point, are all fixed in the shader, such a program is not scalable.

For example, IF I want to draw a terrain map (DEM), usually the terrain data is stored in the terrain file. After being loaded by the program, the data information is first read into the memory, and then transferred to the video memory, and finally drawn by the video card. The rendering pipeline is flexible because it can pass data to the shader that does the drawing.

2. Example: Draw a point (improved version)

Hellopoint1.js improves on the drawing point example in the previous article. The improved code for helloPoint1.js looks like this:

// Vertex shader program
var VSHADER_SOURCE =
  'attribute vec4 a_Position; \n' + // attribute variable
  'void main() {\n' +
  '  gl_Position = a_Position;\n' + // Set the vertex coordinates of the point
  'gl_PointSize = 10.0; \n' +                    // Set the point size
  '}\n';

// Chip shader program
var FSHADER_SOURCE =
  'precision mediump float; \n' +
  'uniform vec4 u_FragColor; \n' +  / / uniform number of variations
  'void main() {\n' +
  '  gl_FragColor = u_FragColor;\n' + // Set the point color
  '}\n';

function main() {
  // Get the 
      
        element
      
  var canvas = document.getElementById('webgl');

  // Get the WebGL rendering context
  var gl = getWebGLContext(canvas);
  if(! gl) {console.log('Failed to get the rendering context for WebGL');
    return;
  }

  // Initialize the shader
  if(! initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log('Failed to intialize shaders.');
    return;
  }

  // Get the location where the attribute variable is stored
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position');
    return;
  }

  // Pass the vertex position to the attribute variable
  gl.vertexAttrib3f(a_Position, 0.5.0.5.0.0);

  // Get the storage address of the u_FragColor variable
  var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
  if(! u_FragColor) {console.log('Failed to get the storage location of u_FragColor');
    return;
  }

  // Pass the dot's color into the u_FragColor variable
  gl.uniform4f(u_FragColor, 0.0.0.8.0.0.1.0);

  // specify to clear the color of 
      
  gl.clearColor(0.0.0.0.0.0.1.0);

  / / to empty < canvas >
  gl.clear(gl.COLOR_BUFFER_BIT);

  // Draw a point
  gl.drawArrays(gl.POINTS, 0.1);
}
Copy the code

1) attribute variables

In the vertex shader, you can see that the global a_Position variable of an attribute is declared and assigned to gl_Position:

// Vertex shader program
var VSHADER_SOURCE =
  'attribute vec4 a_Position; \n' + // attribute variable
  'void main() {\n' +
  '  gl_Position = a_Position;\n' + // Set the vertex coordinates of the point
  'gl_PointSize = 10.0; \n' +                    // Set the point size
  '}\n';
Copy the code

Attribute is one of three variable declarations in GLSL that represent vertex-related data and can only be used in vertex shaders. This variable stores data that is transferred into the vertex shader from outside.

After you define the attribute variable in the Shader, you need to interact with the shader through JS. The method getAttribLocation () to obtain the storage address of attribute variables can be obtained through the rendering context variable GL of WebGL, which is defined as follows:

This function gets the location of the attribute variable in the shader:

  // Get the location where the attribute variable is stored
  var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position');
    return;
  }
Copy the code

Once you get the address, you can pass data to the attribute variable. Pass the value to the shader by using the gl.vertexattrib3f () function. This passes the position of the point you want to draw to the vertex shader.

  // Pass the vertex position to the attribute variable
  gl.vertexAttrib3f(a_Position, 0.5.0.5.0.0);
Copy the code

Its function is defined as follows:

Note that this function has a family of functions, all named after the underlying function name + the number of arguments + the type of arguments, to handle the transfer of different data. Check out the WebGL API for details.

2) uniform variable

Similarly, in the fragment shader, we declare a global uniform variable u_FragColor and assign it to gl_FragColor:

// Chip shader program
var FSHADER_SOURCE =
  'precision mediump float; \n' +
  'uniform vec4 u_FragColor; \n' +  / / uniform number of variations
  'void main() {\n' +
  '  gl_FragColor = u_FragColor;\n' + // Set the point color
  '}\n';
Copy the code

Uniform is another GLSL variable declaration that represents consistent (unchanging) data transmitted by JavaScript programs to vertex shaders and fragment shaders; This variable can be used in vertex shaders as well as chip shaders.

Like an attribute variable, a uniform variable gets its address and then passes a value to it. Here we pass the color we want to draw to the slice shader:

// Get the storage address of the u_FragColor variable
  var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
  if(! u_FragColor) {console.log('Failed to get the storage location of u_FragColor');
    return;
  }

  // Pass the dot's color into the u_FragColor variable
  gl.uniform4f(u_FragColor, 0.0.0.8.0.0.1.0);
Copy the code

As you can see, the Uniform variable gets the address using the gl.getUniformLocation () function, and the gl.Uniform4f () variable sends data. Their functions are defined as follows:



3) the varying variables

In addition to the attribute and UNIFORM variables, there is also a variable varying, which represents variables that flow from the vertex shader to the chip shader. We’ll talk about that later. The following is how data is transferred to the shader:

Results 3.

Open helloPoint1.html again and the following output is displayed:

You can see the position of the dots change and the color changes from red to green. Position and color information is no longer hard-coded in shaders, but imported from outside.

4. Reference

Some of the original code and illustrations come from the WebGL Programming Guide. Code and data addresses

The original link