随着 WebGL 2.0 逐渐在主流浏览器中被支持,在编写或阅读 Shader 代码时,不可避免地需要确认当前使用的版本,版本差异会导致 API 的差异,语法差异等(本站会以 WebGL 1.0 为主,逐步介绍 WebGL 2.0 的新内容)。
在《追根溯源》中,我们提到了 OpneGL、OpenGL ES 和 WebGL 的定义和关系:OpenGL 是开放图形库,定义了一系列 API 接口,OpenGL ES 是其子集,精简了许多非绝对必要的特性,用于嵌入式设备。WebGL 可以理解为 OpenGL ES 在浏览器中的实现。
OpenGL 2.0 支持了一项非常重要的特性,即「可编程着色器方法」。通过 OpenGL Shading Language(简称 GLSL,也可以以 Shader 统称),开发者可以对绘图管线直接控制,而无需使用汇编语言或硬件规格语言。
需要注意:OpenGL 和 OpenGL ES 的 GLSL 版本不在一个体系中。对于 WebGL,我们只需要关心 OpenGL ES GLSL 的版本信息。
OpenGL Version | GLSL Version | Date | Shader Preprocessor |
---|---|---|---|
2.0 | 1.10 | 30 April 2004 | #version 110 |
2.1 | 1.20 | 07 September 2006 | #version 120 |
3.0 | 1.30 | 22 November 2009 | #version 130 |
3.1 | 1.40 | 22 November 2009 | #version 140 |
3.2 | 1.50 | 04 December 2009 | #version 150 |
3.3 | 3.30 | 11 March 2010 | #version 330 |
4.0 | 4.00 | 24 July 2010 | #version 400 |
4.1 | 4.10 | 24 July 2010 | #version 410 |
4.2 | 4.20 | 12 December 2011 | #version 420 |
4.3 | 4.30 | 7 February 2013 | #version 430 |
4.4 | 4.40 | 16 June 2014 | #version 440 |
4.5 | 4.50 | 09 May 2017 | #version 450 |
4.6 | 4.60 | 14 June 2018 | #version 460 |
OpenGL ES version | GLSL ES version | WebGL version | Date | Shader Preprocessor |
---|---|---|---|---|
2.0 | 1.00 | 1.0 | 12 May 2009 | #version 100 |
3.0 | 3.00 | 2.0 | 29 January 2016 | #version 300 es |
3.1 | 3.10 | / | 29 January 2016 | #version 310 es |
3.2 | 3.20 | / | 10 July 2019 | #version 320 es |
当我们在编写 WebGL Shader 时,需要关注的是 API 在 GLSL ES 中的版本支持度。通过在官方文档中查询某个接口 textureGrad
的版本支持度,可以得到如下所示的表格:
Function Name | OpenGL ES Shading Language Version | |
---|---|---|
1.00 | 3.00 | |
textureGrad | - | ✔ |
可知只有 WebGL 2 才支持 textureGrad
,所以在编写 Shader 时,需要指定版本号(#version
必须写在第一行,且不能有 tab 或换行):
<!-- 定义顶点着色器 -->
<script id="vertexShader" type="x-shader/x-vertex">#version 300 es
precision mediump float;
void main() {
...
}
</script>
<!-- 定义片元着色器 -->
<script id="fragmentShader" type="x-shader/x-fragment">#version 300 es
precision mediump float;
void main() {
...
}
</script>
JS 中则需要调用 WebGL2 的能力:
// 获取 WebGL 1
// var gl = canvas.getContext('webgl')
// 获取 WebGL 2
var gl = canvas.getContext("webgl2");