美文网首页webglWebGL,Canvas,前端可视化W3C
WebGL2系列之从WebGL1迁移到WebGL2

WebGL2系列之从WebGL1迁移到WebGL2

作者: ITman彪叔 | 来源:发表于2017-11-14 15:55 被阅读109次

WebGL2几乎100%兼容WebGL1,需要注意的是,这里说的几乎,也就是说,也是存在一些细微的差别的,因此原本WebGL1的代码迁移到WebGL2,应该不会有遇到太多的困难;不过WebGL2和WebGL1有两个主要的差别,请看下文。

获取WebGL2上下文

获取WEBGL2和获取WebGL1的上下文的方式并不完全一致:

  • 通过canvas的getContext方法获取WebGL2的上下文,这和WebGL1是一致的
  • getContext方法传入的参数是"webgl2",而不是"webgl".
    以下是获取WEBGL2上下文的代码
var  canvas = document.createElement('canvas');
var  gl2 = canvas.getContext('webgl2');

WebGL2并非所有的浏览器都支持,所以比较鲁棒的方式是,判断如果不存在WebGL2上下文,则回退使用WebGL1,代码如下:

var  canvas = document.createElement('canvas');
var  gl = canvas.getContext('webgl2');
var isWebGL2 = true;
if (!gl) { // try to fallback to webgl 1
    gl = canvas.getContext('webgl') ||
          canvas.getContext('experimental-webgl');
  isWebGL2 = false;
}
if (!gl) {
    console.log('your browser does not support WebGL');
}

很多WebGL扩展可在WebGL2中直接使用

WebGL1中,有很多扩展功能,在WebGL1中使用这些功能,首先需要加载扩展,然后调用,而在WebGL2中,WebGL1的很多扩展功能可以直接在使用。
比如
顶点数组对象(Vertex Array Object),在WebGL1中,是一个扩展对象OES_vertex_array_object,而在WebGL2直接使用。在WebGL1中,使用代码如下:

var ext = gl.getExtension("OES_vertex_array_object");
if (!ext) {
   // 告诉用户没有此扩展或者使用其他方式
  // tell user they don't have the required extension or work around it
} else {
  var aVAO = ext.createVertexArrayOES();
}

而在WebGL2中,代码如下:

var aVAO = gl.createVertexArray();

有关VAO的相关功能,将会在以后的章节中介绍。


除了以上所说的两点,webgl1的其他功能,WebGL2都可以很好的兼容。

当如,为了能够使用一些WebGL2的高级特性,我们需要做一些改变。

使用 GLSL 300 es

WebGL2的着色器语言支持原本WebGL1的GLSL 100 ,同时也支持GLSL 300 es,但是如果要使用更多的高级特性,则必须使用GLSL 300 es;以下会介绍使用GLSL 300 es的一些变化的地方。

显示指定着色器语言版本

要使用GLSL 300 es,需要在着色器代码中显示的声明,声明版本代码如下:

#version 300 es

需要注意的是:

  • 版本声明的代码需要在顶点着色器和片元着色器中同时指定
  • 版本声明的代码必须严格在第一行
    上文所说的严格的第一行的意思是说,该声明前面不能有任何的行,哪怕是空行和注释也不行,下面通过代码说明:
    比如以下代码是错误的,因为在#version 300 es之前会有一个空行
var vsSource = `
#version 300 es
`;

正确的代码应该是:

var vsSource = `#version 300 es
`;

在比如,以下代码是错误的:

<script id="vs" type="notjs">
#version 300 es
...
</script>

正确的代码应该是:

<script id="vs" type="notjs">#version 300 es
...
</script>

GLSL 300 es 的不同

GLSL 300 es 和GLSL 100 es 有一些不同的地方,以下会一一讲述这些差异的地方

使用in代替attribute

在GLSL 100中,定义顶点数据的变量,使用attribute关键词,如下:

attribute vec4 aPosition;
attribute vec2 aTexcoord;
attribute vec3 aNormal;

而在GLSL 300 es中,使用in关键词,代码如下:

in vec4 aPosition;
in vec2 aTexcoord;
in vec3 aNormal;

varying 被in/out替代

在GLSL 100,在顶点着色器和片元着色器中,通过varying关键词来声明varying变量,代码如下:

 varying vec2 vTexcoord;
 varying vec3 vNormal;

而在GLSL 300 es中,顶点着色器中的varying变量用out声明,表示输出:

 out vec2 vTexcoord;
 out vec3 vNormal;

在片元着色器中的varying变量用in声明,表示输如:

 int vec2 vTexcoord;
 int vec3 vNormal;

GLSL 300 es 中没有内置变量gl_FragColor

在GLSL 100 中,我们通过给内置变量gl_FragColor赋值来设置片元的输出颜色,代码如下:

gl_FragColor = vec4(1,1,1, 1);  // white

而在GLSL 300 es中,需要自己定义一个输出颜色的变量,并在main函数中设置颜色值,代码如下:

out vec4 myOutputColor;
 ......
void main() {
   myOutputColor = vec4(1, 1, 1, 1);  // white
}

此处,输入变量名可以随意定义,不过不能使用gl_开通,因此你也不能这样定义 out vec4 gl_FragColor;

用texture代替 texture2D、textureCube

在GLSL 100中,通过texture2D方法获取2D贴图的像素,textureCube方法获取立方体贴图的像素,代码如下:

uniform sampler2D uTexture;
uniform samplerCube uCubeTexture;
 ......
void main(){
  vec4 color1 = texture2D(uTexture, ...);
  vec4 color2 = textureCube(uCubeTexture, ...);
}

而在GLSL 300 es中,只需要使用texture方法即可,改方法会通过传入的贴图对象,自动判断,代码如下:

uniform sampler2D uTexture;
uniform samplerCube uCubeTexture;
 ......
void main(){
  vec4 color1 = texture(uTexture, ...);
  vec4 color2 = texture(uCubeTexture, ...);
}

总结

前面 列举了从WebGL1 迁移到WebGL2一些主要的差异和使用GLSL 300 es 与GLSL 100的不同,可以看出,WEBGL2虽然不对WebGL1完全兼容,但是不兼容的地方不多,所以迁移的难度不大。
后面的章节,会陆续介绍WebGL2 相关的特性。

相关文章

  • WebGL2系列之从WebGL1迁移到WebGL2

    WebGL2几乎100%兼容WebGL1,需要注意的是,这里说的几乎,也就是说,也是存在一些细微的差别的,因此原本...

  • WebGL2系列之引言

    引子 时光荏苒岁月如梭,不知不觉间,青丝变白发,哦不是,应该是WebGL已经发展到了2.0阶段:WebGL2,We...

  • WebGL2系列之图元重启

    背景 在使用WebGL绘制图形的时候,大多数情况下,绘制一个图形的时候,其各个图元都是相连的。 但是在一些情况下,...

  • WebGL2系列之不可变纹理

    纹理背景知识 在WebGL1中,纹理包括2D纹理和立方体纹理,在实际的使用中,如果纹理的图片是宽和高是2的幂,可以...

  • WebGL2系列之采样器对象

    前言 在WebGL1中,纹理的图片和采样信息都是写在纹理对象之中. 采样信息告诉GPU如何去读取贴图上图片的信息。...

  • WebGL2系列之顶点数组对象

    使用了顶点缓冲技术后,绘制效率有了较大的提升。但是还有一点不尽如人意,那就是顶点的位置坐标、法向量、纹理坐标等不同...

  • WebGL2系列之顶点数组对象

    FYI: https://segmentfault.com/a/1190000012174165 http://w...

  • WebGL2系列之多采样渲染缓冲对象

    在很久很久以前,盘古开辟了天地,他的头顶着天,脚踩着地,最后他挂了。他的毛发变成了森林,他的血液变成了河流,他的肌...

  • WebGL2系列之实例数组(Instanced Arrays)

    实例化数组 实例化是一种只调用一次渲染函数却能绘制出很多物体的技术,它节省渲染一个物体时从CPU到GPU的通信时间...

  • webgl2 uniform 同族函数写法

    WebGL2RenderingContext.uniform[1234][uif]vui 意为无符号整数, i 意...

网友评论

    本文标题:WebGL2系列之从WebGL1迁移到WebGL2

    本文链接:https://www.haomeiwen.com/subject/zqyzsxtx.html