attribute变量
在上一篇文章中,点总是绘制在固定的位置,因为点的位置是直接写(“硬编码”)在顶点着色器中的。我们先来简单回顾一下上一篇文章的代码
//HelloPoint1.js
//顶点着色器程序
var VSHADER_SOURCE=
'void main(){\n'+
'gl_Position=vec4(0.5,0.0,0.0,1.0);\n'+
'gl_PointSize=10.0;\n'+
'}\n';
//片元着色器程序
var FSHADER_SOURCE=
'void main(){\n'+
'gl_FragColor=vec4(1.0,1.0,0.0,1.0);\n'+
'}\n';
function main(){
//获取<canvas>元素
......
//获取绘制三维图形的绘图上下文
......
//设置<canvas>的背景色
......
//用背景色填充<canvas>
......
//绘制一个点
gl.drawArrays(gl.POINTS,0,1);
}
可以看到顶点着色器中的一行代码:gl_Position=vec4(0.5,0.0,0.0,1.0);
这行代码将点的位置写死在了顶点着色器中,这用程序虽然易于理解,但是缺乏扩展性
,那么我们是否可以改进一下程序,使得顶点位置变得可扩展呢?
下面,我们就来学习如何将顶点的位置从JavaScript传到着色器程序中,然后在对应位置上将点绘制出来。
我们先简单看一下改进后的代码,看看和上面一段代码有什么不一样
//HelloPoint2.js
//顶点着色器
var VSHADER_SOURCE=
//在顶点着色器中,声明attribute变量
'attribute vec4 a_Position;\n'+
'attribute float a_PointSize;\n'+
'void main(){\n'+
//将attribute变量赋值给gl_Position变量
'gl_Position=a_Position;\n'+
'gl_PointSize=a_PointSize;\n'+
'}\n';
//片元着色器
var FSHADER_SOURCE=
'void main(){\n'+
'gl_FragColor=vec4(1.0,1.0,0.0,1.0);\n'+
'}\n';
function main(){
//获取<canvas>元素
......
//获取WebGL上下文
......
//初始化着色器
......
//获取attribute变量的存储位置
var a_Position=gl.getAttribLocation(gl.program,'a_Position');
var a_PointSize=gl.getAttribLocation(gl.program,'a_PointSize');
//将顶点位置传输给attribute变量
gl.vertexAttrib3f(a_Position,0.0,0.0,0.0);
//将顶点大小给attribute变量
gl.vertexAttrib1f(a_PointSize,5.0);
//设置<canvas>的背景色
......
//用背景色填充<canvas>
......
//绘制一个点
gl.drawArrays(gl.POINTS,0,1);
}
我们可以看到多了一些代码,下面我们就来详细介绍一下这些代码。首先我们介绍一下attribute变量。
attribute变量
介绍
attribute变量传输的是那些与顶点相关的数据,是一种GLSL ES变量,被用来从外部向顶点着色器内部传输数据,只有顶点着色器能用它。
使用步骤
① 在顶点着色器中,声明attribute变量
attribute vec4 a_Position;
<存储限定符> <类型> <变量名>
↓
表示接下来的变量是一个attribute变量
② 将attribute变量赋值给gl_Position变量
gl_Position=a_Position;
③ 向attribute变量传输数据
//获取attribute变量的存储位置
var a_Position=gl.getAttribLocation(gl.program,'a_Position');
↓
在初始化函数中创建了这个程序对象
gl.getAttribLocation(program,name):获取由name参数指定的attribute变量的存储地址。
参数 | 含义 |
---|---|
program | 指定包含顶点着色器和片 |