webgl入门指南(一)
一、前言
本文基于MDN技术文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/WebGL_API
WebGL 是基于 OpenGL ES 规范的浏览器实现的JavaScript API 。能在任何兼容的Web浏览器中渲染高性能的交互式3D和2D图形。
可以在HTML5 <canvas>元素中使用。
二、基于webgl的开发的库有哪些
业界有很多基于WebGL开发了一些库,这里广东靓仔列举了一些:
基于webGL开发的库
1、three.js 开源的,功能齐全的3D WebGL库
2、RedGL 是一个开源3D WebGL库 (韩国)
3、vtk.js 是一个JavaScript库,用于在浏览器中进行科学可视
4、babylon.js 基于WebGL的图形引擎
5、Hightopo组件丰富,非开源的付费项目
Three.js的Demo图片预览
基于Three.js
三、WebGL绘制图形的5个流程
创建 WebGL 上下文
创建 WebGL 程序(WebGLProgram)
将数据存入缓冲区
将缓冲区数据读取到 GPU
GPU 执行 WebGL 程序,输出结果
我们来看看流程图:
下面我们通过一个Demo来讲解下,这里看不懂的小伙伴不着急,看完Demo回头再看看,会更容易理解。
四、Demo
html
<canvas width="300" height="300"></canvas>
js
html跟Canvas2D一样,我们使用<canvas>元素就可以了
// 调用canvas元素
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// 俩个着色器
const vertex = `
// 将缓冲区数据读取到GPU
attribute vec2 position; // 声明变量名威position的二维向量
varying vec3 color;
void main () {
gl_PointSize = 1.0;
color = vec3(0.5 + position * 0.5, 0.0);
gl_Position = vec4(position * 0.5, 1.0, 1.0);
}
`
const fragment = `
precision mediump float;
varying vec3 color;
void main () {
// RGBA 色值表示的四维向量数据
gl_FragColor = vec4(color, 1.0);
}
`
// 顶点着色器 片元着色器
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);
// 创建program并关联两个shader
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 启用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) // 将数据写入缓冲区对象
// 获取顶点着色器中的position变量的地址
const vPosition = gl.getAttribLocation(program, 'position');
// 给变量设置长度和类型
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
// 激活这个变量
gl.enableVertexAttribArray(vPosition);
// 执行着色器完成绘制
gl.clear(gl.COLOR_BUFFER_BIT); // 清空<canvas>
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2); // 绘制三角形
效果如下
demo详解
创建 WebGL直接调用 canvas 元素的 getContext 即可
将参数从2d换成webgl,代码如下:
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl')
从效果图我们可以看到由三个顶点,绘制成一个三角形。
WebGL就是以顶点和图元来绘制几何图形的。
顶点容易理解,图元是 WebGL
可直接处理的图形单元,具体的有7种:
点 gl.POINTS
线段 gl.LINES
线条 gl.LINE_STRIP
回路 gl.LINE_LOOP
三角形 gl.TRIANGLES
三角带 gl.TRIANGLE_STRIP
三角扇 gl.TRIANGLE_FAN
复杂的图形就是由这7个图元拼成的。
效果图里面三角形的颜色就是由顶点着色器、片元着色器处理的。
顶点着色器:它可以改变顶点的信息,从而改变我们绘制出来的图形的形状或者大小等等。
片元着色器:处理光栅化后的像素信息。
光栅化:从顶点着色器和图元提取像素点给片元着色器执行代码的过程。
我们结合代码来理解这概念
顶点着色器和片元着色器代码片段
// 顶点着色器
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);
WebGLProgram 对象的创建过程主要是添加 vertexShader 和 fragmentShader,然后将这个 WebGLProgram 对象链接到 WebGL 上下文对象上
// 创建program并关联两个shader
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
启用这个 WebGLProgram 对象
// 启用program
gl.useProgram(program);
定义好的数据写入 WebGL 的缓冲区
// 定义三个顶点,类型化数组
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) // 将数据写入缓冲区对象
上面代码中,Float32Array,是一个类型化数组。含义即类型化数组对象描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)。
顶点着色器
// 将缓冲区数据读取到GPU
attribute vec2 position; // 声明变量名position的二维向量
varying vec3 color;
void main () {
gl_PointSize = 1.0;
color = vec3(0.5 + position * 0.5, 0.0);
gl_Position = vec4(position * 0.5, 1.0, 1.0);
}
attribute 表示声明变量,vec2、vec3 是变量的类型,它表示一个二维向量、三维向量,position 是变量名。
把数据绑定给顶点着色器中的 position 变量
// 获取顶点着色器中的position变量的地址
const vPosition = gl.getAttribLocation(program, 'position');
// 给变量设置长度和类型
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
// 激活这个变量
gl.enableVertexAttribArray(vPosition);
执行着色器程序来完成绘制
// 执行着色器完成绘制
gl.clear(gl.COLOR_BUFFER_BIT); // 清空<canvas>
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2); // 绘制三角形
先调用 gl.clear 将当前画布的内容清除,然后调用gl.drawArrays。gl.drawArrays里参数分别表示:
gl.TRIANGLES 表示以三角形为图元绘制、绘制的顶点偏移量、顶点数量
webgl其他知识
1、颜色
2、图案
3、纹理
3、3d(vec3三维)
4、相机
5、光照
等
五、总结
在我们阅读完官方文档后,我们要深入学习,可以着重去掌握以下内容:
坐标系转换
参数方程(圆锥曲线、贝塞尔曲线(二、三阶))
向量(叉乘、点乘)
矩阵
作者:广东靓仔
欢迎关注:前端早茶