WebGL入门课程06-三维世界
[TOC]
十五、进入三维世界
视点和视线
- 试点:观察者所在的三维空间中的位置
- 观察目标点:被观察目标所在的位置
- 视线:从视点出发穿过观察目标点继续延伸
- 上方向:最终绘制在屏幕上的映像中的向上的方向
在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>
从指定视点观察旋转后的图形
<!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>