走进 WebGL:描绘立体的正方体世界,踏入 3D 图形领域
2023-11-02 08:18:51
在计算机图形学的殿堂中,WebGL 闪耀着夺目的光彩,它赋予了浏览器呈现 3D 图形的能力,将虚拟世界栩栩如生地呈现在您的眼前。而正方体,作为三维空间中最基本、最具代表性的几何图形之一,是 WebGL 学习的理想起点。
在这个激动人心的篇章中,我们将携手踏上 WebGL 之旅,从搭建 WebGL 画布开始,一步步构建正方体的顶点数据和索引数据,并运用 WebGL 着色器为其赋予色彩。最终,您将掌握渲染正方体的奥秘,为进一步探索 3D 图形世界奠定坚实的基础。
WebGL 的舞台:画布的搭建
首先,我们需要搭建 WebGL 的舞台——画布。这块画布如同艺术家的调色板,等待着我们挥洒创意。通过创建一个
<canvas id="webgl-canvas"></canvas>
const canvas = document.getElementById('webgl-canvas');
const gl = canvas.getContext('webgl');
正方体的轮廓:顶点数据的构建
接下来,我们需要为正方体勾勒出轮廓,这需要用到顶点数据。顶点数据包含了正方体每个顶点的坐标信息,这些坐标点共同定义了正方体的形状。我们将使用一个 Float32Array 来存储这些顶点数据。
const vertices = new Float32Array([
// 前面
-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
]);
正方体的结构:索引数据的构建
有了顶点数据,我们还需要构建索引数据。索引数据定义了顶点之间的连接方式,告诉 WebGL 如何将顶点组合成三角形,从而形成正方体的各个面。
const indices = new Uint16Array([
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 // 右侧
]);
着色器的艺术:赋予正方体色彩
为了让正方体焕发生机,我们需要借助着色器。着色器是一种程序,用于处理顶点数据和片段数据,并最终生成像素颜色。我们将在顶点着色器中定义顶点位置的变换,并在片段着色器中定义像素的颜色。
顶点着色器
attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
片段着色器
precision mediump float;
uniform vec3 color;
void main() {
gl_FragColor = vec4(color, 1.0);
}
绘制正方体:将数据写入缓冲区
现在,我们需要将顶点数据和索引数据写入缓冲区。缓冲区是显卡中的内存区域,用于存储数据。我们将使用两个缓冲区:顶点缓冲区和索引缓冲区。
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
着色器的舞台:编译和链接
接下来,我们需要将着色器编译并链接到一个着色器程序中。着色器程序是包含顶点着色器和片段着色器的程序,用于处理图形数据。
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
渲染正方体:连接数据和着色器
现在,我们需要将顶点数据、索引数据和着色器程序连接起来,以便 WebGL 可以使用它们来渲染正方体。
gl.useProgram(program);
const positionLocation = gl.getAttribLocation(program, 'position');
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
const colorLocation = gl.getUniformLocation(program, 'color');
gl.uniform3f(colorLocation, 1.0, 0.0, 0.0);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
旋转正方体:增添动态效果
为了让正方体更加生动,我们可以通过旋转矩阵来控制正方体的旋转。
const modelViewMatrix = mat4.create();
mat4.rotate(modelViewMatrix, modelViewMatrix, rotationAngle, [0, 1, 0]);
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'modelViewMatrix'), false, modelViewMatrix);
结语
至此,我们已经完成了 WebGL 正方体渲染之旅。通过一步步的讲解,您已经掌握了 WebGL 的基本知识,包括画布搭建、顶点数据构建、索引数据构建、着色器编写、数据写入缓冲区、着色器编译和链接、连接数据和着色器、以及旋转正方体。相信您已经对 WebGL 有了初步的了解,可以继续探索 WebGL 的更多奥秘,创作出更加精彩的 3D 图形作品。