着色器编程

前2课已经将了如果使用顶点着色器以及片元着色器来绘制点,但是真实情况下是不会存在固定颜色与尺寸位置的,如何对他们进行编码呢?

代码顺序

在对着色器编程时,需要先将program连接到WebGL中,以及需要program使用之后才可编辑。

介绍2个变量

  • attribute: 用于顶点点着色器(Vertex Shader)传值时使用。
  • uniform:可用于顶点着色器(Vertex Shader)与片元着色器(Fragment Shader)使用。

将顶点动态化

首先,先在顶点着色器代码中,将对应的vec4的固定值变成变量

1
2
3
4
5
6
var VSHADER_SOURCE = 
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
' gl_PointSize = 10.0;\n' +
'}\n';

位置参数使用了attribute变量来承载。这样WebGL对象就可以获取到对应的存储位置,就可以去动态改变GLSL变量了。

使用WebGL来获取对应参数的存储地址地址

1
2
3
4
5
6
//返回对应的地址信息
var aPosition = gl.getAttribLocation(gl.program, 'a_Position');
//判断地址是否获取成功
if(aPosition < 0) {
console.log('没有获取到对应position');
}

然后给变量赋值

1
2
3
4
gl.vertexAttrib3f(aPosition, 1.0, 1.0, 0.0);
//或者使用Float32Array来传参
var p = new Float32Array([1.0, 1.0, 1.0]);
gl.vertexAttrib3fv(aPosition, p);

注意:vertexAttrib3fv这个函数是典型的GLSL语法命名规范,
vertexAttrib函数功能,
3:对应需要传3个参数,或者是几维向量,
f:表示参数是float类型,
v:表示传如的为一个vector变量。

也就是说对应设置顶点着色器的函数有一下几种功能,参考文档

  • void gl.vertexAttrib1f(index, v0);
  • void gl.vertexAttrib2f(index, v0, v1);
  • void gl.vertexAttrib3f(index, v0, v1, v2);
  • void gl.vertexAttrib4f(index, v0, v1, v2, v3);

  • void gl.vertexAttrib1fv(index, value);

  • void gl.vertexAttrib2fv(index, value);
  • void gl.vertexAttrib3fv(index, value);
  • void gl.vertexAttrib4fv(index, value);

同样操作可以如下修改PointSize:

1
2
3
4
5
6
7
8
9
10
//着色器中添加变量
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
' gl_PointSize = a_PointSize;\n' +
'}\n';
var aPointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
gl.vertexAttrib1f(aPointSize, 10.0);

片元着色器编程

对片元着色器变成需要使用uniform变量来承载。

1
2
3
4
5
6
 var FSHADER_SOURCE =
'precision mediump float;\n'+
'uniform vec4 vColor;\n'+
'void main() {\n' +
' gl_FragColor = vColor;\n' + // Set the point color
'}\n';

获取片元着色器变量地址

1
var vColor = gl.getUniformLocation(gl.program, 'vColor');

给变量赋值

1
2
3
4
gl.uniform4f(vColor, 1.0, 0.0, 0.0, 1.0);
//或使用Float32Array来传参
var color = new Float32Array([1.0, 0.0, 0.0, 1.0]);
gl.uniform4fv(vColor,color)

注意:uniform3fv这个函数是典型的GLSL语法命名规范,
uniform3fv函数功能,
3:对应需要传3个参数,或者是几维向量,
f:表示参数是float类型,
u:表示参数是Uint32Array类型,
i:表示参数是integer类型,
ui:表示参数是unsigned integer类型,
v:表示传如的为一个vector变量。

顶点着色器对应函数,参考文档

  • void gl.uniform1ui(location, v0);
  • void gl.uniform2ui(location, v0, v1);
  • void gl.uniform3ui(location, v0, v1, v2);
  • void gl.uniform4ui(location, v0, v1, v2, v3);
  • void gl.uniform1fv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform2fv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform3fv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform4fv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform1iv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform2iv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform3iv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform4iv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform1uiv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform2uiv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform3uiv(location, data, optional srcOffset, optional srcLength);
  • void gl.uniform4uiv(location, data, optional srcOffset, optional srcLength);

着色器中的代码precision mediump float;表示的意思是着色器中配置的float对象会占用中等尺寸内存。
具体包含的尺寸:

  • highp for vertex positions,
  • mediump for texture coordinates,
  • lowp for colors.

如果不设置此参数会报错:
我是图片的Alt

最终动态效果图:
我是图片的Alt


Webgl课程列表