WebGL 月影带练 | 青训营笔记

75 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天

WebGL 简介

WebGL≠GPU≠3D

现代图形系统

  • 光栅 构成图像的像素阵列
  • 像素 像素点保存图像上某个具体位置的颜色信息
  • 帧缓存 绘图过程中,像素信息被存放在帧缓存中
  • CPU 中央处理单元,负责逻辑计算
  • GPU 图形处理单元,负责图形计算

图形绘制过程

  • 轮廓提取 meshing
  • 光栅化
  • 帧缓存
  • 渲染

CPU vs GPU

  • CPU 核数量和处理管线相关
  • GPU 由大量小运算单元构成,每个小运算单元负责处理简单的运算,相互之前彼此独立,故所有计算可并行处理

WebGL 和 OpenGL

WebGL 是 OpenGL 在浏览器上的实现

WebGL 使用

WebGL 初始化

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

初始化 webgl

const canvas = document.querySelector('canvas')
const gl = canvas.getContext('webgl')

创建着色器

  • 顶点着色器 处理图形顶点
  • 片段着色器 处理图形片元
const vertex = `
  attribute vec2 position;

  void main () {
    gl_PointSize = 1.0;
    gl_Position = vec4(position, 1.0, 1.0);
  }
`

const fragment = `
  precision mediump float;

  void main () {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 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并使绑定着色器并绑定到webgl上
const program = gl.createProgram()
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
gl.useProgram(program)

创建图形 - 直线

const points = new Float32Array([
  -1, -1,
  0, 1,
  1, -1,
]) // Typed Array

const bufferId = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId)
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW)

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)

WebGL 工具及库

mesh.js

earcut