您的位置:首页 > 其它

webgl 图像处理 加速计算

2021-09-17 23:17 676 查看

webgl 图像处理

webgl 不仅仅可以用来进行图形可视化, 它还能进行图像处理

图像处理1---数据传输

webgl 进行图形处理的第一步: 传输数据到 GPU

下图为传输点数据到 GPU 并进行相应渲染的结果

数据传输过程

  1. 创建 canvas 元素, 用来承接 GPU 生成的数据
  2. 获取 context, program 用于操作数据和使用相应 API
  3. 初始化着色器, 将写的着色器编译进 program 总
  4. 发送数据, 将顶点数据, uv 数据, 等等数据, 均可以通过 sendData 方法将数据传输到 glsl 中的变量上 创建缓冲区
  5. 绑定缓冲区
  6. 向缓冲区中添加数据
  7. 将数据与 glsl 中的变量绑定
  8. 传输数据
  9. 所有传输数据的流程与此基本类似
  • 清除之前的颜色, 清除颜色缓冲区, 画出自己想要的图形
  • 下一阶段

    当前阶段实现了将基本数据传输给 GPU

    下一步是将 图像数据 传输到 GPU, GPU 接收到图像信息后获取每个像素点的颜色值, 通过卷积重置像素, 初步实现 webgl 的图形处理功能

    代码实现

    // 两种着色器
    const VSHADER_SOURCE = `
    attribute vec4 a_Position;
    attribute vec2 uv;
    varying vec2 vUv;
    void main(){
    // 进行插值计算
    vUv = uv;
    gl_Position = a_Position;
    }
    `;
    
    const FSHADER_SOURCE = `
    // 片元着色器中一定要声明精度
    precision mediump float;
    varying vec2 vUv;
    void main(){
    gl_FragColor = vec4(vUv.x, vUv.y, 0.6, 1.0);
    }
    `;
    
    init();
    
    function init() {
    const canvas = document.createElement("canvas");
    canvas.width = 200;
    canvas.height = 200;
    document.body.appendChild(canvas);
    
    // 获取 gl 环境
    const gl = canvas.getContext("webgl");
    if (!gl) {
    console.log("Fail to init content");
    return;
    }
    
    // webgl 程序
    const programe = gl.createProgram();
    
    // 初始化着色器
    initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE, programe);
    
    // 发送数据
    sendData("a_Position", 2, [-1, 1, -1, -1, 1, -1, 1, 1], gl, programe);
    
    sendData("uv", 2, [0, 1, 0, 0, 1, 0, 1, 1], gl, programe);
    
    // 刷新颜色
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    // 清除
    gl.clear(gl.COLOR_BUFFER_BIT);
    // 画图形
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
    }
    
    // 初始化着色器
    function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE, programe) {
    // 创建 shader
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    // 绑定资源
    gl.shaderSource(vertexShader, VSHADER_SOURCE);
    // 编译着色器
    gl.compileShader(vertexShader);
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER, FSHADER_SOURCE);
    gl.shaderSource(fragmentShader, FSHADER_SOURCE);
    gl.compileShader(fragmentShader);
    
    // 常规流程
    gl.attachShader(programe,
    56c
    vertexShader);
    gl.attachShader(programe, fragmentShader);
    gl.linkProgram(programe);
    gl.useProgram(programe);
    }
    
    // 发送数据到 GPU
    function sendData(name, size, arr, gl, programe) {
    // 获取地址空间
    const variate = gl.getAttribLocation(programe, name);
    if (variate < 0) {
    console.log(`Failed to get the location of ${name}`);
    return;
    }
    const variates = new Float32Array(arr);
    // 1. 创建缓存区
    const buffer = gl.createBuffer();
    if (!buffer) {
    console.log("Failed to create buffer");
    }
    // 2. 绑定缓存区
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    // 3. 向缓冲区中添加数据
    gl.bufferData(gl.ARRAY_BUFFER, variates, gl.STATIC_DRAW);
    // 4. 将缓冲区与 glsl 中变量绑定
    gl.vertexAttribPointer(variate, size, gl.FLOAT, false, 0, 0);
    // 5. 开始传输
    gl.enableVertexAttribArray(variate);
    }
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: