convas和webgl入门和基操 | 青训营笔记

144 阅读2分钟

文章第一句话为“这是我参与「第四届青训营 」笔记创作活动的第4天

说实话我这小菜鸡平常做项目根本没用过convas和webgl的知识,这篇主要是记录下基本概念和一些一本的使用方法。

convas和webgl概述

Canvas API 提供了一个通过JavaScript 和 HTML的元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。是 HTML5 提供的一个特性,你可以把它当做一个载体,简单的说就是一张白纸。而 Canvas 2D 相当于获取了内置的二维图形接口,也就是二维画笔。Canvas 3D 是获取基于 WebGL的图形接口,相当于三维画笔。你可以选择不同的画笔在上面作画。

WebGL 允许工程师使用JS 去调用部分封装过的 OpenGL ES2.0 标准接口去 提供硬件级别的3D图形加速功能

image.png

Canvas就是画布,只要浏览器支持,可以在canvas上获取2D上下文和3D上下文,其中3D上下文一般就是WebGL,当然WebGL也能用于2D绘制,并且WebGL提供硬件渲染加速,性能更好。 但是 WEBGL 的支持性caniuse还不是特别好,所以在不支持 WebGL 的情况下,只能使用 Canvas 2D api,注意这里的降级不是降到 Canvas,它只是一个画布元素,而是降级使用 浏览器提供的 Canvas 2D Api,这就是很多库的兜底策略,如 Three.js, PIXI 等

看些小案例

绘制红色正方型

convas版本

<!-- 画布 -->
<canvas id="map" width="200" height="200"></canvas>

<script>
    // 获取canvas元素
    var canvas = document.getElementById("map");
    // 获取渲染上下文
    var ctx = canvas.getContext("2d");
    // 绘制样式  红色
    ctx.fillStyle = "red";
    // API 绘制rect
    ctx.fillRect(10,10,100,100);
</script>  

image.png

webgl版本

<!-- 画布 -->
<canvas id="map" width="200" height="200"></canvas>

<!-- 顶点着色器 -->
<!-- 这里其实就画了一个顶点,只是这个顶点很大看起来是个正方形 -->
<!-- 怎么画四个边,现在还不会 -->
<script id="vertexShader" type="x-shader/x-vertex">
    void main() {
        gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
        gl_PointSize = 100.0;
    }
</script>
<!-- 片元着色器 像素颜色-->
<script id="fragmentShader" type="x-shader/x-fragment">
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
</script>
<script>
    // canvas 画布
    const canvas = document.getElementById("map");

    // webgl画笔
    const gl = canvas.getContext("webgl");
    // 顶点着色器
    const vsSource = document.getElementById("vertexShader").innerText;
    // 片元着色器
    const fsSource = document.getElementById("fragmentShader").innerText;
    // 初始化着色器
    initShaders(gl, vsSource, fsSource);
    // 指定将要用来清理绘图区的颜色
    // gl.clearColor(0, 0.0, 0.0, 1.0);
    // 清理绘图区
    gl.clear(gl.COLOR_BUFFER_BIT);
    // 绘制顶点
    gl.drawArrays(gl.POINTS, 0, 1);

    function initShaders(gl, vsSource, fsSource) {
        //创建程序对象
        const program = gl.createProgram();
        //建立着色对象
        const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
        const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
        //把顶点着色对象装进程序对象中
        gl.attachShader(program, vertexShader);
        //把片元着色对象装进程序对象中
        gl.attachShader(program, fragmentShader);
        //连接webgl上下文对象和程序对象
        gl.linkProgram(program);
        //启动程序对象
        gl.useProgram(program);
        //将程序对象挂到上下文对象上
        gl.program = program;
        return true;
    }

    function loadShader(gl, type, source) {
        //根据着色类型,建立着色器对象
        const shader = gl.createShader(type);
        //将着色器源文件传入着色器对象中
        gl.shaderSource(shader, source);
        //编译着色器对象
        gl.compileShader(shader);
        //返回着色器对象
        return shader;
    }
</script> 

convas2D和webgl在绘制时的区别

参考:WebGL 入门

不同的坐标系

  • convas canvas 2d 坐标系的原点在左上角。 canvas 2d 坐标系的y 轴方向是朝下的。 canvas 2d 坐标系的坐标基底有两个分量,分别是一个像素的宽和一个像素的高,即1个单位的宽便是1个像素的宽,1个单位的高便是一个像素的高。

image.png

  • webgl坐标系的坐标原点在画布中心。webgl坐标系的y 轴方向是朝上的。 webgl坐标基底中的两个分量分别是半个canvas的宽和canvas的高,即1个单位的宽便是半个个canvas的宽,1个单位的高便是半个canvas的高。

image.png

绘图步骤的区别

  • convas
    • 找一张画布。 // convas元素
    • 找一支画笔。 // canvas.getContext('2d');
    • 开始画画 // ctx.fillRect
  • webgl
    • 找一台电脑
    • 找一块手绘板 // 将js转换为GLSL ES语言 program程序对象
    • 找一支触控笔
    • 开始画画

总结

综上所述,webgl 绘图好麻烦啊!但在3D渲染上又不学不行,以前用过一点three.js,未来想更深入的学习一下相关的领域,毕竟当初学前端就是为了炫酷