WebGL 与动画实现 | 青训营笔记

74 阅读2分钟

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

WebGL 与动画实现

一.初识 WebGL

  • WebGL 是什么?

    • GPU != WebGL != 3D
  • WebGL 为什么不像其他前端技术那么简单?

    • 涉及到硬件的一些原理等

image-20220814213853574.png

  • 图形绘制

    1. 轮廓提取
    2. 网格化,平面三角网格、3D常见三角网格,多边形网格
    3. 网格图源光栅化
    4. 点阵数据送到帧缓存
    5. 接着读取帧缓存渲染到显示器上
  • CPU vs GPU

    • CPU,处理能力大的一个处理单元,一个管道对于CPU的一个核心,内核越多,同时处理的能力越大。
    • GPU,由小运算单元构成,每个运算单元只负责处理很简单的计算,每个运算单元彼此独立,因此所有计算可以并行处理

image-20220814214906899.png

OpenGL, OpenGL ES, WebGL, GLSL, GLSL ES API Tables (umich.edu)

二.使用 WebGL

使用 WebGL

  1. 创建 WebGL 上下文
  2. 创建 WebGL Program
  3. 将数据存入缓存区
  4. 将缓冲区读取到 GPU
  5. GPU 执行 WebGL 程序,输出结果
  1. const canvas = document.querySelector('canvas')
    const gl =canvas.getContext('webgl')
    ​
    //老浏览器兼容
    function create3DContext(canvas,options) {
        const names = ['webgl','experimental-webgl','webkit-3d','moz-webgl'];
        if(options.webgl2) name.ynshift('webgl');
        let context =null;
        for(let ii = 0; ii < namer.length; ++ii) {
            try {
                context = canvas.getContext(names[ii],options);
            } catch (e) {
                // no-empty
            } 
            if(context) {
                break;
            }
        }
        return context;
    }
    
  2. // 1.Vertex Shader 顶点着色器,处理图像轮廓
    const vertex =
    attribute vec2 position;
    varying vec4 color;
    ​
    void main() {
        gl_PointSize = 1.0;
        gl_Position = vec4(position,1.0,1.0)
    }
    ;
    // 2.Fragment Shader 片元着色器,把轮廓处理好后把像素点光栅化后映射到片源着色器来处理颜色
    const fragment =
    precision mediump float;
    varying vec4 color;
    ​
    void main() {
        gl_FragColor  vec4(1.0,0.0,0.0,1.0);
    }
    ;
    
  3. 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 ( fr agmentShader );
    ​
    const program = gl.createProgram( );
    gl.attachShader( program, vertexShader );
    gL. attachShader( program, fr agmentShader );
    gl. linkProgram( program);
    ​
    gl.useProgram( program);
    

image-20220814220942904.png

以中心点为坐标系,同时也有z轴;

x、y轴最小坐标是-1,最大坐标是1

一般情况下把图形通过顶点坐标来描述

创建一个三角形,有三个顶点,存在类型数组里

const points = new Float32Array([
    -1,-1,
    0,1,
    1,1,
])
//送到缓冲区
const bufferId = gl.createBuffer();
gl.bindBuffer( gL.ARRAY_BUFFER,bufferId);
gl.bufferData( gl.ARRAY_BUFFER,points, gl.STATIC_DRAW);
​
//通过着色器进行执行

image-20220814221807976.png

const vPosition = gl.getAttribLocation(program,'position');
gl.vertexAttribPointer(vPosition,2,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(vPosition)
l.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES,0,points.length / 2);

只绘制一个纯色 2D 三角形时,性能都差不多。

但是有渐变这些时,WebGL 使得性能更佳,在绘制更多的三角形时,性能差别更大!

image-20220814224104038.png

  • 绘制多边形:

    使用 Earcut 进行三角剖分分。

  • 绘制 3D :

    模型数据离线的用设计工具处理好,将三角形数据导出,然后导入WebGL的代码里面去。不会实时的对物体进行三角剖分

  • Transforms 处理平移/旋转/缩放

image-20220814224921412.png

image-20220814224800241.png

  • 3D标准模型的四个其次矩阵 (mate4)

    1. 投影矩阵 Projection Matirix
    2. 模型矩阵 Model Matrix
    3. 视图矩阵 View Matrix
    4. 法向量矩阵 Normal Matrix

书籍推荐:

  1. The Book of Shaders
  2. github.com
  3. Glsl Doodle (webgl.group)
  4. SpriteJS ~ Next - 下一代 SpriteJS
  5. 三.js – JavaScript 3D Library (threejs.org)
  6. Shadertoy BETA