使用uniform变量
上一节讲过, uniform变量主要用于所以顶点都相同的(与顶点无关的)数据。与attribute变量传递类似,不同的是uniform传递的目标是片元着色器。
实例,鼠标点击生产点,点的位置在不同的象限点的颜色不同
// 顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n'+
'void main() {\n' +
' gl_Position = a_Position ;\n' +
' gl_PointSize = 30.0;\n' +
'}\n';
// 片元着色器程序
var FSHADER_SOURCE =
'precision mediump float;\n'+
'uniform vec4 u_FragColor;\n'+
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' +
'}\n';
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取WebGL渲染上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
// 初始化着色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
}
var u_FragColor = gl.getUniformLocation(gl.program,"u_FragColor");
//获取attribute的存储位置
var a_Position = gl.getAttribLocation(gl.program,"a_Position");
if(a_Position < 0){
console.log("获取存储位置失败!");
return;
}
//注册鼠标响应事件
canvas.onmousedown = function(ev){click(ev,gl,canvas,a_Position,u_FragColor);};
//将顶点位置传给attribute变量
// gl.vertexAttrib1f(a_Position,0.0);
// gl.vertexAttrib2f(a_Position,0.0,0,0);
// gl.vertexAttrib3f(a_Position,0.0,0.0,0.0);
// 指定清空<canvas>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空<canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
}
var g_points = [];
var g_colors = [];
function click(ev,gl,canvas,a_Position,u_FragColor){
var x = ev.clientX;
var y = ev.clientY;
var rect = ev.target.getBoundingClientRect();
x = ((x-rect.left)-canvas.height/2)/(canvas.height/2);
y = (canvas.width/2-(y-rect.top))/(canvas.width/2);
g_points.push([x,y]);
if(x>=0.0&&y>=0.0){
g_colors.push([1.0,0.0,0.0,1.0]);
}else if(x<0.0&&y<0.0){
g_colors.push([1.0,0.5,0.0,1.0]);
}else{
g_colors.push([1.0,1.0,1.0,1.0]);
}
// 清空<canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
var len = g_points.length;
for(var i = 0;i<len;i++){
var xy = g_points[i];
var rgba = g_colors[i];
gl.vertexAttrib3f(a_Position,xy[0],xy[1],0,0);
gl.uniform4f(u_FragColor,rgba[0],rgba[1],rgba[2],rgba[3]);
gl.drawArrays(gl.POINTS,0,1);
}
}
在片元着色器声明uniform变量的时候定义了精度precision mediump float
定义精度:
lowp、meduimp、highp分别是低精度、中等精度、高精度,在顶点中的精度是很高的使用了默认的高精度。
片段着色器uniform vec4 u_FragColor,使用了uniform,他会使得每一个顶点使用同一个值,除非我们去改变它,它负责每一块片段的颜色,颜色有四种颜色组成。
过程为:
(1)声明精度为precision mediump float的uniform变量;
(2)使用getAttribLocation方法获取uniform变量的地址;
(3)使用uniform4f方法传值。;
(4)绘制。
效果如图: