小宝宝也一看就会的WebGL基础 | 青训营笔记

94 阅读3分钟

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

前言

众所周知,我们看到的网页基本上没有静态的,一定充斥着各种各样的动画和效果。那么这些动画效果怎么做捏,就需要我们的WebGL来发挥作用了。

计算机图形学基础

众所周知,电脑中有一个叫做显卡的部件,显卡的主要作用就是渲染画面,一个画面的产生主要有轮廓提取、光栅化、帧缓存和渲染这几个部分,这种工作并不适合CPU来处理,所以就单独产生了一种叫做GPU的东西。GPU的工作方式和CPU区别很大,特点是所有的运算可以并行处理。

WebGL概念与流程

WebGL是一种基于OpenGL的工具,通过JavaScript把OpenGL转换成能够在网页上使用并渲染的动画。

WebGL的工作流程大概是:创建WebGL上下文、创建WebGL Program、将数据存入缓冲区、将数据缓冲区读取到GPU、GPU执行WebGL程序输出结果。

创建一个WebGL程序

一个完整的 WebGL 程序至少包括 HTML、JavaScript 和 OpenGL 着色器代码这几个部分。其中 HTML 代码主要提供一个 Canvas 画布;JavaScript 用来获取 WebGL 的上下文,对模型顶点的坐标、颜色等信息进行处理,并将这些处理好的数据传递给 GPU ;GLSL(也就是OpenGL着色器代码) 是一种类似于C语言的的着色器编程语言,主要包括两大部分:顶点着色器和片元着色器。下面我们通过一个绘制三角形的 WebGL 的示例,来了解一下 WebGL 程序吧。

第一步就是声明一个Canvas画布:

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

之后就需要在脚本中获取 WebGL 上下文:

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

然后就需要编写顶点着色器的代码和片元着色器代码:

const vertexShaderSource = `
  attribute vec3 a;
  void main() {
    gl_Position = vec4(a, 2.0);
  }    
`;

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

在这写编写完之后,就需要声明使用着色器代码:

 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);
  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);
}
var data = [0.0, 1.o, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0];
sendDataToSharder(gl, data);

最后一步就可以绘制图形啦!

gl.drawArrays(gl.TRIANGLES, 0, 3);

使用WebGL的优势

WebGL完美地解决了现有的Web交互式动画的两个问题:第一,它通过HTML脚本本身实现Web交互式三维动画的制作,无需任何浏览器插件支持;第二,它利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、标准的、跨平台的OpenGL接口实现的。

总结

我们在网页中可以创造很多丰富多彩的效果,而WebGL就是其中的一个,所以说我们可以通过学习这个组件,来让我们的网页展现出更加丰富多彩的效果捏。