返回

WebGPU 立方体旋转的引擎盖下:透彻剖析运行奥秘

前端

一个新的旅程即将开始。这次,我们将在WebGPU中绘制3D图形。我们从一个简单的立方体开始,这个立方体将围绕着它的轴旋转。

为了绘制这个立方体,我们需要做的第一步是创建一个顶点缓冲区。这个缓冲区将包含立方体所有顶点的坐标。然后,我们需要创建一个片段着色器,它将决定立方体的颜色。最后,我们需要创建一个画布,并使用WebGL将我们的立方体绘制到画布上。

听起来似乎有些复杂,但其实并不难。让我们一步一步地分解这个过程。

首先,我们需要创建一个顶点缓冲区。这个缓冲区将包含立方体所有顶点的坐标。一个立方体有8个顶点,每个顶点都有三个坐标(x、y和z)。所以,我们的顶点缓冲区将有8*3=24个元素。

const 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,  // 后面的左上角
];

一旦我们创建了顶点缓冲区,我们需要创建一个片段着色器。这个着色器将决定立方体的颜色。我们的片段着色器将非常简单,它将只是输出一个固定的颜色。

const fragmentShaderSource = `
  precision mediump float;
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`;

最后,我们需要创建一个画布,并使用WebGL将我们的立方体绘制到画布上。

const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');

// 设置视口
gl.viewport(0, 0, canvas.width, canvas.height);

// 启用深度测试
gl.enable(gl.DEPTH_TEST);

// 编译并链接着色器程序
const program = gl.createProgram();
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);
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

// 创建顶点缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

// 创建索引缓冲区
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, 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  // 右侧
]), gl.STATIC_DRAW);

// 绑定顶点缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

// 获取顶点着色器的属性位置
const positionAttributeLocation = gl.getAttribLocation(program, 'position');

// 告诉WebGL如何从缓冲区中读取顶点数据
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

// 启用顶点属性
gl.enableVertexAttribArray(positionAttributeLocation);

// 使用着色器程序
gl.useProgram(program);

// 清空画布
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// 旋转矩阵
const rotationMatrix = glm.rotate(glm.mat4(), 0.01, glm.vec3(0, 1, 0));

// 将旋转矩阵传递给着色器程序
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'rotationMatrix'), false, rotationMatrix);

// 绘制立方体
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);

这就是我们绘制旋转立方体所需要做的全部工作。如果你遵循了这些步骤,你应该能够在你的浏览器中看到一个旋转的立方体。

我希望这篇文章对你有帮助。如果您有任何问题,请随时在评论中提问。