文章第一句话为“这是我参与「第四届青训营 」笔记创作活动的第4天
说实话我这小菜鸡平常做项目根本没用过convas和webgl的知识,这篇主要是记录下基本概念和一些一本的使用方法。
convas和webgl概述
Canvas API 提供了一个通过JavaScript 和 HTML的元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。是 HTML5 提供的一个特性,你可以把它当做一个载体,简单的说就是一张白纸。而 Canvas 2D 相当于获取了内置的二维图形接口,也就是二维画笔。Canvas 3D 是获取基于 WebGL的图形接口,相当于三维画笔。你可以选择不同的画笔在上面作画。
WebGL 允许工程师使用JS 去调用部分封装过的 OpenGL ES2.0 标准接口去 提供硬件级别的3D图形加速功能
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>
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个单位的高便是一个像素的高。
- webgl坐标系的坐标原点在画布中心。webgl坐标系的y 轴方向是朝上的。 webgl坐标基底中的两个分量分别是半个canvas的宽和canvas的高,即1个单位的宽便是半个个canvas的宽,1个单位的高便是半个canvas的高。
绘图步骤的区别
- convas
- 找一张画布。 // convas元素
- 找一支画笔。 // canvas.getContext('2d');
- 开始画画 // ctx.fillRect
- webgl
- 找一台电脑
- 找一块手绘板 // 将js转换为GLSL ES语言 program程序对象
- 找一支触控笔
- 开始画画
总结
综上所述,webgl 绘图好麻烦啊!但在3D渲染上又不学不行,以前用过一点three.js,未来想更深入的学习一下相关的领域,毕竟当初学前端就是为了炫酷