WebGL入门(十六)-三维视图模型原理,视点、视线、观察点、上方向

时间:2025-01-17 19:10:07
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <!--通过canvas标签创建一个800px*800px大小的画布--> <canvas id="webgl" width="800" height="800"></canvas> <script type="text/javascript" src="./lib/"></script> <script> //顶点着色器 var VSHADER_SOURCE = '' + 'attribute vec4 a_Position;\n' + //声明attribute变量a_Position,用来存放顶点位置信息 'attribute vec4 a_Color;\n' + //声明attribute变量a_Color,用来存放顶点颜色信息 'uniform mat4 u_ViewMatrix;\n' + //声明uniform变量u_ViewMatrix,用来存放视图矩阵 'varying vec4 v_Color;\n' + //声明varying变量v_Color,用来向片元着色器传值顶点颜色信息 'void main(){\n' + ' gl_Position = u_ViewMatrix * a_Position;\n' + //将视图矩阵与顶点坐标相乘赋值给顶点着色器内置变量gl_Position ' v_Color = a_Color;\n' + //将顶点颜色信息传给片元着色器, '}\n'; //片元着色器 var FSHADER_SOURCE = '' + '#ifdef GL_ES\n' + ' precision mediump float;\n' + // 设置精度 '#endif\n' + 'varying vec4 v_Color;\n' + //声明varying变量v_Color,用来接收顶点着色器传送的片元颜色信息 'void main(){\n' + //将varying变量v_Color接收的颜色信息赋值给内置变量gl_FragColor ' gl_FragColor = v_Color;\n' + '}\n'; //初始化着色器函数 function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE) { //创建顶点着色器对象 var vertexShader = gl.createShader(gl.VERTEX_SHADER); //创建片元着色器对象 var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); //引入顶点、片元着色器源代码 gl.shaderSource(vertexShader, VSHADER_SOURCE); gl.shaderSource(fragmentShader, FSHADER_SOURCE); //编译顶点、片元着色器 gl.compileShader(vertexShader); gl.compileShader(fragmentShader); //创建程序对象program var program = gl.createProgram(); //附着顶点着色器和片元着色器到program gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); //链接program gl.linkProgram(program); //使用program gl.useProgram(program); gl.program = program //返回程序program对象 return program; } function init() { //通过getElementById()方法获取canvas画布 var canvas = document.getElementById('webgl'); //通过方法getContext()获取WebGL上下文 var gl = canvas.getContext('webgl'); //初始化着色器 if (!initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { console.log('初始化着色器失败'); return; } // 设置canvas的背景色 gl.clearColor(0.0, 0.0, 0.0, 1.0); //清空canvas gl.clear(gl.COLOR_BUFFER_BIT); //初始化顶点坐标和顶点颜色 var n = initVertexBuffers(gl) //获取顶点着色器uniform变量u_ViewMatrix的存储地址 var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix') if (!u_ViewMatrix) { console.log('获取u_ViewMatrix的存储地址失败!'); return; } //初始化视图矩阵 var viewMatrix = new Matrix4() //设置视点、视线和上方向 viewMatrix.setLookAt(0.20, 0.25, 0.25, 0, 0, 0, 0, 1, 0) //将视图矩阵传给顶点着色器uniform变量u_ViewMatrix gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements) //绘制三角形 gl.drawArrays(gl.TRIANGLES, 0, n) } //初始化顶点坐标和顶点颜色 function initVertexBuffers(gl) { var verticesColors = 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, -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 vertexColorBuffer = gl.createBuffer(); if (!vertexColorBuffer) { console.log('创建缓冲区对象失败!') return -1 } //将顶点坐标和顶点颜色信息写入缓冲区对象 gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer) gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW) //获取类型化数组中每个元素的大小 var FSIZE = verticesColors.BYTES_PER_ELEMENT //获取顶点着色器attribute变量a_Position的存储地址, 分配缓存并开启 var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0) gl.enableVertexAttribArray(a_Position) //获取顶点着色器attribute变量a_Color(顶点颜色信息)的存储地址, 分配缓存并开启 var a_Color = gl.getAttribLocation(gl.program, 'a_Color'); gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3) gl.enableVertexAttribArray(a_Color) // 解绑缓冲区对象 gl.bindBuffer(gl.ARRAY_BUFFER, null); return verticesColors.length / 6 } init() </script> </body> </html>