webgl之attribute变量

1,057 阅读2分钟

webgl之attribute变量

Attribute

将位置信息从javascript程序中传给顶点着色器,有两种方式可以做到这点:attribute变量、uniform变量,使用哪一个变量取决需传输的数据本身,attribute变量传输的是那些和顶点相关的数据,而uniform变量传输的是那些和顶点无关的数据。

7EAAFB45FA743D6D13FCB417EC072565.jpg

attribute变量是一种GLSL ES变量,被用来从外部向顶点着色器内传输数据,只有顶点着色器才能使用它。

为了使用attribute,一般需要以下几个步骤:

  1. 在顶点着色器中,声明attribute变量;
  2. 将attribute变量赋值给gl_Position变量;
  3. 向attribute变量传输数据;

demo

var VSAHDER_SOURCE = `
	attribute vec4 a_Position;
	void main () {
		gl_Position = a_position;
		gl_PositionSize = 10.0;
	}
`
function main () {
	var canvas = document.getElementById('webgl')
  var gl = getWebGLContext(canvas)
  ...
  // 创建gl.program程序对象
  if (!initShaders(gl, VSAHDER_SOURCE, FSHADER_SOURCE)) {
		...
	}
  // 获取attribute变量的存储位置
  var a_position = gl.getAttribLocation(gl.program, 'a_Position')
  // 将顶点位置传输给attribute变量
  gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)
  gl.clearColor(0.0,0.0,0.0,1.0)
  gl.clear(gl.COLOR_BUFFER_BIT)
  gl.drawArrays(gl.POINTS, 0, 1)
}

attribute vec4 a_Position;

在这一行中,关键词attribute被称为存储限定符,它表示接下来的变量是一个attribute变量。attribute变量必须声明成全局变量,数据从着色器外部传给该变量。变量的声明必须按照以下的格式:<存储限定符> <类型> <变量名>。

EFD10A854FE02FCC4F2E2F66F946EC3F.jpg

命名约定:attribute的变量都以a_前缀开始,所有uniform变量都以u_开始,这样从变量的名字就可以轻易辨认出其类型。

gl.vertexAttrib3f

gl.vertexAttrib3f()是一系列同族函数中的一个,该系列函数的任务就是从Javascript向顶点着色器中的attribute变量传值。gl.vertexAttrib1f()传输1个单精度值,gl.vertexAttrib2f()传输2个值....

你也可以使用这些方法的矢量版本,它们的名字以"v(vector,可见学好英语多么重要,可直接从语意就能判断出api的功能)"结尾,并接受类型化数组作为参数。

var position = new Float32Array([1.0,2.0,3.0,1.0])
gl.vertexAttrib4fv(a_Position, position)

1BA0AFEE-8838-4B92-9A6E-23BF3577BDBE.png 同样的例子,我们还可以修改point的尺寸

var VSHADER_SOURCE = `
	attribute vec4 a_Position;
	attrbute float a_PointSize;
	void main () {
		gl_Position = a_Position;
		gl_PointSize = a_PointSize;
	}
`
...
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
...
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize')
gl.vertexAttrib1f(a_PointSize, 5.0)