WebGL 的学习|青训营笔记

67 阅读2分钟

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

现代的图像系统

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

现代图像的渲染如图过程

  1. 轮廓提取
  2. 光栅化
  3. 帧缓存
  4. 渲染

GPU

  • GPU由大量的小运算单元构成
  • 每个运算单元只负责处理很简单的计算
  • 每个运算单元彼此独立
  • 因此所有计算可以并行处理

WebGL绘图步骤

  1. 创建WebGL上下文
const gl = canvas.getContext('webgl');
// 创建上下文, 注意兼容
function create3DContext(canvas, options) {
    const names = ['webgl', 'experimental-webgL','webkit-3d','moz-webgl'];  // 特性判断
    if(options.webgl2) names.unshift(webgl2);
    let context = null;
    for(let ii = 0; ii < names.length; ++ii) {
        try {
            context = canvas.getContext(names[ii], options);
        } catch(e) {
            // no-empty
        }
        if(context) {
            break;
        }
    }
    return context;
}

  1. 创建WebGL Program
  • Vertex Shader(顶点着色器):通过类型数组position,并行处理每个顶点的位置
void main() {
    gl_PointSize = 1.0;
    gl_Position = vec4(position, 1.0, 1.0);
}

  • Fragment Shader(片元着色器):为顶点轮廓包围的区域内所有像素进行着色
void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);//对应rgba(255,0,0,1.0),红色
}

  1. 将数据存入缓冲区
    坐标轴:webGL的坐标系统是归一化的,浏览器和canvas2D的坐标系统是以左上角为坐标原点,y轴向下,x轴向右,坐标值相对于原点。而webGL的坐标系是以绘制画布的中心点为原点,正常的笛卡尔坐标系。
    通过一个顶点数组表示其顶点,使用 createBuffer() 创建并初始化一个用于储存顶点数据或着色数据的WebGLBuffer对象并返回bufferId,然后使用 bindBuffer() 将给定的 bufferId 绑定到目标并返回,最后使用bufferData(),将数据绑定至buffer中。

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

  • getAttribLocation() 返回了给定WebGLProgram对象中某属性的下标指向位置。
  • vertexAttribPointer() 告诉显卡从当前绑定的缓冲区(bindBuffer()指定的缓冲区)中读取顶点数据。
  • enableVertexAttribArray() 可以打开属性数组列表中指定索引处的通用顶点属性数组。
  1. GPU执行WebGL程序,输出结果
gl.clear(gl.COLOR_BUFFER_BIT);  //清除缓冲的数据
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);