webgl学习笔记三-平移旋转缩放

来源:互联网 发布:数学建模数据分析 编辑:程序博客网 时间:2024/05/16 12:25

写在前面

建议先阅读下前面我的两篇文章。

webgl学习笔记一-绘图单点

webgl学习笔记二-绘图多点

平移

1、关键点说明

  • 顶点着色器需要加上 uniform vec4 u_Translation, 存储平移的坐标矢量。

  • 顶点坐标位置 : gl_Position = a_Position + u_Translation

  • 平移API : gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);

2、demo

  • html
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Title</title></head><body><canvas  width="200px" height="200px"></canvas></body></html>
  • JavaScript
<script>    function main() {        //顶点着色器程序        var VSHADER_SOURCE =            'attribute vec4 a_Position;\n' +            'uniform vec4 u_Translation;\n' +            'void main() {\n' +            '  gl_Position = a_Position + u_Translation;\n' +            '}\n';        //片元着色器        var FSHADER_SOURCE =            'void main() {\n' +            '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +            '}\n';        //获取canvas元素        var canvas = document.getElementById('canvas');        //获取绘制二维上下文        var gl = canvas.getContext('webgl');        if (!gl) {            console.log("Failed");            return;        }        //编译着色器        var vertShader = gl.createShader(gl.VERTEX_SHADER);        gl.shaderSource(vertShader, VSHADER_SOURCE);        gl.compileShader(vertShader);        var fragShader = gl.createShader(gl.FRAGMENT_SHADER);        gl.shaderSource(fragShader, FSHADER_SOURCE);        gl.compileShader(fragShader);        //合并程序        var shaderProgram = gl.createProgram();        gl.attachShader(shaderProgram, vertShader);        gl.attachShader(shaderProgram, fragShader);        gl.linkProgram(shaderProgram);        gl.useProgram(shaderProgram);        //获取坐标点        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');        if (a_Position < 0) {            console.log('Failed to get the storage location of a_Position');            return;        }        var n = initBuffers(gl, shaderProgram);        if (n < 0) {            console.log('Failed to set the positions');            return;        }        // 清除指定<画布>的颜色        gl.clearColor(0.0, 0.0, 0.0, 1.0);        // 清空 <canvas>        gl.clear(gl.COLOR_BUFFER_BIT);        gl.drawArrays(gl.TRIANGLES, 0, n);    }    function opt(gl, shaderProgram) {        var Tx = 0.5, Ty = 0.5, Tz = 0.0;        var u_Translation = gl.getUniformLocation(shaderProgram, 'u_Translation');        if (!u_Translation) {            console.log('Failed to get the storage location of u_Translation');            return;        }        gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);    }    function initBuffers(gl, shaderProgram) {        var vertices = new Float32Array([            0, 0.5,   -0.5, -0.5,   0.5, -0.5        ]);        var n = 3;//点的个数        //创建缓冲区对象        var vertexBuffer = gl.createBuffer();        if (!vertexBuffer) {            console.log("Failed to create the butter object");            return -1;        }        //将缓冲区对象绑定到目标        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);        //向缓冲区写入数据        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);        //获取坐标点        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');        //将缓冲区对象分配给a_Position变量        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);        //连接a_Position变量与分配给它的缓冲区对象        gl.enableVertexAttribArray(a_Position);        return n;    }    main();</script>

旋转

1、关键点说明

  • 坐标P(x,y,z) , 绕Z轴旋转β角度变成 p1(x1, y1, z1)
    则根据数据三角函数公式可得:

x1 = xcosβ - ysinβ

y1 = xsinβ + ycosβ

z1=z

  • 顶点着色器需要加上 uniform float u_CosB, u_SinB 存储旋转角度。

  • 顶点坐标位置 :
    • gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB
    • gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB
  • 旋转API :
    • gl.uniform1f(u_CosB, cosB)
    • gl.uniform1f(u_sinB, sinB);

2、demo

  • JavaScript
<script>    function main() {        //顶点着色器程序        var VSHADER_SOURCE =            'attribute vec4 a_Position;\n' +            'uniform float u_CosB, u_SinB;\n' +            'void main() {\n' +            '  gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n' +            '  gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;\n' +            '  gl_Position.z = a_Position.z;\n' +            '  gl_Position.w = 1.0;\n' +            '}\n';        //片元着色器程序        var FSHADER_SOURCE =            'void main() {\n' +            '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +            '}\n';        var Tx = 0.5, Ty = 0.5, Tz = 0.0;        //获取canvas元素        var canvas = document.getElementById('canvas');        //获取绘制二维上下文        var gl = canvas.getContext('webgl');        if (!gl) {            console.log("Failed");            return;        }        //编译着色器        var vertShader = gl.createShader(gl.VERTEX_SHADER);        gl.shaderSource(vertShader, VSHADER_SOURCE);        gl.compileShader(vertShader);        var fragShader = gl.createShader(gl.FRAGMENT_SHADER);        gl.shaderSource(fragShader, FSHADER_SOURCE);        gl.compileShader(fragShader);        //合并程序        var shaderProgram = gl.createProgram();        gl.attachShader(shaderProgram, vertShader);        gl.attachShader(shaderProgram, fragShader);        gl.linkProgram(shaderProgram);        gl.useProgram(shaderProgram);        //获取坐标点        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');        if (a_Position < 0) {            console.log('Failed to get the storage location of a_Position');            return;        }        var n = initBuffers(gl, shaderProgram);        if (n < 0) {            console.log('Failed to set the positions');            return;        }        opt(gl, shaderProgram);        // 清除指定<画布>的颜色        gl.clearColor(0.0, 0.0, 0.0, 1.0);        // 清空 <canvas>        gl.clear(gl.COLOR_BUFFER_BIT);        gl.drawArrays(gl.TRIANGLES, 0, n);    }    function opt(gl, program) {        // 旋转角度        var ANGLE = 90.0;        var radian = Math.PI * ANGLE / 180.0;        var cosB = Math.cos(radian);        var sinB = Math.sin(radian);        var u_CosB = gl.getUniformLocation(program, 'u_CosB');        var u_sinB = gl.getUniformLocation(program, 'u_SinB');        gl.uniform1f(u_CosB, cosB);        gl.uniform1f(u_sinB, sinB);    }    function initBuffers(gl, shaderProgram) {        var vertices = new Float32Array([            0, 0.5,   -0.5, -0.5,   0.5, -0.5        ]);        var n = 3;//点的个数        //创建缓冲区对象        var vertexBuffer = gl.createBuffer();        if (!vertexBuffer) {            console.log("Failed to create the butter object");            return -1;        }        //将缓冲区对象绑定到目标        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);        //向缓冲区写入数据        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);        //获取坐标点        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');        //将缓冲区对象分配给a_Position变量        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);        //连接a_Position变量与分配给它的缓冲区对象        gl.enableVertexAttribArray(a_Position);        return n;    }    main();</script>

缩放

1、关键点说明

  • 顶点着色器需要加上 uniform mat4 u_xformMatrix, 存储缩放因子的坐标矢量。

  • 顶点坐标位置 : gl_Position = u_xformMatrix * a_Position

  • 缩放API : gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
    • u_xformMatrix : 缩放因子
    • xformMatrix : 原始坐标

2、demo

  • JavaScript
<script>    function main() {        //顶点着色器程序        var VSHADER_SOURCE =            'attribute vec4 a_Position;\n' +            'uniform mat4 u_xformMatrix;\n' +            'void main() {\n' +            '  gl_Position = u_xformMatrix * a_Position;\n' +            '}\n';        //片元着色器程序        var FSHADER_SOURCE =            'void main() {\n' +            '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +            '}\n';        var Tx = 0.5, Ty = 0.5, Tz = 0.0;        //获取canvas元素        var canvas = document.getElementById('canvas');        //获取绘制二维上下文        var gl = canvas.getContext('webgl');        if (!gl) {            console.log("Failed");            return;        }        //编译着色器        var vertShader = gl.createShader(gl.VERTEX_SHADER);        gl.shaderSource(vertShader, VSHADER_SOURCE);        gl.compileShader(vertShader);        var fragShader = gl.createShader(gl.FRAGMENT_SHADER);        gl.shaderSource(fragShader, FSHADER_SOURCE);        gl.compileShader(fragShader);        //合并程序        var shaderProgram = gl.createProgram();        gl.attachShader(shaderProgram, vertShader);        gl.attachShader(shaderProgram, fragShader);        gl.linkProgram(shaderProgram);        gl.useProgram(shaderProgram);        //获取坐标点        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');        if (a_Position < 0) {            console.log('Failed to get the storage location of a_Position');            return;        }        var n = initBuffers(gl, shaderProgram);        if (n < 0) {            console.log('Failed to set the positions');            return;        }        opt(gl, shaderProgram);        // 清除指定<画布>的颜色        gl.clearColor(0, 0, 0, 1);        // 清空 <canvas>        gl.clear(gl.COLOR_BUFFER_BIT);        // Draw the rectangle        gl.drawArrays(gl.TRIANGLES, 0, n);    }    // 缩放    function opt(gl, program) {        // 缩放因子        var Sx = 1.0, Sy = 1.5, Sz = 1.0;        var xformMatrix = new Float32Array([            Sx,   0.0,  0.0,  0.0,            0.0,  Sy,   0.0,  0.0,            0.0,  0.0,  Sz,   0.0,            0.0,  0.0,  0.0,  1.0        ]);        var u_xformMatrix = gl.getUniformLocation(program, 'u_xformMatrix');        gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);    }    // 构建缓冲区    function initBuffers(gl, shaderProgram) {        var vertices = new Float32Array([            0, 0.5,   -0.5, -0.5,   0.5, -0.5        ]);        var n = 3;//点的个数        //创建缓冲区对象        var vertexBuffer = gl.createBuffer();        if (!vertexBuffer) {            console.log("Failed to create the butter object");            return -1;        }        //将缓冲区对象绑定到目标        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);        //向缓冲区写入数据        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);        //获取坐标点        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');        //将缓冲区对象分配给a_Position变量        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);        //连接a_Position变量与分配给它的缓冲区对象        gl.enableVertexAttribArray(a_Position);        return n;    }    // 主方法调用    main();</script>

写在最后

  新博客

原创粉丝点击