Vertex shader calculates vertex by vertex and receives vertex by vertex information. If we want to specify the color of the surface, we need to define the color to the vertex. For example, if we want to define a triangle as a color, we must have the color of all three vertices as a color.
But you will find that a vertex of a cube will be used in three faces, and defining a color will definitely affect the other side. To solve this problem, we need to create multiple vertices with the same vertex coordinates (although this will cause some redundancy).
In this case, the triangle list, i.e. the sequence of vertex index values, points to a different set of vertices for each face and does not share a vertex with the front surface and the upper surface. In this way, the aforementioned effect can be achieved, and different monochromes can be applied to each surface.
Although this example uses gl.drawElements(), it uses 24 vertices. Using gl.drawArrays() draws 36 vertices. It doesn't seem to save much memory overhead. However, in actual production, it is worthwhile to use gl.drawElements().<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Title</title> <style> body { margin: 0; text-align: center; } #canvas { margin: 0; } </style> </head> <body onload="main()"> <canvas id="canvas" height="800" width="1200"></canvas> </body> <script src="lib/webgl-utils.js"></script> <script src="lib/webgl-debug.js"></script> <script src="lib/cuon-utils.js"></script> <script src="lib/cuon-matrix.js"></script> <script> //Vertex Shader var VSHADER_SOURCE = "" + "attribute vec4 a_Position;\n" + "attribute vec4 a_Color;\n" + "uniform mat4 u_ModelViewMatrix;\n" + "varying vec4 v_Color;\n" + "void main(){" + " gl_Position = u_ModelViewMatrix * a_Position;\n" + " v_Color = a_Color;\n" + "}\n"; //Fragment Shader var FSHADER_SOURCE = "" + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "varying vec4 v_Color;\n" + "void main(){" + " gl_FragColor = v_Color;\n" + "}\n"; //Declare the relevant variables required by js var canvas = document.getElementById("canvas"); var gl = getWebGLContext(canvas); function main() { if (!gl) { console.log("Your browser does not support it WebGL"); return; } //Initialization shader if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { console.log("Unable to initialize shader"); return; } var n = initVertexBuffers(gl); if (n < 0) { console.log("Unable to create buffer"); return; } //Information about setting perspective matrix var u_ModelViewMatrix = gl.getUniformLocation(gl.program, "u_ModelViewMatrix"); if (u_ModelViewMatrix < 0) { console.log("Unable to obtain the storage location of matrix variables"); return; } //Set the background color gl.clearColor(0.0, 0.0, 0.0, 1.0); //Initialization of Entry Scene draw(gl, n, u_ModelViewMatrix); } function draw(gl, n, u_ModelViewMatrix) { //Set up the relevant information of the view matrix (view, line of sight, top direction) var viewMatrix = new Matrix4(); viewMatrix.setLookAt(3,3,7,0,0,0,0,1,0); //Setting up the Relevant Information of Model Matrix var modelMatrix = new Matrix4(); modelMatrix.setRotate(0, 0, 0, 1); //Setting Perspective Projection Matrix var projMatrix = new Matrix4(); projMatrix.setPerspective(30,canvas.width/canvas.height,1,100); //Calculate the model view matrix viewMatrix. multiply (model Matrix) equivalent to u_ViewMatrix * u_Model Matrix in the shader var modeViewMatrix = projMatrix.multiply(viewMatrix.multiply(modelMatrix)); //Pass the attempt matrix to the u_ViewMatrix variable gl.uniformMatrix4fv(u_ModelViewMatrix, false, modeViewMatrix.elements); //Open Hidden Surface Clearance gl.enable(gl.DEPTH_TEST); //Clear the color and depth buffer gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //Drawing Graphics gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0); } function initVertexBuffers(gl) { // Create a cube // v6----- v5 // /| /| // v1------v0| // | | | | // | |v7---|-|v4 // |/ |/ // v2------v3 var vertices = new Float32Array([ // Vertex position coordinate data 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front 1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // v0-v3-v4-v5 right 1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up -1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, // v1-v6-v7-v2 left -1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, // v7-v4-v3-v2 down 1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0 // v4-v7-v6-v5 back ]); var colors = new Float32Array([ // The color of the vertex 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, // v0-v1-v2-v3 front(blue) 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, 0.9, // v0-v3-v4-v5 right(green) 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, // v0-v5-v6-v1 up(red) 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, // v1-v6-v7-v2 left 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, // v7-v4-v3-v2 down 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8 // v4-v7-v6-v5 back ]); var indices = new Uint8Array([ // Drawn Index 0, 1, 2, 0, 2, 3, // front 4, 5, 6, 4, 6, 7, // right 8, 9,10, 8,10,11, // up 12,13,14, 12,14,15, // left 16,17,18, 16,18,19, // down 20,21,22, 20,22,23 // back ]); //Creating Buffer Objects initArrayBuffer(gl,vertices,3,gl.FLOAT,"a_Position"); initArrayBuffer(gl,colors,3,gl.FLOAT,"a_Color"); //Write vertex index data to buffer objects var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW); return indices.length; } function initArrayBuffer(gl,data,num,type,attribute) { //Creating Buffer Objects var buffer = gl.createBuffer(); if (!buffer) { console.log("Buffer object cannot be created"); return -1; } //Binding Buffer Objects and Writing Data gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); //Getting the position of vertex position variable var a_attribue = gl.getAttribLocation(gl.program, attribute); if (a_attribue < 0) { console.log("Storage variable unable to obtain vertex location"); return -1; } //Allocate the vertex data of the location and open it gl.vertexAttribPointer(a_attribue, num, type, false, 0, 0); gl.enableVertexAttribArray(a_attribue); } </script> </html>
In this way, we have achieved the drawing of the same color surface.