mvp矩阵实际上就是:
<投影矩阵>x<视图矩阵>x<模型矩阵>x<顶点坐标>
<canvas id="webgl" width="800px" height="600px"></canvas> <script> //vertex shader var VSHADER_SOURCE = ` attribute vec4 a_Position; attribute vec4 a_Color; uniform mat4 u_ViewMatrix; uniform mat4 u_ModelMatrix; uniform mat4 u_ProjMatrix; varying vec4 v_Color; void main() { // gl_Position = a_Position; gl_Position =u_ProjMatrix * u_ViewMatrix * u_ModelMatrix*a_Position; v_Color = a_Color; } `; //fragment shader var FSHADER_SOURCE = ` precision mediump float; varying vec4 v_Color; void main() { gl_FragColor = v_Color; } `; //main ready(loadWEBGL); //主程序 function loadWEBGL() { var canvas = document.getElementById('webgl'); if (!canvas) { console.error('Failed to get canvas-element!'); return; } var webgl = canvas.getContext('webgl'); if (!webgl) { console.error('Failed to get canvas context: webgl!'); return; } if (!initShaders(webgl, VSHADER_SOURCE, FSHADER_SOURCE)) { console.error('Failed to init shaders!'); return; } var n = initBuffer(webgl); if (n < 0) { console.error('Failed to init buffer!'); return; } setViewMatrix(webgl); setModelMatrix(webgl); setProjMatrix(webgl, canvas); webgl.clearColor(0.0, 0.0, 0.0, 1.0); webgl.clear(webgl.COLOR_BUFFER_BIT); webgl.drawArrays(webgl.TRIANGLES, 0, n); } function initBuffer(webgl) { var vertexData = new Float32Array([ //顶点坐标颜色 0.0, 0.5, -0.4, 0.4, 1.0, 0.4, -0.5, -0.5, -0.4, 0.4, 1.0, 0.4, 0.5, -0.5, -0.4, 1.0, 0.4, 0.4, 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, -0.5, 0.4, -0.2, 1.0, 1.0, 0.4, 0, -0.6, -0.2, 1.0, 1.0, 0.4, 0.0, 0.5, 0.0, 0.4, 0.4, 1.0, -0.5, -0.5, 0.0, 0.4, 0.4, 1.0, 0.5, -0.5, 0.0, 1.0, 0.4, 0.4 ]); var n = vertexData.length / 6; var FSIZE = vertexData.BYTES_PER_ELEMENT; var a_Position = webgl.getAttribLocation(webgl.program, 'a_Position'); var a_Color = webgl.getAttribLocation(webgl.program, 'a_Color'); var buffer = webgl.createBuffer(); webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer); webgl.bufferData(webgl.ARRAY_BUFFER, vertexData, webgl.STATIC_DRAW); webgl.vertexAttribPointer(a_Position, 3, webgl.FLOAT, false, FSIZE * 6, 0); webgl.vertexAttribPointer(a_Color, 3, webgl.FLOAT, false, FSIZE * 6, FSIZE * 3); webgl.enableVertexAttribArray(a_Position); webgl.enableVertexAttribArray(a_Color); return n; } function setViewMatrix(webgl) { var u_ViewMatrix = webgl.getUniformLocation(webgl.program, 'u_ViewMatrix'); //设置视点 视线 上方向 var viewMatrix = new Matrix4(); viewMatrix.setLookAt(-0.20, 0.05, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); webgl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements); } function setModelMatrix(webgl) { var u_ModelMatrix = webgl.getUniformLocation(webgl.program, 'u_ModelMatrix'); //设置视点 视线 上方向 var modelMatrix = new Matrix4(); modelMatrix.setRotate(45, 0, 0, 1); webgl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements); } function setProjMatrix(webgl, canvas) { var u_ProjMatrix = webgl.getUniformLocation(webgl.program, 'u_ProjMatrix'); //设置视点 视线 上方向 var projMatrix = new Matrix4(); projMatrix.setPerspective(45, canvas.width / canvas.height, 1, 100); webgl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements); } </script>但是上面的算法中,每个顶点都要计算几次mvp,所以可以在代码中直接先计算好mvp矩阵,然后在顶点着色器中直接调用就好。
<canvas id="webgl" width="800px" height="600px"></canvas> <script> //vertex shader var VSHADER_SOURCE = ` attribute vec4 a_Position; attribute vec4 a_Color; uniform mat4 u_MVPMatrix; varying vec4 v_Color; void main() { // gl_Position = a_Position; gl_Position =u_MVPMatrix*a_Position; v_Color = a_Color; } `; //fragment shader var FSHADER_SOURCE = ` precision mediump float; varying vec4 v_Color; void main() { gl_FragColor = v_Color; } `; //main ready(loadWEBGL); //主程序 function loadWEBGL() { var canvas = document.getElementById('webgl'); if (!canvas) { console.error('Failed to get canvas-element!'); return; } var webgl = canvas.getContext('webgl'); if (!webgl) { console.error('Failed to get canvas context: webgl!'); return; } if (!initShaders(webgl, VSHADER_SOURCE, FSHADER_SOURCE)) { console.error('Failed to init shaders!'); return; } var n = initBuffer(webgl); if (n < 0) { console.error('Failed to init buffer!'); return; } setMVPMatrix(webgl, canvas); webgl.clearColor(0.0, 0.0, 0.0, 1.0); webgl.clear(webgl.COLOR_BUFFER_BIT); webgl.drawArrays(webgl.TRIANGLES, 0, n); } function initBuffer(webgl) { var vertexData = new Float32Array([ //顶点坐标颜色 0.0, 0.5, -0.4, 0.4, 1.0, 0.4, -0.5, -0.5, -0.4, 0.4, 1.0, 0.4, 0.5, -0.5, -0.4, 1.0, 0.4, 0.4, 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, -0.5, 0.4, -0.2, 1.0, 1.0, 0.4, 0, -0.6, -0.2, 1.0, 1.0, 0.4, 0.0, 0.5, 0.0, 0.4, 0.4, 1.0, -0.5, -0.5, 0.0, 0.4, 0.4, 1.0, 0.5, -0.5, 0.0, 1.0, 0.4, 0.4 ]); var n = vertexData.length / 6; var FSIZE = vertexData.BYTES_PER_ELEMENT; var a_Position = webgl.getAttribLocation(webgl.program, 'a_Position'); var a_Color = webgl.getAttribLocation(webgl.program, 'a_Color'); var buffer = webgl.createBuffer(); webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer); webgl.bufferData(webgl.ARRAY_BUFFER, vertexData, webgl.STATIC_DRAW); webgl.vertexAttribPointer(a_Position, 3, webgl.FLOAT, false, FSIZE * 6, 0); webgl.vertexAttribPointer(a_Color, 3, webgl.FLOAT, false, FSIZE * 6, FSIZE * 3); webgl.enableVertexAttribArray(a_Position); webgl.enableVertexAttribArray(a_Color); return n; } function setMVPMatrix(webgl, canvas) { var u_mvpMatrix = webgl.getUniformLocation(webgl.program, 'u_MVPMatrix'); var modelMatrix = new Matrix4(); var viewMatrix = new Matrix4(); var projMatrix = new Matrix4(); var mvpMatrix = new Matrix4(); modelMatrix.setRotate(45, 0, 0, 1); viewMatrix.setLookAt(-0.20, 0.05, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); projMatrix.setPerspective(45, canvas.width / canvas.height, 1, 100); mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix) webgl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrix.elements); } </script>