七、图形转换 - 矩阵

53 阅读2分钟

1.什么是矩阵

矩阵就是纵横排列的数据表格(m行n列)

作用是把一个点转换到另一个点

1、矩阵赋值

gl.uniformMatrix4fv(location, transpose,transpose,array)

location:指定 uniform 变量的存储位置

transpose:在webgl中恒为false

array:矩阵数组

let webglDiv = document.getElementById('practice');
let webgl = webglDiv.getContext('webgl');

/*着色器*/
// 顶点着色器
const VERTEX_SHADER_SOURCE = `
        //  attribute 只能用于传递定点数据
       attribute vec4 aPosition;
        //  定义矩阵
       uniform mat4 mat;
        //  点的大小
       attribute float aPointSize;
       void main(){
          // 要绘制的点的坐标
          gl_Position =mat* aPosition;
          // 点的大小
          gl_PointSize = aPointSize;
        }
  `;
// 片元着色器
const FRAGMENT_SHADER_SOURCE = `
   //  设置默认精度
    precision mediump float;
    //  uniform 只能用于传递颜色
    uniform vec3 uColor;
    void main(){
     gl_FragColor = vec4(uColor.r, uColor.g, uColor.b,1.0);
    }
  `;

// 创建着色器并绑定程序对象
const program = initShader(webgl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE);

// 获取attribute变量
const aPosition = webgl.getAttribLocation(program, 'aPosition');
const aPointSize = webgl.getAttribLocation(program, 'aPointSize');
const mat = webgl.getUniformLocation(program, 'mat');
// 获取uniform 变量
const uColor = webgl.getUniformLocation(program, 'uColor');

// 创建类型化数组
const points = new Float32Array([
  -0.5, -0.5, 10.0,
  0.5, -0.5, 20.0,
  0.0, 0.5, 30.0,
  -0.8, 0.6, 30.0,
  -0.8, 1
]);
// 获取每个数据占据的字节数
const BYTES = points.BYTES_PER_ELEMENT;
//创建缓冲区
const buffer = webgl.createBuffer();
//绑定缓冲区到顶点数据
webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);
//给已绑定的缓冲区赋值
webgl.bufferData(webgl.ARRAY_BUFFER, points, webgl.STATIC_DRAW);
// uniform 变量赋值
webgl.uniform3f(uColor, 0.1, 1.0, 1.0);

//矩阵赋值顶点数据
webgl.vertexAttribPointer(aPosition, 2, webgl.FLOAT, false, BYTES * 3, 0);
//激活变量
webgl.enableVertexAttribArray(aPosition);


//矩阵赋值顶点大小
webgl.vertexAttribPointer(aPointSize, 1, webgl.FLOAT, false, BYTES * 3, BYTES * 2);
//激活变量
webgl.enableVertexAttribArray(aPointSize);
let x = -1;
function animation() {
  x += 0.01;
  if( x>1){
    x = -1
  }
  const Matrix = getMatrix(x,x);
  //矩阵属性赋值
  webgl.uniformMatrix4fv(mat,false,Matrix)
  webgl.drawArrays(webgl.TRIANGLE_FAN, 0, 5);
  requestAnimationFrame(animation)
}
animation()

2、矩阵转换方法

缩放矩阵

const getScaleMatrix = function (x=1,y=1,z=1){
    return new Float32Array([
        x, 0.0, 0.0, 0.0,
        0.0, y, 0.0, 0.0,
        0.0, 0.0, z, 0.0,
        0.0, 0.0, 0.0,1.0
    ]);
}

平移矩阵

 const getScaleMatrix = function (x=1,y=1,z=1){
    return new Float32Array([
        x, 0.0, 0.0, 0.0,
        0.0, y, 0.0, 0.0,
        0.0, 0.0, z, 0.0,
        0.0, 0.0, 0.0,1.0
    ]);
}

旋转矩阵

const getRotateMatrix = function (deg){
    return new Float32Array([
      Math.cos(deg), Math.sin(deg), 0.0, 0.0,
      -Math.sin(deg),-Math.cos(deg), 0.0, 0.0,
        0.0,             0.0,        1.0, 0.0,
        0.0,             0.0,        0.0,1.0
    ]);
}

合并矩阵

const mixMatrix = function (a,b){
    const result = new Float32Array(16);
    for (let i = 0 ;i<4;i++){
        result[i]       = a[i]*b[0]+ a[i+4]*b[1]+ a[i+8]*b[2]+ a[i+12]*b[3];
        result[i+4]     = a[i]*b[4]+ a[i+4]*b[5]+ a[i+8]*b[6]+ a[i+12]*b[7];
        result[i+8]     = a[i]*b[8]+ a[i+4]*b[9]+ a[i+8]*b[10]+ a[i+12]*b[11];
        result[i+12]    = a[i]*b[12]+ a[i+4]*b[13]+ a[i+8]*b[14]+ a[i+12]*b[15];
    }
    return result
}