WebGl-移动、旋转、缩放demo

883 阅读2分钟

webGl的图形变换无非就是顶点坐标的矩阵变换,下面我们看几个例子。

移动图形

1.想要改变顶点坐标,那就需要通过变量translation与原始坐标进行运算,查可改变位置,这部分需要编写在glsl里。

          attribute vec3 coordinates;
          uniform mat4 translation;
          void main(void) {
            gl_Position = translation*vec4(coordinates,1.0); //这里一定要注意  是translation在前
          };

2.对于二维来说,图形的移动无非上下左右移动。所以对应的矩阵如下,TX,TY是上下左右的偏移量。z待定

        var xformMatrix = new Float32Array([
            1.0, 0.0, 0.0, 0.0,
            0.0, 1.0, 0.0, 0.0,
            0.0, 0.0, 1.0, 0.0,
            Tx, Ty, Tz, 1.0
        ]);

3.如何通过js代码将需要动态改变的参数传给着色器,实现图形移动

        gl.uniformMatrix4fv(translation, false, xformMatrix);
        //重复 第5步 - 绘制所需的对象
        gl.clearColor(0.5, 0.5, 0.5, 0.9);
        gl.enable(gl.DEPTH_TEST);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.viewport(0, 0, myCanvas.width, myCanvas.height);
        gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

148df53fd2ec2149a54b9473c88c421e.png 通过点击事件变更移动参数

    switch (event.keyCode){
        case 37:
            Tx -= 0.05;
            break;
        case 38:
            Ty += 0.05;
            break;
        case 39:
            Tx += 0.05;
            break;
        case 40:
            Ty -= 0.05;
            break;
    }

4dc9d775ee9cf14cadf39d792ffac595.png

旋转图形

1.想要旋转图形,同理是修改顶点坐标,通过点乘旋转矩阵达到效果。

         attribute vec3 coordinates; 
         uniform mat4 Pmatrix;
         uniform mat4 Vmatrix;
         uniform mat4 Mmatrix;
         attribute vec3 color;
         varying vec3 vColor;
         void main(void) {
            gl_Position = rotate*vec4(coordinates,1.0);
            vColor = color;
         }

2.学过力学应该知道一个力可以分解为另外两个方向的力,同理旋转方向也可以分解成x,y,z,三个方向的旋转叠加。 那我们看z方向。B为旋转角度。

         var zformMatrix = new Float32Array([
            cosB,  sinB, 0.0, 0.0,
            -sinB, cosB, 0.0, 0.0,
            0.0,    0.0, 1.0, 0.0,
            0.0,    0.0, 0.0, 1.0
        ]);

x旋转.gif x轴

         xformMatrix = new Float32Array([
            1.0, 0.0, 0.0, 0.0,
            0.0, cosB, sinB, 0.0,
            0.0, -sinB, cosB, 0.0,
            0.0,  0.0, 0.0, 1.0
        ]);

x1旋转.gif y轴

         yformMatrix = new Float32Array([
            cosB, 0.0, sinB, 0.0,
            0.0,  1.0, 0.0,  0.0,
           -sinB, 0.0, cosB, 0.0,
            0.0,  0.0, 0.0,  1.0
        ]);

y旋转.gif

缩放图形

1.缩放是通过缩放倍数来修改顶点坐标的,下面通过例子看下。

     attribute vec3 coordinates;
     uniform mat4 scale;
     void main(void) {
       gl_Position = scale*vec4(coordinates,1.0);
     }

2.scale矩阵如下。

         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
        ]);

3.如何通过js代码将需要动态改变的参数传给着色器,实现图形移动

        var scale = gl.getUniformLocation(shaderProgram,'scale');
        gl.uniformMatrix4fv(scale, false, xformMatrix);
        gl.clearColor(0.5, 0.5, 0.5, 0.9);
        gl.enable(gl.DEPTH_TEST);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.viewport(0, 0, myCanvas.width, myCanvas.height);
        gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

通过点击事件变更移动参数

     document.addEventListener("keyup",function (event) {
            switch (event.keyCode){
                case 38:
                    Sx += 0.05;
                    Sy += 0.05;
                    Sz += 0.05;
                    break;
                case 40:
                    Sx -= 0.05;
                    Sy -= 0.05;
                    Sz -= 0.05;
                    break;
            }

            //重复以上部分操作
            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
            ]);
            gl.uniformMatrix4fv(scale, false, xformMatrix);
            //重复 第5步 - 绘制所需的对象
            gl.clearColor(0.5, 0.5, 0.5, 0.9);
            gl.enable(gl.DEPTH_TEST);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.viewport(0, 0, myCanvas.width, myCanvas.height);
            gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

        });

缩放1.png

缩放2.png