版本梳理

随着 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 与 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 与 GLSL ES 版本的对应关系(需要关注):

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");