返回

用旋转打造动态 WebGL 世界

前端

在 WebGL 的奇幻之旅中,我们踏上了令人振奋的第十课,这次,我们深入挖掘顶点着色器,让我们的 3D 世界旋转起来,增添无限魅力。

旋转的魔力

旋转是计算机图形学中必不可少的技术,它赋予物体运动和动态感。在 WebGL 中,通过旋转矩阵,我们可以围绕任意轴旋转物体。

旋转矩阵

旋转矩阵是一个 4x4 矩阵,用于表示三维空间中的旋转。它通过一系列数学运算将一个点的坐标从一个坐标系变换到另一个坐标系中。

用顶点着色器实现旋转

在 WebGL 中,顶点着色器负责转换每个顶点的坐标。为了实现旋转,我们只需在顶点着色器中应用旋转矩阵即可。

void main() {
  // 获取顶点原始坐标
  vec4 position = vec4(a_position, 1.0);

  // 定义旋转矩阵
  mat4 rotationMatrix = mat4(
    cos(angle), -sin(angle), 0, 0,
    sin(angle), cos(angle), 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  );

  // 将原始坐标应用旋转矩阵
  gl_Position = rotationMatrix * position;
}

在这个顶点着色器中:

  • a_position 是顶点的原始坐标。
  • angle 是旋转角度,通常由用户输入或动画函数动态更新。
  • 旋转矩阵被定义为一个 4x4 矩阵,其中 cos(angle)sin(angle) 用于生成旋转变换。

实践出真知

现在,我们来将旋转应用到实际场景中。假设我们有一个立方体,我们想让它围绕 y 轴旋转。

// 定义立方体顶点
const cubeVertices = [
  // 前
  -1, -1,  1, 1, -1,  1, 1,  1,  1, -1,  1,  1,
  // 后
  -1, -1, -1, -1,  1, -1, 1,  1, -1, 1, -1, -1,
  // 上
  -1,  1, -1, -1,  1,  1, 1,  1,  1, 1,  1, -1,
  // 下
  -1, -1, -1, 1, -1, -1, 1, -1,  1, -1, -1,  1,
  // 左
  -1, -1, -1, -1, -1,  1, -1,  1,  1, -1,  1, -1,
  // 右
  1, -1, -1, 1, -1,  1, 1,  1,  1, 1,  1, -1
];

// 创建 WebGL 程序
const gl = createWebGLContext();

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

// 创建顶点着色器
const vertexShader = createVertexShader(vertexShaderCode);

// 创建片段着色器
const fragmentShader = createFragmentShader(fragmentShaderCode);

// 创建 WebGL 程序对象
const program = createProgram(vertexShader, fragmentShader);

// 获取顶点着色器的属性位置
const positionAttribLocation = gl.getAttribLocation(program, "a_position");

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

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

// 清空颜色缓冲区
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// 设置旋转角度
let angle = 0.0;

// 渲染函数
function render() {
  // 更新旋转角度
  angle += 0.01;

  // 清空颜色缓冲区
  gl.clear(gl.COLOR_BUFFER_BIT);

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

  // 设置顶点属性
  gl.vertexAttribPointer(positionAttribLocation, 3, gl.FLOAT, false, 0, 0);

  // 使用 WebGL 程序
  gl.useProgram(program);

  // 设置旋转角度
  gl.uniform1f(gl.getUniformLocation(program, "angle"), angle);

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

  // 循环渲染
  requestAnimationFrame(render);
}

// 开始渲染
render();

在这段代码中,我们首先定义了立方体的顶点坐标。然后,我们设置了顶点缓冲区,创建了顶点着色器和片段着色器。接着,我们创建了一个 WebGL 程序对象并启用了顶点属性。

最后,我们在 render() 函数中循环渲染立方体,更新旋转角度并应用旋转矩阵。这样,我们就可以让立方体围绕 y 轴旋转了。

探索更多可能性

旋转不仅仅局限于 y 轴,我们还可以围绕 x 轴或 z 轴旋转。通过结合多个旋转矩阵,我们可以实现更加复杂的旋转效果。

此外,我们可以通过使用 requestAnimationFrame() 函数控制旋转速度,或者添加用户输入来让用户控制旋转。

结语

掌握了顶点着色器中的旋转技术,我们就能在 WebGL 世界中创造充满动态感的物体。从旋转立方体到复杂的人物动画,旋转在计算机图形学中无处不在。通过不断的探索和实践,你将能够打造出令人惊叹的 WebGL 作品。