深入理解 webgl

1. 深入理解 WebGLShader 对象

2019-07-19  本文已影响0人  纯爱枫若情

概念

WebGL API 的 WebGLShader 可以是一个顶点着色器(vertex shader)或片元着色器(fragment shader)。

每个 WebGLProgram 都需要这两种类型的着色器。

创建流程

要创建一个 WebGLShader 需要使用 WebGLRenderingContext.createShader,通过 WebGLRenderingContext.shaderSource() 然后挂接GLSL源代码 , 最后调用 WebGLRenderingContext.compileShader() 完成着色器(shader)的编译。

function createShader (gl, sourceCode, type) {
  // 调用 WebGLRenderingContext 的 createShader 方法,创建一个 WebGLShader 对象
  // type 有两种类型,分别是 gl.VERTEX_SHADER 和 gl.FRAGMENT_SHADER
  var shader = gl.createShader( type );
  
  // 挂载 glsl 源码
  gl.shaderSource( shader, sourceCode );
  
  // 编译挂接了源码以后的 shader
  gl.compileShader( shader );

  // 获取编译 shader 的状态,是否编译成功了
  // 这个方法可以还能获取shader 的一些别的信息,比如是否已经将 shader 删除,shader 的类型等等,具体可以参考下面的链接:
  // https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/getShaderParameter
  if ( !gl.getShaderParameter(shader, gl.COMPILE_STATUS) ) {
    // 获取 shader 的信息,如果编译过程中没有任何问题的话,获得的 info 为一个空的字符串
    var info = gl.getShaderInfoLog( shader );
    throw "Could not compile WebGL program. \n\n" + info;
  }
  return shader;
}

此时 WebGLShader 仍不是可用的形式,他需要被添加到一个 WebGLProgram 里后才能够使用。

WebGLShader 的理解

WebGLShader 实例化以后,其实是一个空对象,不信可以打开 chrome 控制台看一下,你会发现里面干净的什么都没有。

image.pngimage.png

那么我们就能明白过来,其实这一块,并不是采用我们熟悉的 js 的面型对象的编程方式构建的,至于为什么要这样构建,那就只能去问规范编制的人了。

所以,有些初看不是很好理解的地方,我们才能明白为什么要这么用了。

比如为什么创建 shader 用这个方式:

var shader = gl.createShader( type );   // 创建
gl.shaderSource( shader, sourceCode );  // 挂载源码
gl.compileShader( shader ); // 编译 shader

如果用 JavaScript 的眼光来看的话,明显感觉这样写好多余啊,直接这样简化一下,岂不是更简单:

var shader  = new gl.Shader(type, sourceCode);  // 实例化
shader.compile();   // 编译

现在我只能提出这个疑问,无法解答。

也就是说,我们要习惯各种不同的编程语言的变成习惯,孰优孰劣我们无从判断,也许只有等我们站到了一定的高度以后,才能对这个问题给出满意的答案吧。

上一篇下一篇

猜你喜欢

热点阅读