初识 WebGL | 青训营笔记

105 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

初识 WebGL

Why WebGL / Why GPU

  • WebGL(Web Graphics Library)是一种基于 JavaScript 和 OpenGL 的图形库,它允许在 Web 浏览器中实时渲染 3D 和 2D 图形,从而使网页能够呈现出更加复杂和丰富的交互式图形效果。 WebGL 利用了浏览器中的 HTML5 Canvas 元素,并将其与 OpenGL ES 2.0 API 结合使用,以实现在 Web 浏览器中进行高性能的图形渲染。它提供了一套强大的 API,包括着色器(shader)、纹理(texture)和缓冲区对象(buffer objects),使开发者可以使用类似于 OpenGL 的方式来创建和控制图形渲染。 WebGL 可以在任何支持它的现代 Web 浏览器中使用,而不需要任何插件或其他附加组件。它在游戏、虚拟现实、数据可视化等领域有广泛的应用,是 Web 开发中一个非常有用的工具。

Modern Graphics System

  • 光栅 (Raster): 几乎所有的现代图形系统都是基于光栅来绘制图形的,光栅就是指构成图像的像素阵列。
  • 像素 (Pixel) :一个像素对应图像上的一个点,它通常保存图像上的某个具体位置的颜色等信息。
  • 帧缓存 (Frame Buffer): 在绘图过程中,像素信息被存放于帧缓存中,帧缓存是一块内存地址。
  • CPU (Central Processing Unit) : 中央处理单元,负责逻辑计算。
  • GPU (Graphics Processing Unit) : 图形处理单元,负责图形计算。

渲染流程:

  1. 轮廓提取
  2. 光栅化
  3. 帧缓存
  4. 渲染

WebGL Startup

  1. 创建 WebGL 上下文
  2. 创建 WebGL Program
  3. 将数据存入缓冲区
  4. 将缓冲区数据读取到 GPU
  5. GPU 执行 WebGL 程序,输出结果

创建 WebGL 上下文

const canvas = document.querySelector("canvas");
const gl = canvas.getContext("webgl");

function create3DContext(canvas, options) {
  const names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
  if (options.webgl2) snames.unshift("webgl2");
  let context = null;
  for (let ii = 0; ii < names.length; ++ii) {
    try {
      context = canvas.getContext(names[ii], options);
    } catch (e) {
      // no-empty
    }
    if (context) {
      break;
    }
  }
  return context;
}

Vertex Shader

attribute vec2 position;
void main() {
    gl_PointSize = 1.0;
    gl_Position = vec4(position, 1.0, 1.0);
}

Fragment Shader

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

创建 WebGL Program

const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragment);
gl.compileShader(fragmentShader);

const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);

gl.useProgram(program);

将数据存入缓冲区

const points = new Float32Array([-1, -1, 0, 1, 1, -1]);
const bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);

将缓冲区数据读取到 GPU

const vPosition = gl.getAttribLocation(program, "position"); // 获取顶点着色器中的 position 变量的地址
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0); // 给变量设置长度和类型
gl.enableVertexAttribArray(vPosition); // 激活这个变量
attribute vec2 position;

void main(){
    gl_PointSize = 1.0;
    gl_Position = vec4(position, 1.0, 1.0);
}

GPU 执行 WebGL 程序,输出结果

l.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);

总结

WebGL 是一种用于在网页上呈现 3D 图形的技术,它允许开发者在浏览器中使用 JavaScript 和 OpenGL ES API 来创建交互式 3D 应用程序。

WebGL 的基础知识包括 WebGL 渲染流程、WebGL 坐标系统、WebGL 着色器等。WebGL 渲染流程的基本过程包括创建 WebGL 上下文、设置视口、清除画布、设置投影矩阵、设置模型矩阵、设置顶点属性指针、绑定着色器程序、绘制图形等步骤。WebGL 坐标系统采用的是右手坐标系,坐标原点位于画布中心,坐标范围为 [-1, 1],其中 x 轴向右,y 轴向上,z 轴垂直于画布向外。WebGL 着色器包括顶点着色器和片元着色器,其中顶点着色器负责对每个顶点进行计算和处理,而片元着色器则负责对每个像素进行计算和处理,二者共同决定了每个图元的最终呈现效果。

WebGL 有很多有趣的应用场景,比如游戏、虚拟现实、数据可视化等。通过学习 WebGL,我不仅了解一种新的技术,还了解了更广泛的计算机图形学和计算机科学知识。我相信,在不断的实践和学习中,我会更深入地理解 WebGL 技术,并能够将它应用于更多的实际项目中。 总之,学习 WebGL 是一个具有挑战性但也非常有趣和有价值的过程。