初识 WebGL 小记

什么是 WebGL ?

WebGL 是一门能够在浏览器中渲染 3D/2D 图形的技术。它提供一套 JavaScript API,使用在 canvas元素上,从而使得 Web 开发者能够在浏览器中无需借助插件便可绘制3D图形。javascript

虽然开发使用的是 JavaScript 接口,但最终调用的是硬件设备底层 OpenGL 库相关的接口,而且有硬件加速,因此 WebGL 渲染要比通常的 Canvas 2D 渲染性能高不少。html

WebGL 与 OpenGL、OpenGL ES ?

这里了解一下 OpenGL。根据 MDN 上的描述,OpenGL (Open Graphics Library) 是一套用来渲染2D和3D矢量图形的跨语言的、跨平台的应用程序接口(API) 。其实 OpenGL 是一套规范而不是接口,接口的实现要靠各硬件厂商,这里的硬件厂商主要指 GPU 生产商,由于 OpenGL 库指令是运行在GPU中的,各个 GPU 厂商若是要支持 OpenGL 的话,就须要按照规范去实现本身的 OpenGL 库。各个厂家的 OpenGL 库其实是他们整合本身的图形知识以及 GPU 硬件指令而实现的,这些实现一般被称为“驱动”,负责将 OpenGL 定义的 API 命令翻译为 GPU 运行指令,因此使用时只须要安装显卡驱动便可。前端

WebGL 根植于 OpenGL,但它们中间还隔着一个 OpenGL ES。OpenGL ES 是 OpenGL 的子集,专门针对手机/PDA/游戏主机等嵌入式设备设计的。OpenGL ES 主要直接提供 C 语言的 api,其余平台能够根据习惯加一层包装,好比安卓提供了 Java 的包装, IOS 提供了 Objective-C 的包装。而 WebGL 就是基于 OpenGL ES 2.0 的 JavaScript API,也能够说是 OpenGL ES 经过增长一个 JavaScript 绑定而实现了 WebGL。java

学习 WebGL 须要学习什么 ?

使用 WebGL 绘图主要利用 WebGL API 和 canvas 元素,WebGL API 是 JavaScript 语言的,这点对于前端而言不在话下的。前面提到 OpenGL 是运行在 GPU 中的,但不是全部编程语言都能运行在 GPU 上,这就须要用到特殊的编程语言,即 着色器语言,着色器语言用于计算机图形编程,运行在GPU中,而平时所说的大多数语言编写的程序都是运行在 CPU 中的。与 OpenGL API 相配合的是着色器语言 GLSL,与 OpenGL ES API、WebGL API 相互配合的是着色器语言 GLSL ES。因此咱们还须要学习 GLSL ES 这门语言。web

可能有人会疑问,说好的使用 JavaScript 开发,怎么还要学习新编程语言,这个 GLSL ES 也能运行在浏览器中吗?GLSL ES 不能在浏览器环境运行,只是咱们会借助 WebGL API 将编写好的 GLSL ES 程序传入底层设备运行,最终借助系统显卡来在浏览器里更流畅地展现图形场景,这样既达到了高性能,又不须要浏览器插件的支持。编程

WebGL 与 Three.js ?

不少人都听过 Three.js 的大名,知道它是用来作 3D 图形的,其实 Three.js 是基于原生 WebGl API着色器封装获得的 3D 引擎,是一个 JavaScript 库。直接经过原生 WebGL 编写会比较麻烦,还须要写 GLSL ES 的程序,因此开发项目通常直接使用 Three.js 引擎。可是若是想深刻 Web3D 应用开发,学习底层 WebGL 和着色器 GLSL 知识仍是颇有必要的。canvas

小试牛刀

笔者也是刚了解 webgl,这段实践代码也是参考网上资料得来,已经加了注释。直接复制这段 html 代码在浏览器中执行便可,能够自行修改相关参数,查看显示效果,具体知识点留待后续文章记录。api

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL 画一个点</title>
</head>

<body>
    <canvas id="canvas" width="500" height="500"></canvas>

    <script> // 获取画布 const canvas = document.getElementById('canvas'); // 获取 webgl 上下文 const gl = canvas.getContext('webgl'); /* 下面两个着色器源码以字符串形式存着,供 webgl api 调用 */ //顶点着色器源码 const vertexShaderSource = '' + 'void main(){' + //给内置变量gl_PointSize赋值像素大小 ' gl_PointSize=20.0;' + //顶点位置,位于坐标原点 ' gl_Position =vec4(0.0,0.0,0.0,1.0);' + '}'; //片元着色器源码 const fragShaderSource = '' + 'void main(){' + //定义片元颜色 ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' + '}'; //初始化着色器 const program = initShader(gl, vertexShaderSource, fragShaderSource); // 指定将要用来清空绘图区域的颜色 gl.clearColor(0,1,0,0.5); // 使用以前指定的颜色,清空绘图区 gl.clear(gl.COLOR_BUFFER_BIT); //开始绘制,显示器显示结果 gl.drawArrays(gl.POINTS, 0, 1); //声明初始化着色器函数 function initShader(gl, vertexShaderSource, fragmentShaderSource) { //建立顶点着色器对象 const vertexShader = gl.createShader(gl.VERTEX_SHADER); //建立片元着色器对象 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); //引入顶点、片元着色器源代码 gl.shaderSource(vertexShader, vertexShaderSource); gl.shaderSource(fragmentShader, fragmentShaderSource); //编译顶点、片元着色器 gl.compileShader(vertexShader); gl.compileShader(fragmentShader); //建立程序对象program const program = gl.createProgram(); //附着顶点着色器和片元着色器到program gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); //连接program gl.linkProgram(program); //使用program gl.useProgram(program); //返回程序program对象 return program; } </script>
</body>

</html>
复制代码

结尾

对于 WebGL,我仍是挺感兴趣的,但愿后面本身能多写几篇记录。浏览器

以上关于 WebGL 的记录,都是笔者从网上众多资料中总结而来。若有错误,欢迎指出。markdown