# 说在前面
getContext
clearColor
clear
WebGL 使得在支持 HTML 的 canvas 标签的浏览器中,不需要安装任何插件,便可以使用基于 OpenGL ES 2.0 的 API 在 canvas 中进行 2D 和 3D 渲染。
THREE.js和BABYLON.js等很多框架封装了 WebGL,提供了各个平台之间的兼容性。使用这些框架而非原生的 WebGL 可以更容易地开发 3D 应用和游戏。
# 一些概念
# 光栅化引擎
WebGL 经常被当成 3D API,人们总想“我可以使用 WebGL 和一些神奇的东西做出炫酷的 3D 作品”。
事实上 WebGL 仅仅是一个光栅化引擎,它可以根据你的代码绘制出点,线和三角形。
想要利用 WebGL 完成更复杂任务,取决于你能否提供合适的代码,组合使用点,线和三角形代替实现。
# GLSL
WebGL 在电脑的 GPU 中运行。因此你需要使用能够在 GPU 上运行的代码。
这样的代码需要提供成对的方法。每对方法中一个叫顶点着色器, 另一个叫片断着色器,并且使用一种和 C 或 C++类似的强类型的语言 GLSL。
# 着色器程序
每一对着色器组合起来称作一个 program(着色程序)。
几乎整个 WebGL API 都是关于如何设置这些成对方法的状态值以及运行它们。
对于想要绘制的每一个对象,都需要先设置一系列状态值,然后通过调用 gl.drawArrays 或 gl.drawElements 运行一个着色方法对。
# 着色器的数据
属性 Attribute 和缓冲 buffer
缓冲是发送到 GPU 的一些二进制数据序列(在 JS 中一般就是类型化数组,通过 ArrayBuffer 送进缓冲)
属性用来指明怎么从缓冲中获取所需数据并将它提供给顶点着色器。
缓冲不是随意读取的。事实上顶点着色器运行的次数是一个指定的确切数字, 每一次运行属性会从指定的缓冲中按照指定规则依次获取下一个值。
全局变量 Uniform
全局变量在着色程序运行前赋值,在运行过程中全局有效。
纹理 Texture
纹理是一个数据序列,可以在着色程序运行中随意读取其中的数据。大多数情况存放的是图像数据,但是纹理仅仅是数据序列, 你也可以随意存放除了颜色数据以外的其它数据。
可变量 Varyings
可变量是一种顶点着色器给片断着色器传值的方式,顶点着色器中设置的可变量会在片断着色器运行中获取不同的插值。
稍微总结一下
在 JS 中创建缓冲,通过属性指定传值给 WebGL。
在 JS 中创建变量,通过全局变量传值给 WebGL。
在 WebGL 中,顶点着色器通过可变量传值给片段着色器。
gl.getAttribLocation(program, "attrubute_name");
gl.getUniformLocation(program, "uniform_name");
# 核心问题
WebGL 只关心两件事:裁剪空间中的坐标值和颜色值。
你需要提供两个着色器来做这两件事,一个顶点着色器提供裁剪空间坐标值,一个片断着色器提供颜色值。
注意:无论你的画布有多大,裁剪空间的坐标范围永远是 -1 到 1 。
# 准备工作
# 准备 3D 渲染
<canvas id="glcanvas" width="320" height="240">
你的浏览器似乎不支持或者禁用了 HTML5 <code><canvas></code> 元素。
</canvas>
# 准备 WebGL 上下文
const canvas = document.querySelector("#glcanvas");
// 初始化 WebGL 上下文
const gl = canvas.getContext("webgl");
// 确认 WebGL 支持性
if (!gl) {
alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
return;
}
// 使用完全不透明的黑色清除所有图像
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 用上面指定的颜色清除缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
- 我们所要做的第一件事就是是获取 canvas 的引用,把它保存在 ‘canvas’ 变量里。
- 当我们获取到 canvas 之后,我们会调用getContext 函数并向它传递"webgl"参数,来尝试获取 WebGLRenderingContext
- 如果 WebGL 上下文成功初始化,变量 ‘gl’ 会用来引用该上下文。在这个例子里,我们用黑色清除上下文内已有的元素。
# 渲染结果
一个黑色矩形