初识WebGL|青训营笔记

93 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第5天。

写在前面

WebGL 是一种 JavaScript API。由于 WebGL 技术旨在帮助我们在不使用插件的情况下在任何兼容的网页浏览器中开发交互式 2D 和 3D 网页效果。WebGL知识密度很大,完全足矣以一整个体系来写,在这里我借着课程的体系,只能说初步认识WebGL的部分生态。

现代图形系统

WebGL 运行在电脑的 GPU 中,因此需要使用能在 GPU 上运行的代码,这样的代码需要提供成对的方法,每对方法中的一个叫顶点着色器而另外一个叫做片元着色器,并且使用 GLSL 语言。

image.png

Screen Shot 2022-08-13 at 11.29.10 PM.png

而处理完数据,经过处理器把数据处理成Frame帧流模式,最后绘制成像素点。

Screen Shot 2022-08-13 at 11.41.37 PM.png

开始使用WebGL绘制图像

一段完整的 WebGL 程序,至少包括 HTML、JavaScript 和 OpenGL 着色器代码(GLSL),其中 HTML 代码主要提供一个 Canvas 画布;JavaScript 用来获取 WebGL 的上下文,对模型顶点的坐标、颜色等信息进行处理,并将这些处理好的数据传递给 GPU ;GLSL 是一种类 C 的着色器编程语言,主要包括两大部分,即顶点着色器和片元着色器。

Screen Shot 2022-08-13 at 11.43.16 PM.png

下面以绘制一个三角形作为示例。

创建上下文声明一个canvas画布

<canvas id="webgl" width="500" height="300" style="border: 1px solid;"></canvas>

获取WebGL上下文

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

声明着色器

// 着色器源码
const vertexShaderSource = `
  // 声明一个属性变量 a
  attribute vec3 a;
  void main() {
    // 顶点在作色器处理后的位置信息
    gl_Position = vec4(a, 1.0);
  }    
`;

const fragmentShaderSource = `
  void main() {
      // 片段颜色
      gl_FragColor = vec4(0.1, 0.7, 0.3, 1.0);
    }
`;

建立program

 // 初始化着色器方法
 function initShader(gl, vertexSource, fragmentSource) {
   const vertexShader = gl.createShader(gl.VERTEX_SHADER);
   const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
   // 将着色器源码附加到着色器上
   gl.shaderSource(vertexShader, vertexSource);
   gl.shaderSource(fragmentShader, fragmentSource);

  // 编译着色器
  gl.compileShader(vertexShader);
  gl.compileShader(fragmentShader);

  // 创建一个程序对象
  const program = gl.createProgram();
  // 将编译好的着色器附加到程序对象上
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  // 链接程序对象
  gl.linkProgram(program);
  // WebGL引擎使用该程序对象
  gl.useProgram(program);

  return program;
}

 const program = initShader(gl, vertexShaderSource, fragmentShaderSource);

输出


function sendDataToSharder(gl, data) {
 // 将顶点数据写入缓存区,并将数据传递给顶点着色器
 var vertexBuffer = gl.createBuffer();
 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
 var vertexAttribLocation = gl.getAttribLocation(program, "a");
 gl.vertexAttribPointer(vertexAttribLocation, 3, gl.FLOAT, false, 0, 0);
 // 设置通过顶点着色器将缓冲的输入数据转换为一系列顶点数组
 gl.enableVertexAttribArray(vertexAttribLocation);
}

// 定义顶点数据,这里定义了三角形的三个顶点坐标,以中心点为坐标原点,z 轴为 0
var data = [0.0, 0.5, 0.0, -0.5, -0.5, 0.0, 0.5, -0.5, 0.0];
sendDataToSharder(gl, data);
// 绘制缓冲数组
gl.drawArrays(gl.TRIANGLES, 0, 3);

图像变换

这些图形变换跟线性代数的关系比较大,对矩阵进行投影或者模运算时,相关的图像也会发生变化。而WebGL也是可以基于这些机制对图像进行变换操作。

Screen Shot 2022-08-13 at 10.14.21 PM.png

关于WebGL生态

WebGL的应用广泛,相比起普通的Canvas 2D,增加了许多图形绘制支持,并且许多开放的库比如说Three.js可以绘制很生动的3D图形。

Screen Shot 2022-08-13 at 11.32.47 PM.png

写在后面

WebGL是新一代web的探索,将使得web具有更丰富的表现力。当然,WebGL也与图像学息息相关,亦会是一个半「跨学科」的技术。与其说WebGL是前端工程的技术,不如说是图像三维在Web上的Open API。

此图来源 ushiroad.com/3j/ , 这样的架构也是WebGL真正意义上的图谱。

Screen Shot 2022-08-13 at 11.53.16 PM.png

参考

  1. juejin.cn/post/687511…
  2. zhuanlan.zhihu.com/p/40932600
  3. dev.opera.com/articles/in…