1.demo effect
As shown in the figure above, this demo has the same effect as the previous one, but there is a difference. When we define the vertex shader, the value of a_Position is hard-coded. What should we do when we want to dynamically pass the value from js to the shader? ? First, get a through gl.getAttribLocation()_ Position, and then through GL Vertexattrib3f() method to shader variable a_Position can pass the value
2.1 Shader attribute naming convention
The attribute variable is a GLSL ES variable that is used to transfer data to the vertex shader from the outside. Next, let's introduce the declaration of the attribute variable. The declaration of the variable has certain format requirements: <storage qualifier> <type> <variable name>
- attribute variables must be declared as global variables
- All attribute variables preferably start with a_ prefix, so that the type can be distinguished from the variable name
2.2gl.getAttribLocation()
The attribute variable we declare in the shader program will have its own storage address. Through this address, we can assign it in the external program. The gl.getAttribLocation() method is a powerful tool to help us obtain this address.
Function: get the name in the specified shader attribute variable storage address -------------------------------------------------------------------------- Example of calling: gl.getAttribLocation(program, name) -------------------------------------------------------------------------- parameter program Specifies a shader program object containing vertex shaders and fragment shaders name Specify the storage address of which you want to get attribute variable name -------------------------------------------------------------------------- return value >=0 attribute variable storage address -1 The specified variable name does not exist, or the name has gl_or webgl_prefix -------------------------------------------------------------------------- Error INVALID_OPERATION Program object failed to connect successfully INVALID_VALUE name The length of the parameter is greater than the maximum length, the default is 256 bytes
sample code
//Get the storage address of the shader attribute variable a_Position const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
2.3 gl.vertexAttrib3f() method
The gl.getAttribLocation() method helps us get the address of the shader variable, then we need to call out the gl.vertexAttrib3f() method, through which we can assign the value we want to the shader in the JavaScript program attribute variable in
Function: convert data v0, v1, v2 passed to by location the shader specified by the parameter attribute variable ------------------------------------------------------------------------------ Example of calling: gl.vertexAttrib3f(location, v0, v1, v2) ------------------------------------------------------------------------------ parameter location Specifies the one to be modified attribute variable storage address v0 specify padding attribute the value of the first component of the variable v1 specify padding attribute the value of the second component of the variable v2 specify padding attribute the value of the third component of the variable ------------------------------------------------------------------------------ return value none ------------------------------------------------------------------------------ Error INVALID_OPERATION no current program object INVALID_VALUE location greater or equal to attribute The maximum data of the variable, default is 8
sample code
//Pass a value to the shader attribute variable a_Position gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)
2.4 Similar functions of gl.vertexAttrib3f()
The gl.vertexAttrib3f() method is one of a family of functions whose job is to pass values from a JavaScript program to an attribute variable in a vertex shader
Function: convert data[1~4 components]passed to by location the shader specified by the parameter attribute variable ------------------------------------------------------------------------------ gl.vertexAttrib1f(location, v0) gl.vertexAttrib2f(location, v0, v1) gl.vertexAttrib3f(location, v0, v1, v2) gl.vertexAttrib4f(location, v0, v1, v2, v3) ------------------------------------------------------------------------------ parameter location Specifies the one to be modified attribute variable storage address v0,v1,v2,v3 designated to transmit to attribute the values of the four components of the variable ------------------------------------------------------------------------------ return value none ------------------------------------------------------------------------------ Error INVALID_VALUE location greater or equal to attribute The maximum data of the variable, default is 8
You can also use the vector versions of these methods, whose names end in "v". And accepts a typed array as a parameter, the number in the function name represents the number of elements in the array
const position = new Float32Array([1.0,2.0,3.0,1.0]); gl.vertexAttrib4fv(position);
2.5 Introduction to the use process of attribute variables
- Declare attribute variable in shader
- Get the storage address of the attribute variable in the JavaScript program
- Pass the value to the attribute variable in the shader through the storage address of the attribute variable
3.demo code
// vertex shader program var VSHADER_SOURCE = `attribute vec4 a_Position; attribute float a_Size; void main() { gl_Position = a_Position; gl_PointSize = a_Size; }`; // Fragment shader program var FSHADER_SOURCE = `void main() { gl_FragColor = vec4(1, 0, 0, 1); }`; const main = () => { let count = 0.1 //Get the drawing dom const canvas = document.getElementById('webgl'); //get canvas context const gl = canvas.getContext('webgl'); //Initialize shader if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { return console.log('Failed to initialize shaders.') } const aPosition = gl.getAttribLocation(gl.program, 'a_Position'); const aSize = gl.getAttribLocation(gl.program, 'a_Size') console.log('aPosition', aPosition); gl.vertexAttrib3f(aPosition, 0.0, 0.3, 0.0) // setInterval(() => { // count += 0.1 // console.log(count); // gl.clear(gl.COLOR_BUFFER_BIT); // gl.vertexAttrib3f(aPosition, 0.0, count, 0.0); // gl.drawArrays(gl.POINTS, 0, 1); // gl.vertexAttrib3f(aPosition, 0.2, count, 0.0); // // draw a point // gl.drawArrays(gl.POINTS, 0, 1); // }, 1000) gl.vertexAttrib3f(aPosition, 0.0, 0.2, 0.0); gl.vertexAttrib1f(aSize, 15); //Set the background color of the canvas gl.clearColor(0.0, 0.0, 0.0, 1.0); //empty canvas gl.clear(gl.COLOR_BUFFER_BIT); //draw a point gl.drawArrays(gl.POINTS, 0, 1); } main()