14初识WebGL | 青训营笔记

91 阅读2分钟

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

PPT: bytedance.feishu.cn/file/boxcnh…

Why WebGL / Why GPU

  • WebGL 是什么?

    • GPU ≠ WebGL ≠ 3D
  • webGL为什么不像其他前端技术那么简单?

Modern Graphics System

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

WebGL & OpenGL

WebGL 是 OpenGL 的子集

WebGL Startup

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

默认: WebGL中, 坐标系以中心为原点, X轴向右, Y轴向上, Z轴向外

坐标轴是归一化的, 即坐标绝对值最大为1

示例 绘制三角形

WebGL

code.juejin.cn/pen/7119692…

 // 1 创建 WebGL 上下文 (Create WebGL Context)
 const canvas = document.querySelector('canvas');
 const gl = canvas.getContext('webgl');
 ​
 // 2 利用着色器创建 WebGL Program (Create WebGL Program)
 ​
     //> 1 Vertex Shader 顶点着色器
 const vertex = `
     attribute vec2 position;
     varying vec4 color;
 ​
     void main() {
         gl_PointSize = 1.0;
         gl_Position = vec4(position, 1.0, 1.0);
         color = vec4(0.5 * (vec2(1.0) + position), 0.0, 1.0);
     }
 `;
 ​
 ​
     //> 2 Fragment Shader 片段着色器
 const fragment = `
     precision mediump float;
     varying vec4 color;
 ​
     void main() {
         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 相当于 #FF0000 不透明的红色
         // gl_FragColor = color;
     }
 `;
 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);
 ​
 ​
 // Data to Frame Buffer
 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);
 ​
 // Frame Buffer to GPU
 const vPosition = gl.getAttribLocation(program, 'position'); // 获取顶点着色器中position变量的地址
 gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0); // 给变量设置长度和类型
 gl.enableVertexAttribArray(vPosition); // 激活这个变量
 ​
 gl.clear(gl.COLOR_BUFFER_BIT);
 gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);

code.juejin.cn/pen/7119692…

2D

code.juejin.cn/pen/7119692…

canvas坐标系和浏览器一致, 左上角为原点

mesh.js (对WebGL封装)

code.juejin.cn/pen/7119692…

示例 应用线性变换

code.juejin.cn/pen/7119694…

Read More