高级变换和动画基础

# 矩阵函数库

矩阵函数库之平移函数

提示

调用平移函数并传入三个值,不必手动创建平移矩阵

例子一:使用库函数实现平移功能

<!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>使用矩阵库实现旋转功能</title>
        <script src="./lib/webgl-utils.js"></script>
        <script src="./lib/webgl-debug.js"></script>
        <script src="./lib/cuon-utils.js"></script>
        <script src="./lib/cuon-matrix.js"></script>
    </head>

    <body onload="main()">
        <canvas width="300" height="300" id='webgl'>
            请使用支持功能的浏览器查看
        </canvas>

        <script>
            let VSHADER_SOURCE =
                `attribute vec4 a_Position;
                 uniform mat4 u_xformMatrix;
                 void main(){
                    gl_Position=u_xformMatrix*a_Position;
                 }`;

            let FSHADER_SOURCE =
                `void main(){
                    gl_FragColor=vec4(1.0,0.0,0.0,1.0);
                }`;

            let ANGLE = 90;

            function main() {
                let canvas = document.querySelector('#webgl');
                let gl = getWebGLContext(canvas);
                if (!gl) {
                    console.info('failed initlizated gl.');
                    return;
                }

                if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                    console.info('failed initlizeted shader.');
                    return;
                }

                let n = initVertexBuffer(gl);
                if (n < 0) {
                    console.info('failed initlizated vertexBuffer');
                    return;
                }

                //矩阵对象
                let xformMatrix = new Matrix4();
                //设置旋转
                xformMatrix.setRotate(ANGLE, 0, 0, 1);

                let u_xformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix');
                //将矩阵值传递给顶点着色器
                gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix.elements);

                gl.clearColor(0.0, 0.0, 0.0, 1.0);
                gl.clear(gl.COLOR_BUFFER_BIT);
                gl.drawArrays(gl.TRIANGLES, 0, n)
            }

            function initVertexBuffer(gl) {
                let vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5]);
                let n = 3;
                let vertexBuffer = gl.createBuffer();
                if (!vertexBuffer) {
                    console.info('failed initalized vertexBuffer');
                    return -1;
                }

                gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
                gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STREAM_DRAW);
                let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
                if (a_Position < 0) {
                    console.info('failed initalized position');
                    return -1;
                }
                gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
                gl.enableVertexAttribArray(a_Position);
                return n;

            }
        </script>
    </body>

    </html>   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

# 模型变换(model transformation)

又称为建模变换(modeling transformation),相应地,模型变换的矩阵称为模型矩阵(model matrix)。

例子二:复合矩阵

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模型变换矩阵</title>
    <script src="./lib/webgl-utils.js"></script>
    <script src="./lib/webgl-debug.js"></script>
    <script src="./lib/cuon-utils.js"></script>
    <script src="./lib/cuon-matrix.js"></script>
</head>

<body onload="main()">
    <canvas width="300" height="300" id='webgl'>
        请使用支持功能的浏览器查看
    </canvas>

    <script>
        let VSHADER_SOURCE =
            `attribute vec4 a_Position;
             uniform mat4 u_ModelMatrix;
             void main(){
                gl_Position=u_ModelMatrix*a_Position;
             }`;

        let FSHADER_SOURCE =
            `void main(){
                gl_FragColor=vec4(1.0,0.0,0.0,1.0);
             }`;

        let ANGLE = 90;
        let Tx = 0.5;

        function main() {
            let canvas = document.querySelector('#webgl');
            let gl = getWebGLContext(canvas);
            if (!gl) {
                console.info('failed initlizated gl.');
                return;
            }

            if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                console.info('failed initlizeted shader.');
                return;
            }

            let n = initVertexBuffer(gl);
            if (n < 0) {
                console.info('failed initlizated vertexBuffer');
                return;
            }

            //矩阵对象
            let modelMatrix = new Matrix4();
            //设置旋转
            modelMatrix.setRotate(ANGLE, 0, 0, 1);
            modelMatrix.translate(Tx, 0, 0);

            let u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
            //将矩阵值传递给顶点着色器
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);

            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.TRIANGLES, 0, n)
        }

        function initVertexBuffer(gl) {
            let vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5]);
            let n = 3;
            let vertexBuffer = gl.createBuffer();
            if (!vertexBuffer) {
                console.info('failed initalized vertexBuffer');
                return -1;
            }

            gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STREAM_DRAW);
            let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
            if (a_Position < 0) {
                console.info('failed initalized position');
                return -1;
            }
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(a_Position);
            return n;
        }
    </script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

# 动画

例子三:旋转动画

    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>动起来</title>
        <script src="./lib/webgl-utils.js"></script>
        <script src="./lib/webgl-debug.js"></script>
        <script src="./lib/cuon-utils.js"></script>
        <script src="./lib/cuon-matrix.js"></script>
    </head>

    <body onload="main()">
        <canvas width="300" height="300" id='webgl'>
            请使用支持功能的浏览器查看
        </canvas>

        <script>
            let VSHADER_SOURCE =
               `attribute vec4 a_Position;
                uniform mat4 u_ModelMatrix;
                void main(){
                    gl_Position=u_ModelMatrix*a_Position;
                }`;

            let FSHADER_SOURCE =
                `void main(){
                    gl_FragColor=vec4(1.0,0.0,0.0,1.0);
                }`;

            let ANGLE_STEP = 45; //每秒旋转45度
            let MOVE_STEP = 10; //移动速度
            function main() {
                let canvas = document.querySelector('#webgl');
                let gl = getWebGLContext(canvas);
                if (!gl) {
                    console.info('failed initlizated gl.');
                    return;
                }

                if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                    console.info('failed initlizeted shader.');
                    return;
                }

                let n = initVertexBuffer(gl);
                if (n < 0) {
                    console.info('failed initlizated vertexBuffer');
                    return;
                }

                gl.clearColor(0.0, 0.0, 0.0, 1.0);
                //矩阵对象
                let modelMatrix = new Matrix4();
                let u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
                //当前旋转角度
                let currentAngle = 0.0;
                let currentMove = 0.0;

                let tick = function () {
                    currentAngle = animate(currentAngle);
                    currentMove = animateMove(currentMove);
                    draw(gl, n, currentAngle, currentMove, modelMatrix, u_ModelMatrix);
                    window.requestAnimationFrame(tick);
                };

                tick();
            }

            let g_last = Date.now();

            function animate(angle) {
                let now = Date.now();
                let elapsed = now - g_last; //毫秒
                g_last = now;
                let newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
                console.info(newAngle %= 360);
                return newAngle %= 360;
            }

            let flag = 1;

            function animateMove(move) {
                let now = Date.now();
                let elapsed = now - g_last;
                g_last = now;
                let newMove = move * flag + (MOVE_STEP * elapsed) / 1000.0;
                if (newMove > 0.35) {
                    flag = -1;
                } else if (newMove < -0.35) {
                    flag = 1;
                }
                return newMove;
            }

            function draw(gl, n, currentAngle, currentMove, modelMatrix, u_ModelMatrix) {
                modelMatrix.setRotate(currentAngle, 0, 0, 1);
                modelMatrix.translate(currentMove, 0, 0);
                gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
                gl.clear(gl.COLOR_BUFFER_BIT);
                gl.drawArrays(gl.TRIANGLES, 0, n);
            }

            function initVertexBuffer(gl) {
                let vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5]);
                let n = 3;
                let vertexBuffer = gl.createBuffer();
                if (!vertexBuffer) {
                    console.info('failed initalized vertexBuffer');
                    return -1;
                }

                gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
                gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STREAM_DRAW);
                let a_Position = gl.getAttribLocation(gl.program, 'a_Position');
                if (a_Position < 0) {
                    console.info('failed initalized position');
                    return -1;
                }
                gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
                gl.enableVertexAttribArray(a_Position);
                return n;
            }
        </script>
    </body>
    </html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
动画

解析

例子三:旋转动画

  • 需要在每个刷新时刻调用同一个函数来绘制三角形
  • 每次绘制之前,清除上次绘制的内容,并使三角形旋转相应的角度
上次更新: 2025/02/15, 13:42:25
最近更新
01
vue3尚硅谷课件
04-26
02
Git问题集合
01-29
03
安装 Nginx 服务器
01-25
更多文章>
×
×