WebGL2系列之從WebGL1遷移到WebGL2

WebGL2幾乎100%兼容WebGL1,須要注意的是,這裏說的幾乎,也就是說,也是存在一些細微的差異的,所以本來WebGL1的代碼遷移到WebGL2,應該不會有遇到太多的困難;不過WebGL2和WebGL1有兩個主要的差異,請看下文。web

獲取WebGL2上下文

獲取WEBGL2和獲取WebGL1的上下文的方式並不徹底一致:canvas

  • 經過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中,代碼以下:webgl

var aVAO = gl.createVertexArray();
有關VAO的相關功能,將會在之後的章節中介紹。

除了以上所說的兩點,webgl1的其餘功能,WebGL2均可以很好的兼容。ui

當如,爲了可以使用一些WebGL2的高級特性,咱們須要作一些改變。code

使用 GLSL 300 es

WebGL2的着色器語言支持本來WebGL1的GLSL 100 ,同時也支持GLSL 300 es,可是若是要使用更多的高級特性,則必須使用GLSL 300 es;如下會介紹使用GLSL 300 es的一些變化的地方。orm

顯示指定着色器語言版本

要使用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聲明,表示輸如:

in vec2 vTexcoord;
 in 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 相關的特性。

歡迎關注公衆號:ITman彪叔

相關文章
相關標籤/搜索