webGL | 青训营笔记

95 阅读3分钟

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

1.重点知识

  • 什么是webGL?
  • 计算机图形学
  • GPU和CPU
  • 使用webGL

2.详细知识

2.1 什么是webGL?

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。

2.2 计算机图形学

现代图形系统绘制图形的流程是:

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

QQ截图20230217182538.png

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

2.3 CPU与GPU

CPU即中央处理单元是作为计算机系统的运算和控制核心,具有很强大的运算功能

GPU图形处理单元又称显示核心,视觉处理器,等是一种专门用作与图像处理图形运算相关联的微处理器

我们可以将CPU 想象成一根很大的管道, 通过的数据的体积可以很大,可以进行很复杂的计算,但是数量很少,而GPU是管道很小,但是数量很多,虽然只只能处理很简单的数据, 但是每个运算单元都是彼此独立的,所有计算可以并行处理

QQ截图20230217184505.png

2.4 使用webGL

选择canvas元素,绑定webGL上下文

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

定义顶点着色器

const vertex = `attrubute verc2 position;
void main(){
    gl_PointSize = 1.0;
    gl_Position = vec4()
}
`

定义片段着色器

const fragment = `precision highp float;

   void main(){
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
   }
`

创建顶点着色器对象和片段着色器着色器对象, 并编译成二进制数据

// 创建顶点着色器对象
const vertexShader = gl.createShader(gl.VERTEX_SHADER)
// 为着色器对象设置 GLSL 程序代码
gl.shaderSource(vertexShader, vertex)
// 编译一个 GLSL 着色器,使其成为为二进制数据,然后就可以被WebGLProgram对象所使用
gl.compileShader(vertexShader)

// 判断报错
if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
  const info = gl.getShaderInfoLog(vertexShader)
  throw new Error('Could not compile WebGL program. \n\n' + info)
}

// 片段着色器
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)

//完成为程序的片元和顶点着色器准备 GPU 代码的过程
gl.linkProgram(program)

使用着色器

gl.useProgram(program)

// 三个顶点的位置
const points = new Float32Array([-1, -1, 0, 1, 1, -1])

// 创建并初始化一个用于储存顶点数据或着色数据的WebGLBuffer对象
const bufferId = gl.createBuffer()
// 将给定的WebGLBuffer绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId)
// 创建并初始化了 Buffer 对象的数据存储区
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW)

// 返回了给定WebGLProgram对象中某属性的下标指向位置
const vPosition = gl.getAttribLocation(program, 'position')
// 告诉显卡从当前绑定的缓冲区, 每个顶点区域(每个顶点属性的组成数量为2)
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0)
// 使用
gl.enableVertexAttribArray(vPosition)

最终效果:

QQ截图20230217222220.png