本文主要介绍MVP矩阵,MVP矩阵实际上是由模型矩阵、视图矩阵以及投影矩阵组合而成,主要用于调整模型位置、观察模型位置以及相机投影信息。文中部分代码源自《WebGL编程指南》。
代码如下:
<template>
<div>
<canvas ref="myglCanvas" width="400" height="400"></canvas>
</div>
</template>
<script>
import Tools from "../lib/tools";
export default {
name: "glCanvas",
data() {
return {
VSHEADER_SOURCE: `attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_mvpMatrix;
varying vec4 v_color;
void main(){
gl_Position = u_mvpMatrix* a_Position;
v_color = a_Color;
}`,
FSHEADER_SOURCE: `precision mediump float;
varying vec4 v_color;
void main(){
gl_FragColor = v_color;
}`,
gl: null
};
},
methods: {
setBufferAndMatrix: function(gl) {
let verticesColors = new Float32Array([
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,
]);
let n = 9;
// Create a buffer object
let 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);
let FSIZE = verticesColors.BYTES_PER_ELEMENT;
this.initBuffer(gl,"a_Position",3,FSIZE*6,0);
this.initBuffer(gl,"a_Color",3,FSIZE*6,FSIZE*3);
this.setMatrix(gl);
return n;
},
drawTriangles:function(gl){
//设置缓冲区及矩阵
let n = this.setBufferAndMatrix(gl);
if(n<0){
console.log("设置缓冲区错误");
return;
}
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT); // Clear <canvas>
gl.drawArrays(gl.TRIANGLES, 0, n); // Draw the triangles
},
setMatrix:function(gl){
//获取着色器中的mvp矩阵变量
let u_mvpMatrix = gl.getUniformLocation(gl.program, 'u_mvpMatrix');
if (!u_mvpMatrix) {
console.log('获取着色器中的mvp矩阵变量错误');
return;
}
//创建mvp三个矩阵
let modelMatrix = mat4.create(); // 模型矩阵
let viewMatrix = mat4.create(); // 视图矩阵
let projMatrix = mat4.create(); // 投影矩阵
//沿x轴平移0.75单位
mat4.translate(modelMatrix, modelMatrix, [0.75,0,0]);
//设置视图矩阵
mat4.lookAt(viewMatrix, [0,0,5], [0,0,-100], [0,1,0]);
//获取画布的宽高
let canvasWidth = this.$refs.myglCanvas.width;
let canvasHeight = this.$refs.myglCanvas.height;
//将角度转为弧度
const angleRad =30 * Math.PI / 180;
//设置投影矩阵
mat4.perspective(projMatrix, angleRad, canvasWidth/canvasHeight, 1, 100);
//mvp矩阵
let mv_Matrix = mat4.create();
let mvp_Matrix = mat4.create();
mat4.mul(mv_Matrix, viewMatrix,modelMatrix);
mat4.mul(mvp_Matrix, projMatrix,mv_Matrix);
//将mvp矩阵传递给着色器
gl.uniformMatrix4fv(u_mvpMatrix,false,mvp_Matrix);
},
/**
* 初始化缓冲区
* paramStr 变量名
* count 对象个数
* stride 步长
* offset 偏移量
*/
initBuffer:function(gl,paramStr,count,stride,offset){
let a_param = this.gl.getAttribLocation(gl.program,paramStr);
if (a_param < 0) {
console.log(paramStr+" failed");
return -1;
}
// 将缓冲区对象分配给attribute对象
gl.vertexAttribPointer(a_param, count, gl.FLOAT, false, stride, offset);
// 开启attribute对象
gl.enableVertexAttribArray(a_param);
},
setGL: function() {
this.gl = this.$refs.myglCanvas.getContext("webgl");
}
},
mounted() {
this.setGL();
Tools.initShaders(this.gl, this.VSHEADER_SOURCE, this.FSHEADER_SOURCE);
this.drawTriangles(this.gl);
}
};
</script>
<style scoped>
</style>
15行 在顶点着色器中设置u_mvpMatrix变量;
80-115行 设置MVP矩阵信息,代码中的矩阵操作引用的是gl-martix库;不会配置的可以联系我。
运行代码,效果如下
更多内容请扫码关注我的微信公众号,或者在微信里搜索公众号webgis学习,我会不定期更新自己的web方面的学习心得。