1. WebGL程序
    1. 用JavaScript写的控制代码
    2. 在GPU中执行的着色代码(GLSL)
      1. GLSL: OpenGL着色语言
        1. 负责记录着像素点的位置和颜色
        2. 两种着色器
          1. 顶点着色器
          2. 片段着色器
          3. 二者的集合,称为着色器程序
        3. 使用方式
          1. 通过GLSL编写着色器
          2. 把代码文本传递给WebGL
          3. 在GPU执行时编译
    3. WebGL中不论多么复杂的几何体最终都是由三角形构成
      1. 因此绘制之前都需要把物体进行三角形化(Triangulation),也就是把复杂的多边形分解成一个个三角形,再交由三角形绘制
  2. 着色器
    1. 顶点着色器
      1. GL物体构成
        1. 物体由一系列顶点组成
        2. 每个顶点都有位置和颜色信息
        3. 默认情况下
          1. 所有像素的颜色都由线性插值计算的来,自动形成平滑渐变
      2. 最基本任务
        1. 接收三维空间中的坐标,处理为二维空间中的坐标并输出
      3. 处理单元
        1. 单个顶点
    2. 片段着色器
      1. 最基本任务
        1. 对需要处理的屏幕上的每个像素,输出一个颜色值
    3. 初始化着色器
  3. GPU
    1. Graphics Process Unit
    2. 图形流水线
      1. 1. CPU发送指令
        1. 编译的着色器程序
        2. 几何数据
        3. 到位于显卡内的GPU
      2. 2. 顶点着色器执行
        1. 几何变换
        2. 光照计算
      3. 3. 若几何着色器位于图形处理器内,它便会修改一些几何信息
      4. 4. 计算后的几何模型被三角化(分隔为三角形)
      5. 5. 三角形被映射为2*2的像素块
    3. 渲染管线
    4. 并行计算
      1. 着色器被用来同时处理大量数据,比如屏幕上的一整块像素群,或者一个模型结构的所有顶点
  4. 关键字
    1. 作用描述符
      1. attribute
        1. 从缓冲中获取的数据
      2. uniform
        1. 在一次绘制中对所有顶点保持一致值
      3. varying
    2. 数据类型
      1. vec3
        1. 以三维向量的形式存储点在三维空间中的信息
      2. mat4
        1. 矩阵
    3. 像素着色器
      1. 也叫片段着色器
      2. color shader = fragment shader
  5. WebGL重要API
    1. 方法
      1. drawElements()
        1. void gl.drawElements(mode, count, type, offset)
        2. renders primitives from array data.
      2. drawArrays()
        1. renders primitives from array data.
        2. void gl.drawArrays(mode, first, count);
    2. 枚举
      1. 图元
        1. 三角形
          1. gl.TRIANGLES
          2. 最基本的三角形图元
          3. 绘制的三角形数量 = 顶点(索引数) / 3
          4. gl.TRIANGLE_STRIP
          5. 三角形带
          6. 绘制的三角形数量 = 顶点( 索引数) - 2
          7. ?
          8. 相比gl.TRIANGLES
          9. 可重用三角形之间的顶点。
          10. 在构建几何模型的三角形时,可以定义较少的顶点
          11. 意味着:从内存传送到CPU的数据量也较少
          12. 具有连续性
          13. gl.TRIANGLE_FAN
          14. 三角形扇
          15. 绘制的三角形数量 = 顶点(索引数) - 2
          16. 不常用
  6. 高性能WebGL原则
    1. gl.TRIANGLE_STRIP + 退化三角形 + IBO 优于 gl.TRIANGLES
      1. IBO
        1. drawElements
          1. 通过索引代替点数据
      2. TRIANGLE_STRIP
        1. 去除冗余点或冗余索引
      3. 退化三角形
      4. 示例
        1. 一个只包含100个三角形的小网格,而且只考虑顶点位置。由于只考虑顶点的位置,因此数组缓冲的每个元素占用12个字节的内存。如果面对的是一个很大的网格,而且还需要包括法线和纹理坐标,则使用gl.drawElements()方法和gl.TRIANGLE_STRIP图元的组合可以节省更多的内存。          重要的是,不要毫无必要地浪费内存,但是从性能角度来看,内存并不是唯一重要的因素。从性能角度来看,三角形绘制的顺序以及顶点数据的组织形式也是很重要的因素。
    2. 减少JS对WebGL API的调用
      1. 用Buffer换API调用次数
    3. 剔除背面
      1. 如果一个场景由许多对象组成,它们的背面对用户是不可见的,则最好激活背面剔除功能。这可以改善WebGL应用程序的性能,因为GPU不需要对不可见的三角形进行光栅化处理。
    4. 实例化技术
      1. 将数据一次性发送给GPU,然后告诉WebGL使用一个绘制函数,绘制多个物体
      2. 关键API
        1. drawElementsInstanced
        2. drawArrayInstanced
  7. 图形渲染管线
    1. 应用程序阶段
      1. CPU计算出model的
        1. 顶点坐标
        2. 法向量
        3. 纹理坐标
        4. 纹理
    2. 几何阶段
      1. 主要作用:将三维场景转换到二维。
        1. 空间转换
      2. 模型空间转世界空间
      3. 世界空间转视图空间
      4. 视图空间转齐次裁剪空间
      5. 顶点着色器
        1. 处理每个顶点,将顶点的空间位置投影在屏幕上,即计算顶点的二维坐标。
        2. 执行几何变换和光照计算
        3. 负责顶点的深度缓冲(Z-Buffer)的计算
        4. 掌控顶点的位置、颜色和纹理坐标等属性,但无法生成新的顶点
      6. primitive assembly 图元装配
        1. 图元装配指根据模型中顶点的原始连接关系还原出网格结构。网格由顶点和索引组成,根据索引将顶点连接在一起,组成线、面单元,然后再进行裁剪。OpenGL ES 支持点、线和面三种图元。
          1. primitive GL_POINTS、GL_TRIANGLES、GL_LINE_STRIP
      7. 几何着色器
        1. 处理顶点着色器中的输出数据
        2. 以从多边形网格中增删顶点,在着色器中生成新的顶点
        3. 它能够执行对CPU来说过于繁重的生成几何结构和增加模型细节的工作。
      8. 剪裁
        1. 可配置功能阶段,此阶段可以添加自定义的剪裁面
      9. 屏幕映射
        1. 齐次剪裁空间转窗口空间
          1. 顶点在齐次裁剪空间坐标系中的 x、y 值乘以窗口的长高,即可得到顶点在窗口空间中的二维坐标,即顶点在屏幕上的位置。
    3. 光栅化阶段
      1. 主要作用:确定几何阶段输出的各个primitive所覆盖的像素以及每个像素的颜色
      2. 三角形设定
        1. 几何阶段输出的都是三角形网格的顶点。
        2. 三角形设定阶段需要计算光栅化一个三角形网格所需要的信息。
        3. 具体就是计算三角形边界的表达方式。
      3. 三角形遍历
        1. 检查每个像素是否会被某个三角形覆盖。
        2. 如果被覆盖的画,就生成一个片元。
        3. 遍历阶段根据上一个阶段的计算结果,来判断三角网格覆盖了哪些像素,并使用三角网格的三个顶点的信息对覆盖区域的像素坐标进行插值
      4. 像素着色器
        1. 输入
          1. 三角形遍历阶段得到的各个像素中顶点信息的插值结果。
        2. 处理
          1. 场景光照
          2. 纹理采样
        3. 顶点着色器会输出每个顶点对应的像素坐标。
        4. 三角形遍历通过三角形的三个点的插值运算可以得到三角形内各个像素的纹理坐标,从而可以在像素着色器中确定各个像素在纹理上对应的颜色。
      5. 合并阶段
        1. 将像素着色器中生成的各个片段的深度和颜色与帧缓冲结合在一起
  8. 坐标系
    1. 世界坐标系(属于绝对坐标系)
    2. 物体坐标系(模型坐标系)
      1. 物体坐标系和世界坐标系的可以通过一个4*4的矩阵变换
    3. 摄像机坐标系(视图空间)
      1. 由摄像机可视范围组成的空间
          1. X轴
          2. 摄像机右方
          3. Y轴
          4. 摄像机上方
          5. Z轴
          6. 摄像机对准方向为负Z轴
        1. 组成
          1. 摄像机镜头方向
          2. 视角(fov)
          3. 近平面(near)
          4. 远平面(far)
        2. 锥形结构
          1. 使得三维物体在屏幕上呈现透视效果
        3. 和世界空间的关系
          1. 世界空间中的场景只有处于视图空间的部分才会在屏幕上呈现出来
          2. three.js中的应用
          3. 摄像机移动
          4. 移动摄像机坐标系
          5. 物体移动
          6. 移动物体在摄像机坐标系中的位置的变化
          7. 变换
          8. 默认情况下,视图坐标系原点即摄像机位于世界坐标系原点,并且坐标系方向与世界坐标系一致。故摄像机镜头初始朝向世界坐标系负Z轴,即垂直屏幕向内
  9. 名词解释
    1. 图元(primitive)
      1. 全称:图形输出原语(Graphics output primitive)
      2. 图元就是组成图像的基本单元
    2. 光栅化(Grating)
      1. 同:栅格化
      2. 利用光的衍射、投射、反射或模拟等,将向量图形格式转换成位图以用于在显示器或打印机输出的过程
      3. 光栅化
        1. 将顶点着色器输出的二维空间中的点坐标
        2. 转化为需要处理的像素
        3. 并传递为片段着色器的过程
    3. GLSL
      1. 图形语言着色器语言
    4. 退化三角形
      1. 两个顶点重叠的三角形面积为0,被GPU舍弃掉
    5. BO
      1. IBO
        1. 索引缓冲区对象(Index Buffer Object)
        2. 通过索引的方式达到去除冗余顶点数据的目的
      2. VBO
    6. WebGL缓冲区
      1. WebGL中的一块内存区域
      2. 我们一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用
    7. 数学名词
      1. 插值(interpolation)
        1. 一种通过已知的、离散的数据点,在范围内推求新数据点的过程或方法
      2. 向量
        1. 位置向量
          1. 相对于坐标系原点的位置矢量
        2. 法向量
          1. 法向量是空间解析几何的一个概念,垂直于平面的直线所表示的向量为该平面的法向量。 由于空间内有无数个直线垂直于已知平面,因此一个平面都存在无数个法向量(包括两个单位法向量)
        3. 行向量
        4. 列向量
      3. 空间变换
        1. 简单来讲是指顶点坐标向量乘以空间变换矩阵后得到的顶点坐标为转换后的空间中的坐标系上的坐标。比如对一个模型进行旋转平移变换。旋转平移的变换矩阵即为该模型的模型矩阵。用模型矩阵乘以该模型的顶点坐标,即对模型顶点坐标进行旋转和平移变换。运算后的顶点坐标就是在世界空间中的坐标,而顶点在自己模型空间中的坐标不变。
  10. 参考资料
    1. GPU 渲染管线简单总结(网上资料总结)
      1. https://juejin.im/post/5ad04f7e518825619d4d2ed4
    2. OpenGL坐标系理解
      1. https://www.jianshu.com/p/c9bcc84c0312
    3. 维基百科:着色器
      1. https://zh.wikipedia.org/wiki/%E7%9D%80%E8%89%B2%E5%99%A8
    4. WebGL中gl.drawArrays()与gl.drawElements()对比
      1. https://blog.csdn.net/u011294404/article/details/53605873
    5. WebGL基础绘制之二:绘制三角形
      1. http://www.jiazhengblog.com/blog/2016/02/19/2910/
    6. 高性能 WebGL —— 使用 ImageBitmap 提升纹理性能
      1. http://www.jiazhengblog.com/blog/2019/03/24/3407/
    7. WebGL 着色器和GLSL
      1. https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-shaders-and-glsl.html
    8. WebGL 工作原理
      1. https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-how-it-works.html
    9. WebGL2系列之实例数组(Instanced Arrays)
      1. https://segmentfault.com/a/1190000017048578