github编辑

WebGL基础

【第二届青训营-寒假前端场】- 「WebGL基础」,这节课老师非常详尽的讲解了WebGL的绘图及其相关库,展示了很多有意思的WebGL小项目

Why WebGL / Why GPU?

  • WebGL是什么?

    • GPU ≠ WebGL ≠ 3D

  • WebGL为什么不像其他前端技术那么简单?

现代的图像系统

  • 光栅(Raster):几乎所有的现代图形系统都是基于光栅来绘制图形的,光栅就是指构成图像的像素阵列

  • 像素(Pixel)一个像素对应图像上的一个点,它通常保存图像上的某个具体位置的颜色等信息。

  • 帧缓存(Frame Buffer):在绘图过程中,像素信息被存放于帧缓存中,帧缓存是一块内存地址。

  • CPU (Central Processing Unit):中央处理单元,负责逻辑计算

  • GPU (Graphics Processing Unit):图形处理单元,负责图形计算

image.png
  • 如上图,现代图像的渲染如图过程

  1. 轮廓提取/ meshing

  2. 光栅化

  3. 帧缓存

  4. 渲染

The Pipeline

image.png

GPU

  • GPU由大量的小运算单元构成

  • 每个运算单元只负责处理很简单的计算

  • 每个运算单元彼此独立

  • 因此所有计算可以并行处理

WebGL & OpenGL关系

OpenGL, OpenGL ES, WebGL, GLSL, GLSL ES API Tables (umich.edu)arrow-up-right

image.png

WebGL绘图步骤

步骤

  1. 创建WebGL上下文

  2. 创建WebGL Program

  3. 将数据存入缓冲区

  4. 将缓冲区数据读取到GPU

  5. GPU执行WebGL程序,输出结果

image.png

如图,针对几个单词进行解释:

  • Raw Vertices & Primitives 原始顶点&原语

  • Vertex Processor 顶点着色器

  • 运算后送到 片元着色器 进行处理:Fragment Processor

创建WebGL上下文

创建WebGL Program(The Shaders)

  1. Vertex Shader(顶点着色器)

    通过类型数组position,并行处理每个顶点的位置

  2. Fragment Shader(片元着色器)

    为顶点轮廓包围的区域内所有像素进行着色

其具体步骤如下:

  1. 创建顶点着色器和片元着色器代码:

  2. 使用 createShader()arrow-up-right 创建着色器对象

  3. 使用 shaderSource()arrow-up-right 设置着色器的程序代码

  4. 使用 compileShader()arrow-up-right 编译一个着色器

  5. 使用 attachShader() arrow-up-rightWebGLProgramarrow-up-right 添加一个片段或者顶点着色器。

  6. 使用 **linkProgram() arrow-up-right**链接给定的WebGLProgramarrow-up-right,从而完成为程序的片元和顶点着色器准备GPU代码的过程。

  7. 使用 useProgram()arrow-up-right 将定义好的WebGLProgramarrow-up-right 对象添加到当前的渲染状态

将数据存到缓冲区中(Data to Frame Buffer)

  • 坐标轴:webGL的坐标系统是归一化的,浏览器和canvas2D的坐标系统是以左上角为坐标原点,y轴向下,x轴向右,坐标值相对于原点。而webGL的坐标系是以绘制画布的中心点为原点正常的笛卡尔坐标系

通过一个顶点数组表示其顶点,使用 createBuffer()arrow-up-right 创建并初始化一个用于储存顶点数据或着色数据的WebGLBufferarrow-up-right对象并返回bufferId,然后使用 bindBuffer()arrow-up-right 将给定的 bufferId 绑定到目标并返回,最后使用**bufferData()arrow-up-right**,将数据绑定至buffer中。

读取缓冲区数据到GPU(Frame Buffer to GPU)

输出结果(Output)

Outputarrow-up-right

drawArrays()arrow-up-right 从向量数组中绘制图元

image.png

WebGL太复杂?其他方式

canvas 2D

看看人家canvas2D,绘制同样的三角形:

Mesh.js

mesh-js/mesh.js: A graphics system born for visualization 😘. (github.com)arrow-up-right

Earcut

使用Earcutarrow-up-right进行三角剖分

3D Meshing

由设计师导出给我们,再提取

SpriteJS/next - The next generation of spritejs.arrow-up-right

图形变换(Transforms)

这就是数字图像处理相关的知识了(学过的都还回来了.jpg)

平移

image.png

旋转

image.png

缩放

image.png

线性变换(旋转+缩放)

image.png
image.png

从线性变换到齐次矩阵

image.png

老师的又一个栗子:Apply Transformsarrow-up-right

3D Matrix

3D标准模型的四个齐次矩阵(mat4)

  1. 投影矩阵Projection Matrix(正交投影和透视投影)

  2. 模型矩阵Model Matrix (对顶点进行变换Transform)

  3. 视图矩阵View Matrix(3D的视角,想象成一个相机,在相机的视口下)

  4. 法向量矩阵Normal Matrix(垂直于物体表面的法向量,通常用于计算物体光照)

Read more

  1. The Book of Shadersarrow-up-right (介绍片元着色器,非常好玩的)

  2. Mesh.jsarrow-up-right (底层库,欸嘿)

  3. Glsl Doodlearrow-up-right (片元着色器的一个轻量库,有很多小demo)

  4. SpriteJSarrow-up-right (月影老师写的开源库orz)

  5. Three.jsarrow-up-right(很多有意思的游戏项目)

  6. Shadertoy BETAarrow-up-right(很多有意思的项目)

总结感想

这节课老师非常详尽的讲解了WebGL的绘图及其相关库,展示了很多有意思的WebGL小项目~

本文引用的大部分内容来自月影老师的课和MDN!月影老师,tql!

最后更新于

这有帮助吗?