返回

WebGL世界入门指南:探索你的第一个 WebGL 程序

前端

在数字世界的汪洋中,WebGL 宛如一颗璀璨的明珠,将交互式 3D 图形带入了浏览器。它的出现,让开发者能够直接使用 JavaScript 来创建生动逼真的 3D 场景,在网页上呈现出令人惊叹的视觉效果。

想要领略 WebGL 的魅力,首先让我们从一个简单的 WebGL 程序开始。这个程序将清空画布,并用纯色填充它。这看似简单的操作,却能为我们打开 WebGL 世界的大门。

<!DOCTYPE html>
<html>
<head>
  
  <script type="text/javascript">
    "use strict";

    // 创建 WebGL 上下文
    var canvas = document.getElementById("glcanvas");
    var gl = canvas.getContext("webgl");

    // 定义顶点着色器代码
    var vertexShaderCode = `
      attribute vec2 a_position;
      void main() {
        gl_Position = vec4(a_position, 0.0, 1.0);
      }
    `;

    // 定义片段着色器代码
    var fragmentShaderCode = `
      void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
      }
    `;

    // 编译顶点着色器
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderCode);
    gl.compileShader(vertexShader);

    // 编译片段着色器
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderCode);
    gl.compileShader(fragmentShader);

    // 创建着色器程序
    var program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);

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

    // 定义顶点数据
    var vertexData = new Float32Array([
      -1.0,  1.0,
      -1.0, -1.0,
       1.0,  1.0,
       1.0, -1.0
    ]);

    // 创建顶点缓冲区
    var vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);

    // 定义顶点属性
    var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
    gl.enableVertexAttribArray(positionAttributeLocation);
    gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

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

    // 绘制三角形
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  </script>
</head>
<body>
  <canvas id="glcanvas" width="500" height="500"></canvas>
</body>
</html>

在 HTML 文件中,我们首先创建了一个画布元素,并为其指定了一个 ID。接下来,我们在 JavaScript 代码中获取这个画布元素,并通过 getContext() 方法获取 WebGL 上下文。

WebGL 上下文是 WebGL 的核心对象,它提供了操作 WebGL 的各种方法。有了这个上下文,我们就可以开始创建着色器程序了。

着色器程序由顶点着色器和片段着色器组成。顶点着色器负责处理顶点数据,而片段着色器负责处理片元数据。我们使用 createShader() 方法创建两个着色器,然后分别为它们设置代码并编译它们。

// 定义顶点着色器代码
var vertexShaderCode = `
  attribute vec2 a_position;
  void main() {
    gl_Position = vec4(a_position, 0.0, 1.0);
  }
`;

// 定义片段着色器代码
var fragmentShaderCode = `
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`;

在顶点着色器中,我们定义了一个名为 a_position 的顶点属性,并将其传递给内置变量 gl_Position。这将把顶点数据转换为裁剪空间坐标。

在片段着色器中,我们简单地设置片元颜色为红色。这样,当我们绘制三角形时,它将被填充为红色。

接下来,我们需要将着色器程序链接起来。这可以通过 linkProgram() 方法来完成。然后,我们使用 useProgram() 方法将着色器程序设置为当前活动的着色器程序。

// 创建着色器程序
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

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

现在,我们需要定义顶点数据。我们使用一个简单的矩形作为顶点数据,它由四个顶点组成。每个顶点由两个分量组成:x 坐标和 y 坐标。

// 定义顶点数据
var vertexData = new Float32Array([
  -1.0,  1.0,
  -1.0, -1.0,
   1.0,  1.0,
   1.0, -1.0
]);

我们使用 createBuffer() 方法创建一个顶点缓冲区,然后使用 bindBuffer() 方法将它绑定到 ARRAY_BUFFER。接下来,我们将顶点数据复制到缓冲区中,并使用 vertexAttribPointer() 方法将顶点属性与缓冲区中的数据关联起来。

// 创建顶点缓冲区
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexData, gl.STATIC_DRAW);

// 定义顶点属性
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

最后,我们可以使用 clearColor() 方法来清空画布,然后使用 clear() 方法来执行清空操作。接下来,我们使用 drawArrays() 方法来绘制三角形。

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

// 绘制三角形
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

现在,运行这个程序,你将在画布上看到一个红色的三角形。这就是你的第一个 WebGL 程序!

通过这个简单的示例,你已经掌握了 WebGL 的基本概念和技术。你可以继续学习更高级的 WebGL 技术,并构建出更加复杂的 3D 场景。