WebGL入门课程06-三维世界

[TOC]

十五、进入三维世界

视点和视线

1582596069890

在WebGL中,利用视点,观察点,上方向这三个矢量创建一个视图矩阵

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三维世界</title>
    <style>
        #webgl{
            height: 500px;
            width: 500px;
        }
    </style>
    <script src="lib.js"></script>
    <script src="lib/cuon-matrix.js"></script>
</head>
<body>
<canvas id="webgl"></canvas>
<script>
    let canvas=document.getElementById("webgl");
    let gl=canvas.getContext('webgl');
    let VERTEX_SHADER=`
        attribute vec4 a_pos;
        attribute vec4 a_color;
        varying vec4 v_color;
        uniform mat4 u_ViewMatrix;
        void main(){
            gl_Position=u_ViewMatrix*a_pos;
            v_color=a_color;
        }`;
    let FRAG_SHADER=`
        precision lowp float;
        varying vec4 v_color;
        void main(){
            gl_FragColor=v_color;
        }`;
    let program=initShader(gl,VERTEX_SHADER,FRAG_SHADER);
    let dataVertices=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,0.4,1.0,0.4,

        0.5,0.4,-0.2,1.0,0.4,0.4,
        -0.5,0.4,-0.2,1.0,0.4,0.4,
        0.0,-0.6,-0.2,1.0,0.4,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,0.4,0.4,1.0,
    ]);
    let FSIZE=dataVertices.BYTES_PER_ELEMENT;
    let buffer=gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
    gl.bufferData(gl.ARRAY_BUFFER,dataVertices,gl.STATIC_DRAW);

    let a_pos=gl.getAttribLocation(program,'a_pos');
    let a_color=gl.getAttribLocation(program,'a_color');

    gl.vertexAttribPointer(a_pos,3,gl.FLOAT,false,FSIZE*6,0);
    gl.vertexAttribPointer(a_color,3,gl.FLOAT,false,FSIZE*6,FSIZE*3);

    gl.enableVertexAttribArray(a_pos);
    gl.enableVertexAttribArray(a_color);

    let u_ViewMatrix=gl.getUniformLocation(program,'u_ViewMatrix');
    let x=0.2,y=0.25,z=0.25;
    window.onkeydown=function(e){
        if(e.keyCode==39){
            x+=0.01;
        }
        if (e.keyCode==37){
            x-=0.01;
        }
        run();
    }

    function run() {
        let viewMatrix=new Matrix4();
        viewMatrix.setLookAt(x,y,z,0.0,0.0,0.0,0.0,1.0,0.0);
        gl.uniformMatrix4fv(u_ViewMatrix,false,viewMatrix.elements);
        gl.drawArrays(gl.TRIANGLES,0,9);
    }

</script>
</body>
</html>

从指定视点观察旋转后的图形

1582601709097

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三维世界</title>
    <style>
        #webgl{
            height: 500px;
            width: 500px;
        }
    </style>
    <script src="lib.js"></script>
    <script src="lib/cuon-matrix.js"></script>
</head>
<body>
<canvas id="webgl"></canvas>
<script>
    let canvas=document.getElementById("webgl");
    let gl=canvas.getContext('webgl');
    let VERTEX_SHADER=`
        attribute vec4 a_pos;
        attribute vec4 a_color;
        varying vec4 v_color;
        uniform mat4 u_ViewMatrix;
        uniform mat4 u_ModelMatrix;
        void main(){
            gl_Position=u_ViewMatrix*u_ModelMatrix*a_pos;
            v_color=a_color;
        }`;
    let FRAG_SHADER=`
        precision lowp float;
        varying vec4 v_color;
        void main(){
            gl_FragColor=v_color;
        }`;
    let program=initShader(gl,VERTEX_SHADER,FRAG_SHADER);
    let dataVertices=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,0.4,1.0,0.4,

        0.5,0.4,-0.2,1.0,0.4,0.4,
        -0.5,0.4,-0.2,1.0,0.4,0.4,
        0.0,-0.6,-0.2,1.0,0.4,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,0.4,0.4,1.0,
    ]);
    let FSIZE=dataVertices.BYTES_PER_ELEMENT;
    let buffer=gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
    gl.bufferData(gl.ARRAY_BUFFER,dataVertices,gl.STATIC_DRAW);

    let a_pos=gl.getAttribLocation(program,'a_pos');
    let a_color=gl.getAttribLocation(program,'a_color');

    gl.vertexAttribPointer(a_pos,3,gl.FLOAT,false,FSIZE*6,0);
    gl.vertexAttribPointer(a_color,3,gl.FLOAT,false,FSIZE*6,FSIZE*3);

    gl.enableVertexAttribArray(a_pos);
    gl.enableVertexAttribArray(a_color);

    let u_ViewMatrix=gl.getUniformLocation(program,'u_ViewMatrix');
    let u_ModelMatrix=gl.getUniformLocation(program,'u_ModelMatrix');
    let x=0.2,y=0.25,z=0.25,angle=0.0;
    window.onkeydown=function(e){
        if(e.keyCode==39){
            x+=0.01;
        }
        if (e.keyCode==37){
            x-=0.01;
        }
        if (e.keyCode==38){
            angle+=1;
        }
        run();
    }

    function run() {
        let viewMatrix=new Matrix4();
        let modelMatrix=new Matrix4();
        viewMatrix.setLookAt(x,y,z,0.0,0.0,0.0,0.0,1.0,0.0);
        modelMatrix.setRotate(angle,0,1,0);

        gl.uniformMatrix4fv(u_ViewMatrix,false,viewMatrix.elements);
        gl.uniformMatrix4fv(u_ModelMatrix,false,modelMatrix.elements);
        gl.drawArrays(gl.TRIANGLES,0,9);
    }

</script>
</body>
</html>