webgl的shader系列(3)——mvp矩阵

 mvp矩阵实际上就是:

<投影矩阵>x<视图矩阵>x<模型矩阵>x<顶点坐标>

<canvas id="webgl" width="800px" height="600px"></canvas>
    <script>
        //vertex shader
        var VSHADER_SOURCE = `
            attribute vec4 a_Position;
            attribute vec4 a_Color;
            uniform mat4 u_ViewMatrix;
            uniform mat4 u_ModelMatrix;
            uniform mat4 u_ProjMatrix;
            varying vec4 v_Color;
            void main() {
                // gl_Position = a_Position;
                gl_Position =u_ProjMatrix * u_ViewMatrix * u_ModelMatrix*a_Position;
                v_Color = a_Color;
            }
        `;

                //fragment shader
                var FSHADER_SOURCE = `
            precision mediump float;
            varying vec4 v_Color;
            void main() {
                gl_FragColor = v_Color;
            }
        `;

        //main
        ready(loadWEBGL);

        //主程序
        function loadWEBGL() {
            var canvas = document.getElementById('webgl');
            if (!canvas) {
                console.error('Failed to get canvas-element!');
                return;
            }

            var webgl = canvas.getContext('webgl');
            if (!webgl) {
                console.error('Failed to get canvas context: webgl!');
                return;
            }

            if (!initShaders(webgl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                console.error('Failed to init shaders!');
                return;
            }

            var n = initBuffer(webgl);
            if (n < 0) {
                console.error('Failed to init buffer!');
                return;
            }

            setViewMatrix(webgl);
            setModelMatrix(webgl);
            setProjMatrix(webgl, canvas);

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

        function initBuffer(webgl) {
            var vertexData = new Float32Array([
                //顶点坐标颜色
                0.0, 0.5, -0.4, 0.4, 1.0, 0.4,
                -0.5, -0.5, -0.4, 0.4, 1.0, 0.4,
                0.5, -0.5, -0.4, 1.0, 0.4, 0.4,

                0.5, 0.4, -0.2, 1.0, 0.4, 0.4,
                -0.5, 0.4, -0.2, 1.0, 1.0, 0.4,
                0, -0.6, -0.2, 1.0, 1.0, 0.4,

                0.0, 0.5, 0.0, 0.4, 0.4, 1.0,
                -0.5, -0.5, 0.0, 0.4, 0.4, 1.0,
                0.5, -0.5, 0.0, 1.0, 0.4, 0.4
            ]);
            var n = vertexData.length / 6;
            var FSIZE = vertexData.BYTES_PER_ELEMENT;

            var a_Position = webgl.getAttribLocation(webgl.program, 'a_Position');
            var a_Color = webgl.getAttribLocation(webgl.program, 'a_Color');

            var buffer = webgl.createBuffer();
            webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);
            webgl.bufferData(webgl.ARRAY_BUFFER, vertexData, webgl.STATIC_DRAW);
            webgl.vertexAttribPointer(a_Position, 3, webgl.FLOAT, false, FSIZE * 6, 0);
            webgl.vertexAttribPointer(a_Color, 3, webgl.FLOAT, false, FSIZE * 6, FSIZE * 3);
            webgl.enableVertexAttribArray(a_Position);
            webgl.enableVertexAttribArray(a_Color);

            return n;
        }

        function setViewMatrix(webgl) {
            var u_ViewMatrix = webgl.getUniformLocation(webgl.program, 'u_ViewMatrix');

            //设置视点 视线 上方向
            var viewMatrix = new Matrix4();
            viewMatrix.setLookAt(-0.20, 0.05, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

            webgl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
        }

        function setModelMatrix(webgl) {
            var u_ModelMatrix = webgl.getUniformLocation(webgl.program, 'u_ModelMatrix');

            //设置视点 视线 上方向
            var modelMatrix = new Matrix4();
            modelMatrix.setRotate(45, 0, 0, 1);

            webgl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
        }

        function setProjMatrix(webgl, canvas) {
            var u_ProjMatrix = webgl.getUniformLocation(webgl.program, 'u_ProjMatrix');

            //设置视点 视线 上方向
            var projMatrix = new Matrix4();
            projMatrix.setPerspective(45, canvas.width / canvas.height, 1, 100);
            webgl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
        }
    </script>

但是上面的算法中,每个顶点都要计算几次mvp,所以可以在代码中直接先计算好mvp矩阵,然后在顶点着色器中直接调用就好。

    <canvas id="webgl" width="800px" height="600px"></canvas>
    <script>
        //vertex shader
        var VSHADER_SOURCE = `
            attribute vec4 a_Position;
            attribute vec4 a_Color;
            uniform mat4 u_MVPMatrix;
            varying vec4 v_Color;
            void main() {
                // gl_Position = a_Position;
                gl_Position =u_MVPMatrix*a_Position;
                v_Color = a_Color;
            }
        `;

        //fragment shader
        var FSHADER_SOURCE = `
            precision mediump float;
            varying vec4 v_Color;
            void main() {
                gl_FragColor = v_Color;
            }
        `;

        //main
        ready(loadWEBGL);

        //主程序
        function loadWEBGL() {
            var canvas = document.getElementById('webgl');
            if (!canvas) {
                console.error('Failed to get canvas-element!');
                return;
            }

            var webgl = canvas.getContext('webgl');
            if (!webgl) {
                console.error('Failed to get canvas context: webgl!');
                return;
            }

            if (!initShaders(webgl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                console.error('Failed to init shaders!');
                return;
            }

            var n = initBuffer(webgl);
            if (n < 0) {
                console.error('Failed to init buffer!');
                return;
            }

            setMVPMatrix(webgl, canvas);

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

        function initBuffer(webgl) {
            var vertexData = new Float32Array([
                //顶点坐标颜色
                0.0, 0.5, -0.4, 0.4, 1.0, 0.4,
                -0.5, -0.5, -0.4, 0.4, 1.0, 0.4,
                0.5, -0.5, -0.4, 1.0, 0.4, 0.4,

                0.5, 0.4, -0.2, 1.0, 0.4, 0.4,
                -0.5, 0.4, -0.2, 1.0, 1.0, 0.4,
                0, -0.6, -0.2, 1.0, 1.0, 0.4,

                0.0, 0.5, 0.0, 0.4, 0.4, 1.0,
                -0.5, -0.5, 0.0, 0.4, 0.4, 1.0,
                0.5, -0.5, 0.0, 1.0, 0.4, 0.4
            ]);
            var n = vertexData.length / 6;
            var FSIZE = vertexData.BYTES_PER_ELEMENT;

            var a_Position = webgl.getAttribLocation(webgl.program, 'a_Position');
            var a_Color = webgl.getAttribLocation(webgl.program, 'a_Color');

            var buffer = webgl.createBuffer();
            webgl.bindBuffer(webgl.ARRAY_BUFFER, buffer);
            webgl.bufferData(webgl.ARRAY_BUFFER, vertexData, webgl.STATIC_DRAW);
            webgl.vertexAttribPointer(a_Position, 3, webgl.FLOAT, false, FSIZE * 6, 0);
            webgl.vertexAttribPointer(a_Color, 3, webgl.FLOAT, false, FSIZE * 6, FSIZE * 3);
            webgl.enableVertexAttribArray(a_Position);
            webgl.enableVertexAttribArray(a_Color);

            return n;
        }


        function setMVPMatrix(webgl, canvas) {
            var u_mvpMatrix = webgl.getUniformLocation(webgl.program, 'u_MVPMatrix');
            var modelMatrix = new Matrix4();
            var viewMatrix = new Matrix4();
            var projMatrix = new Matrix4();
            var mvpMatrix = new Matrix4();
            modelMatrix.setRotate(45, 0, 0, 1);
            viewMatrix.setLookAt(-0.20, 0.05, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
            projMatrix.setPerspective(45, canvas.width / canvas.height, 1, 100);
            
            mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix)
            webgl.uniformMatrix4fv(u_mvpMatrix, false, mvpMatrix.elements);
        }
    </script>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值