WebGL編程指南案例解析之3D視圖視區問題
阿新 • • 發佈:2019-04-11
fill form color point front attribute buffer sha vertex
var VSHADER_SOURCE = ‘attribute vec4 a_Position;\n‘ + ‘attribute vec4 a_Color;\n‘ + ‘uniform mat4 u_MvpMatrix;\n‘ + ‘varying vec4 v_Color;\n‘ + ‘void main() {\n‘ + ‘ gl_Position = u_MvpMatrix * a_Position;\n‘ + ‘ v_Color = a_Color;\n‘ + ‘}\n‘; // Fragment shader program varFSHADER_SOURCE = ‘#ifdef GL_ES\n‘ + ‘precision mediump float;\n‘ + ‘#endif\n‘ + ‘varying vec4 v_Color;\n‘ + ‘void main() {\n‘ + ‘ gl_FragColor = v_Color;\n‘ + ‘}\n‘; function main() { // Retrieve <canvas> element var canvas = document.getElementById(‘webgl‘);// Get the rendering context for WebGL var gl = getWebGLContext(canvas); if (!gl) { console.log(‘Failed to get the rendering context for WebGL‘); return; } // Initialize shaders if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { console.log(‘Failed to intialize shaders.‘); return; } // Set the vertex coordinates and color (the blue triangle is in the front) var n = initVertexBuffers(gl); if (n < 0) { console.log(‘Failed to set the vertex information‘); return; } // Specify the color for clearing <canvas> gl.clearColor(0, 0, 0, 1);
② gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); //開啟隱藏面消除(基於Z軸,前面的自動遮住後面的,這樣不用在意圖形先後繪制決定層級的問題) gl.enable(gl.DEPTH_TEST); //開啟多邊形偏移解決不同物體Z軸值一樣的問題(基於所在面與視區的角度設置z軸偏移量) gl.enable(gl.POLYGON_OFFSET_FILL); // Get the storage location of u_MvpMatrix var u_MvpMatrix = gl.getUniformLocation(gl.program, ‘u_MvpMatrix‘); if (!u_MvpMatrix) { console.log(‘Failed to get the storage location of u_MvpMatrix‘); return; } var modelMatrix = new Matrix4(); // Model matrix var viewMatrix = new Matrix4(); // View matrix var projMatrix = new Matrix4(); // Projection matrix var mvpMatrix = new Matrix4(); // Model view projection matrix ① //模型矩陣,用於計算模型的運動(平移、旋轉、縮放) modelMatrix.setTranslate(0.75, 0, 0); //視圖矩陣(人開物體的位置) viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0); //透視投影矩陣(相對應的還有正視投影,但是3D下一般用透視投影,看起來更符合人類視角) projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100); //上述三種矩陣相乘 mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix); gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements); gl.clear(gl.COLOR_BUFFER_BIT); // Clear <canvas> gl.drawArrays(gl.TRIANGLES, 0, n); // Draw the triangles ③ //繪制之前設置多邊形偏移參數值 gl.polygonOffset(1.0, 1.0); //幾何體位置移動再畫一次(放到右邊) modelMatrix.setTranslate(-0.75, 0, 0); mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix); gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements); gl.drawArrays(gl.TRIANGLES, 0, n); // Draw the triangles } function initVertexBuffers(gl) {
④ var verticesColors = new Float32Array([ // Vertex coordinates and color 0.0, 1.0, -4.0, 0.4, 1.0, 0.4, // The back green one -0.5, -1.0, -4.0, 0.4, 1.0, 0.4, 0.5, -1.0, -4.0, 1.0, 0.4, 0.4, 0.0, 1.0, -2.0, 1.0, 1.0, 0.4, // The middle yellow one -0.5, -1.0, -2.0, 1.0, 1.0, 0.4, 0.5, -1.0, -2.0, 1.0, 0.4, 0.4, 0.0, 1.0, 0.0, 0.4, 0.4, 1.0, // The front blue one -0.5, -1.0, 0.0, 0.4, 0.4, 1.0, 0.5, -1.0, 0.0, 1.0, 0.4, 0.4, ]); var n = 9; // Create a buffer object var vertexColorBuffer = gl.createBuffer(); if (!vertexColorBuffer) { console.log(‘Failed to create the buffer object‘); return -1; } // Write the vertex information and enable it gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer); gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW); var FSIZE = verticesColors.BYTES_PER_ELEMENT; 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 -1; } gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0); gl.enableVertexAttribArray(a_Position); var a_Color = gl.getAttribLocation(gl.program, ‘a_Color‘); if(a_Color < 0) { console.log(‘Failed to get the storage location of a_Color‘); return -1; } gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3); gl.enableVertexAttribArray(a_Color); return n; }
WebGL編程指南案例解析之3D視圖視區問題