WebGL 基础篇1/2

着色器获取数据的4种方法。

  1. 属性(Attributes)和缓冲缓冲是发送到GPU的一些二进制数据序列,通常情况下缓冲数据包括位置,法向量,纹理坐标,顶点颜色值等。 你可以存储任何数据。属性用来指明怎么从缓冲中获取所需数据并将它提供给顶点着色器。 例如你可能在缓冲中用三个32位的浮点型数据存储一个位置值。 对于一个确切的属性你需要告诉它从哪个缓冲中获取数据,获取什么类型的数据(三个32位的浮点数据), 起始偏移值是多少,到下一个位置的字节数是多少。缓冲不是随意读取的。事实上顶点着色器运行的次数是一个指定的确切数字, 每一次运行属性会从指定的缓冲中按照指定规则依次获取下一个值。
  2. 全局变量(Uniforms)全局变量在着色程序运行前赋值,在运行过程中全局有效。
  3. 纹理(Textures)纹理是一个数据序列,可以在着色程序运行中随意读取其中的数据。 大多数情况存放的是图像数据,但是纹理仅仅是数据序列, 你也可以随意存放除了颜色数据以外的其它数据。
  4. 可变量(Varyings)简单说来就是顶点色器片断着色器 传值,依照渲染的图元是点, 线还是三角形,顶点着色器中设置的可变量会在片断着色器运行中获取不同的插值。

WebGL – Hallo World

  WebGL只关心两件事:裁剪空间中的坐标值和颜色值。使用WebGL只需要给它提供这两个东西。 你需要提供两个着色器来做这两件事,一个顶点着色器提供裁剪空间坐标值,一个片断着色器提供颜色值。

  无论你的画布有多大,裁剪空间的坐标范围永远是 -1 到 1 。 这里有一个简单的WebGL例子展示WebGL的简单用法。

让我们从顶点着色器开始:

javascript // 从缓冲中获取数据 attribute vec4 a_position; // 着色器 必须 有一个main函数 void main() { // gl_Position 是一个顶点着色器主要设置的变量 gl_Position = a_position; }

如果用JavaScript代替GLSL,当它运行的时候,你可以想象它做了类似以下的事情 :

  实际情况没有那么简单,因为 positionBuffer 将会被转换成二进制数据(见下文), 所以真实情况下从缓冲中读取数据有些麻烦,但是希望这个例子能够让你想象出顶点着色器是怎么执行的。

接下来我们需要一个片断着色器 :

  上方我们设置 gl_FragColor 为 1, 0, 0.5, 1,其中1代表红色值,0代表绿色值, 0.5代表蓝色值,最后一个1表示阿尔法通道值。WebGL中的颜色值范围从 0 到 1 。

现在我们有了两个着色器方法,让我们开始使用WebGL吧。

首先我们需要一个HTML中的canvas(画布)对象:

然后可以用JavaScript获取它 :

  现在我们需要编译着色器对然后提交到GPU,先让我们通过字符串获取它们。 你可以利用JavaScript中创建字符串的方式创建GLSL字符串:用串联的方式(concatenating), 用AJAX下载,用多行模板数据。或者在这个例子里,将它们放在非JavaScript类型的标签中。

  事实上,大多数三维引擎在运行时利用模板,串联等方式创建GLSL。 对于这个网站上的例子来说,没有复杂到要在运行时创建GLSL的程度。

  接下来我们使用的方法将会创建一个着色器,只需要上传GLSL数据,然后编译成着色器。 你可能注意到这段代码没有任何注释,因为可以从方法名很清楚的了解方法的作用 (这里作为翻译版本我还是稍微注释一下)。

  现在我们已经在GPU上创建了一个GLSL着色程序,我们还需要给它提供数据。 WebGL的主要任务就是设置好状态并为GLSL着色程序提供数据。 在这个例子中GLSL着色程序的唯一输入是一个属性值a_position。 我们要做的第一件事就是从刚才创建的GLSL着色程序中找到这个属性值所在的位置。