返回
揭秘WebGL坐标系及深度:洞悉三维虚拟世界的奥秘
前端
2023-09-05 16:52:32
WebGL坐标系统
WebGL使用右手坐标系,如下所示:
+y
|
|
|
+x------>
|
|
|
+z
- x轴指向右。
- y轴指向向上。
- z轴指向向外。
WebGL中的坐标系原点位于屏幕的中心。x轴和y轴的范围从-1到1。z轴的范围从-1到1,其中-1表示最接近相机的平面,1表示最远处的平面。
WebGL深度
WebGL中的深度用于确定片段在屏幕上的前后顺序。较近的片段将在较远的片段之前绘制。深度范围从0到1,其中0表示最接近相机的片段,1表示最远处的片段。
WebGL坐标系及深度的相互关系
WebGL坐标系和深度紧密相关。片段在屏幕上的位置由其坐标和深度共同决定。较近的片段将在较远的片段之前绘制,即使较近的片段在屏幕上的坐标比较远的片段更靠后。
实例:使用WebGL坐标系和深度创建三维图形
以下是一个简单的WebGL程序,该程序创建一个旋转的立方体:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
// 顶点着色器
var vertexShaderSource = `
attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
// 片段着色器
var fragmentShaderSource = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// 创建WebGL上下文
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");
// 编译顶点着色器和片段着色器
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// 创建着色器程序
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 获取着色器程序中的属性和uniform变量
var positionAttribute = gl.getAttribLocation(program, "position");
var modelViewMatrixUniform = gl.getUniformLocation(program, "modelViewMatrix");
var projectionMatrixUniform = gl.getUniformLocation(program, "projectionMatrix");
// 创建立方体的顶点数据
var vertices = [
// 前面的顶点
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// 后面的顶点
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// 顶面的顶点
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// 底面的顶点
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// 左面的顶点
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
// 右面的顶点
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0
];
// 创建立方体的索引数据
var indices = [
0, 1, 2, 0, 2, 3, // 前面
4, 5, 6, 4, 6, 7, // 后面
8, 9, 10, 8, 10, 11, // 顶面
12, 13, 14, 12, 14, 15, // 底面
16, 17, 18, 16, 18, 19, // 左面
20, 21, 22, 20, 22, 23 // 右面
];
// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// 启用顶点属性数组
gl.enableVertexAttribArray(positionAttribute);
// 绑定顶点属性数组到缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(positionAttribute, 3, gl.FLOAT, false, 0, 0);
// 设置模型视图矩阵
var modelViewMatrix = mat4.create();
mat4.translate(modelViewMatrix, modelViewMatrix, [0.0, 0.0, -6.0]);
mat4.rotateX(modelViewMatrix, modelViewMatrix, degToRad(45));
mat4.rotateY(modelViewMatrix, modelViewMatrix, degToRad(30));
// 设置投影矩阵
var projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, 45, canvas.width / canvas.height, 0.1, 100.0);
// 清除颜色缓冲区和深度缓冲区
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// 使用着色器程序
gl.useProgram(program);
// 设置uniform变量
gl.uniformMatrix4fv(modelViewMatrixUniform, false, modelViewMatrix);
gl.uniformMatrix4fv(projectionMatrixUniform, false, projectionMatrix);
// 绘制立方体
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
</script>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>
该程序将创建一个旋转的立方体。您可以通过修改modelViewMatrix和projectionMatrix矩阵来改变立方体的旋转角度和位置。
结论
WebGL坐标系和深度是WebGL三维图形编程的基础知识。通过理解WebGL坐标系和深度,您可以创建出更复杂的三维图形。