webGL 基础 
简单介绍 
- canvas 画布 二维 Canvas api 三维 web GL api
 - canvas.getContext('webgl');
 - canvas.getContext('webgl2');
 - webgl 是绘图协议,结合 html 显示 3d 图像
 - 可实现功能:数据可视化(图表)、图形/ 游戏引擎、图形渲染、地图、VR、场景展示、城市规划
 - 优势:内嵌在浏览器
 - 着色器是以字符串形式存储在 js 中
 - 开源框架的使用,避免兼容逻辑的麻烦
 
常见的 webGL 框架 
- three — webGL 库
 - Babylon — 图像引擎
 - kick — 游戏引擎
 - clayGL — 3D 应用
 - playCanvas — 网络游戏
 - WebGLStudio & Litescene — 图像编辑器
 - Luma — 数据可视化
 - A-Frame — AR
 
新的开始 
开启一个 webgl 除了原生提供的 api 还需要实现两 556688 个基础功能来减少开发流程中的重复代码:
- 通过上下文、顶点着色器和片元着色器片段(gl, vertex, fragment)来初始化渲染器;
 - 创建矩阵功能函数:平移、旋转、归一、点叉等;
 
这里的初始化过程其实就是将着色器代码关联着色器,然后将代码编译后绑定到一个新的程序中并使用它,而功能函数则是将三维信息做了一个可视化的形变效果。
js
/** 初始化着色器 */
function initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) {
	if (!gl) {
		alert("无法初始化webgl");
		return;
	}
	// 创建着色器
	const vertexShader = gl.createShader(gl.VERTEX_SHADER);
	const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
	// 关联着色器和着色器源码
	gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE);
	gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE);
	// 编译着色器
	gl.compileShader(vertexShader);
	gl.compileShader(fragmentShader);
	// 创建program
	const program = gl.createProgram();
	// 指定program的着色器
	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	// 关联着色器和program
	gl.linkProgram(program);
	// 使用着色器
	gl.useProgram(program);
	return program;
}绘制一个点 
创建一个顶点着色器
js
const VERTEX_SHADER_SOURCE = `
  void main() {
    gl_Position = vec4(0.0,0.0,0.0,1.0);
    gl_PointSize = 100.0;
  }
`;创建一个片元着色器
gl_PointCoord和gl_FragCoord是内置变量,gl_PointCoord表示当前片元在点上的位置,gl_FragCoord表示当前片元在屏幕上的位置。
js
const FRAGMENT_SHADER_SOURCE = `
  precision lowp float;
  float distanceSelf(vec2 a, vec2 b) {
    float x = a.x - b.x;
    float y = a.y - b.y;
    float v = x * x + y * y;
    return sqrt(v);
  }
  void main() {
    // 计算距离
    // float dis = distance(gl_PointCoord, vec2(0.5,0.5));
    float dis = distanceSelf(gl_PointCoord, vec2(0.5,0.5));
    if (dis > 0.5 || (dis < 0.4 && dis > 0.3) || dis < 0.2) {
      discard; // 丢弃片元
    }
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
  }
`;绘制
js
/**
 * void gl.drawArrays(mode, first, count);
 * mode: 指定绘制的方式,如点、线、三角形等
 * first: 指定从哪个顶点开始绘制
 * count: 指定绘制需要使用到多少个顶点
 */
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE); 初始化着色器
gl.drawArrays(gl.POINTS, 0, 1); // 绘制