当前位置: 代码迷 >> 综合 >> webgl入门系列(3)——mvp矩阵
  详细解决方案

webgl入门系列(3)——mvp矩阵

热度:93   发布时间:2024-02-25 18:20:05.0

 mvp矩阵实际上就是:

<投影矩阵>x<视图矩阵>x<模型矩阵>x<顶点坐标>

<canvas id="webgl" width="800px" height="600px"></canvas><script>//vertex shadervar 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 shadervar FSHADER_SOURCE = `precision mediump float;varying vec4 v_Color;void main() {gl_FragColor = v_Color;}`;//mainready(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 shadervar 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 shadervar FSHADER_SOURCE = `precision mediump float;varying vec4 v_Color;void main() {gl_FragColor = v_Color;}`;//mainready(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>