[Getting started with WebGL] 15th, color the polygon (specify the vertex color), and webgl Vertex
Note: The article is translated from http://wgld.org/, the original author shanbenya (doxas). If I have additional instructions in the article, I will add [lufy:]. In addition, the research on webgl is not in-depth enough, and some professional words are required, if the translation is incorrect, please correct me.
Running result of this demo
Increase the number of vertex attributes
Last time, I finally drew a triangle, but only drew a pure white polygon.
This time, the color attribute is added to the vertices of the polygon. Basically, we did the same thing as in the previous article, just adding a little bit.
First, as previously repeated, a vertex can contain many types of intelligence (see vertex cache and basics), and each intelligence is called a vertex attribute. In the previous demo, the vertex type only contains the vertex attribute of location intelligence. This time, a color vertex attribute is added.
A vertex attribute must correspond to something. Remember.
The answer is: vertex cache (VBO ). In the previous article, we prepared the VBO used to save the position for rendering. This time we prepared another VBO. At the same time, we sent both the VBO and the VBO of the location intelligence to the vertex shader to color the polygon.
Changes to the coloring er code
Then, let's start with the code of the shadow.
This time, two attribute variables are required. It is to receive the position and color of the vertex, respectively.
> Vertex coloring code
attribute vec3 position;attribute vec4 color;uniform mat4 mvpMatrix;varying vec4 vColor;void main(void){ vColor = color; gl_Position = mvpMatrix * vec4(position, 1.0);}
We can see that two attribute variables are declared together. The position is the same as the previous one, and there is no change. A color is added under it to process the color of the vertex.
The varying variable that does not appear in the previous article also appears this time. The varying variable serves as a bridge between the vertex shader and the fragment shader. Let's take a look at the code in the main function. You only need to assign the color of the vertex in the attribute variable to the varying variable.
After this processing, the vertex attributes in the vertex coloring tool can be passed to the fragment coloring tool. Of course, data can be transmitted to the fragment shader without any processing. This is also one of the advantages of Editable rendering pipelines.
Next, let's look at the fragment shader.
> Part coloring code
precision mediump float;varying vec4 vColor;void main(void){ gl_FragColor = vColor;}
The part coloring tool used in the previous article directly substitutes the color data into gl_FragColor, so the triangle drawn is monochrome. This time, using the varying variable vColor from the vertex coloring tool, the color attribute of the vertex will affect the polygon.
* Although the varying variable with the same name is used in both the vertex and fragment pasters, it is actually two completely different variables.
> Precision of the specified precision
The first line in the fragment coloring tool this time has a strange precision, which is a keyword used to specify the precision of a value, followed by a precision modifier. There are three modifiers. Simply put, the precision is set to upper, middle, lower. In fact, when the decimals used in the variable change (that is, the number of digits of the processed value increases or decreases), the results are not uniform according to the running environment. Lowp: low accuracy Mediump: Medium precision Highp: High Accuracy In the code above, the precision is followed by the mediump float, which means that the float value in the fragment coloring tool is used according to mediump. No matter whether you have made any special processing in the fragment coloring tool, you must first write the precision-related settings. Otherwise, errors may occur when compiling the coloring tool. This is like a magic spell that cannot be escaped.
|
Processing of vertex Cache
After the shadow, it is VBO. Although some content has been added here, the same thing is actually done twice. If you read it carefully, you will understand that there is basically no change in the last time.
> Creating a matrix of vertex data
// Get attributeLocationvar attLocation = new Array (2); attLocation [0] = gl. getAttribLocation (prg, 'position'); attLocation [1] = gl. getAttribLocation (prg, 'color'); // Save the element prime attribute to the Array var attStride = new Array (2); attStride [0] = 3; attStride [1] = 4; // array for storing vertex location intelligence var vertex_position = [0.0, 1.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0]; // array of color intelligence for storing vertices var vertex_color = [1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0];
The last vertex attribute has only one, so the sequence number of the vertex attribute is a pure variable. This time, there are two vertex attributes, so an array is used. The color is composed of four elements, so the length of the color intelligence array is [number of vertices x 4].
After saving the vertex data to the array, the next step is to generate VBO Based on the array. The following is the code.
> Generate VBO Based on the vertex data array
// Generate VBOvar position_vbo = create_vbo (vertex_position); var color_vbo = create_vbo (vertex_color); // VBO binding (location intelligence) gl. bindBuffer (gl. ARRAY_BUFFER, position_vbo); gl. enableVertexAttribArray (attLocation [0]); gl. vertexAttribPointer (attLocation [0], attStride [0], gl. FLOAT, false, 0, 0); // VBO binding (color intelligence) gl. bindBuffer (gl. ARRAY_BUFFER, color_vbo); gl. enableVertexAttribArray (attLocation [1]); gl. vertexAttribPointer (attLocation [1], attStride [1], gl. FLOAT, false, 0, 0 );
After VBO is generated, bind and write data. The location intelligence and color intelligence are the same, so the same processing is repeated twice. Some people may have some ideas here. The processing around VBO can be directly made into a function. It is basically solved to pass the array as a parameter.
Summary
The above is the change point compared with the previous article. The main difference is that the processing around the sprite and VBO changes slightly. If you add other attributes to the vertex, you can follow the same steps and repeat them, in this way, you can add attributes to the vertex freely.
Finally, all the demo code of this article is posted, and the link is also provided at the end. You can refer to it.
Next time, you can use the model transformation matrix to draw multiple models.
> Demo HTML code
> Demo javascript code
Onload = function () {// obtain var c = document from the canvas object. getElementById ('canvas '); c. width = 300; c. height = 300; // obtain var gl = c from the context of webgl. getContext ('webgl ') | c. getContext ('experimental-webgl '); // you can specify the color of the canvas. clearColor (0.0, 0.0, 0.0, 1.0); // sets the depth of gl during canvas initialization. clearDepth (1.0); // initialize gl for canvas. clear (gl. COLOR_BUFFER_BIT | gl. DEPTH_BUFFER_BIT); // generate var v_shader = create_sha for vertex pasters and fragment pasters Der ('vs '); var f_shader = create_shader ('fs'); // generate and connect the program object var prg = create_program (v_shader, f_shader ); // attributeLocation var attLocation = new Array (2); attLocation [0] = gl. getAttribLocation (prg, 'position'); attLocation [1] = gl. getAttribLocation (prg, 'color'); // Save the element prime attribute to the Array var attStride = new Array (2); attStride [0] = 3; attStride [1] = 4; // array that stores vertex location intelligence var vertex_position = [0.0, 1.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0]; // array of color intelligence for storing vertices var vertex_color = [1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0]; // generate VBO var position_vbo = create_vbo (vertex_position); var color_vbo = create_vbo (vertex_color ); // VBO binding (location intelligence) gl. bindBuffer (gl. ARRAY_BUFFER, position_vbo); gl. enableVertexAttribArray (attLocation [0]); gl. vertexAttribPointer (attLocation [0], attStride [0], gl. FLOAT, false, 0, 0); // VBO binding (color intelligence) gl. bindBuffer (gl. ARRAY_BUFFER, color_vbo); gl. enableVertexAttribArray (attLocation [1]); gl. vertexAttribPointer (attLocation [1], attStride [1], gl. FLOAT, false, 0, 0); // use minMatrix. js matrix-related processing // generate var m = new matIV () for matIV objects; // generate and initialize various matrices var mMatrix = m. identity (m. create (); var vMatrix = m. identity (m. create (); var pMatrix = m. identity (m. create (); var mvpMat Rix = m. identity (m. create (); // view transformation coordinate matrix m. lookAt ([0.0, 1.0, 3.0], [0, 0, 0], [0, 1, 0], vMatrix); // projection coordinate transformation matrix m. perspective (90, c. width/c. height, 0.1, 100, pMatrix); // The final coordinate transformation matrix m is obtained. multiply (pMatrix, vMatrix, mvpMatrix); m. multiply (mvpMatrix, mMatrix, mvpMatrix); // obtain var uniLocation = gl for uniformLocation. getUniformLocation (prg, 'mvpmatrix '); // input the coordinate transformation matrix gl to the uniformLocation. uniformMatri X4fv (uniLocation, false, mvpMatrix); // draw the model gl. drawArrays (gl. TRIANGLES, 0, 3); // refresh gl of context. flush (); // generate the colorant function create_shader (id) {// used to save the variable var shader of the colorant; // obtain the specified script tag var scriptElement = document from HTML based on the id. getElementById (id); // if the specified script tag does not exist, if (! ScriptElement) {return;} // identifies the type attribute switch (scriptElement. type) {// case 'x-shader/x-vertex ': shader = gl. createShader (gl. VERTEX_SHADER); break; // case 'x-shader/x-fragment ': shader = gl. createShader (gl. FRAGMENT_SHADER); break; default: return;} // assign the code in the label to the generated sprite gl. shaderSource (shader, scriptElement. text); // compile the gl. compileShader (shader); // checks whether the coloring er has been compiled successfully if (gl. getShaderParameter (shader, gl. COMPILE_STATUS) {// If compilation is successful, return shader;} else {// If compilation fails, the error message alert (gl. getShaderInfoLog (shader);} // function of the program object generation and coloring machine connection function create_program (vs, fs) {// var program = gl generated by the program object. createProgram (); // assign the coloring machine gl to the program object. attachShader (program, vs); gl. attachShader (program, fs); // connect the shader to gl. linkProgram (program); // determines whether the connection of the shadow is successful if (gl. getProgramParameter (program, gl. LINK_STATUS) {// if the program object is successfully set to valid gl. useProgram (program); // return the program object return program;} else {// if it fails, the error message alert (gl. getProgramInfoLog (program);} // generate the VBO function create_vbo (data) {// generate the cache object var vbo = gl. createBuffer (); // bind the cache gl. bindBuffer (gl. ARRAY_BUFFER, vbo); // write data to the cache gl. bufferData (gl. ARRAY_BUFFER, new Float32Array (data), gl. STATIC_DRAW); // sets the bound cache to invalid gl. bindBuffer (gl. ARRAY_BUFFER, null); // return the generated VBO return vbo ;}};
Add a color to the vertex, and then draw a triangle demo.
Http://wgld.org/s/sample_003/
Reprinted Please note: