改变点的颜色
现在,我们对如何将数据从js程序传入着色器有了一个很好的了解。在此基础上来实现一个更复杂的程序。
改变绘制点的颜色。而且颜色依赖它在canvas中的位置。
可以用unifrom变量将颜色值传给着色器,器步骤与用attribute变量传值类似。不同的仅仅是,这次数据传值的目标是片元着色器。
- 在片元着色器中准备uniform变量。
- 用这个uniform变量想gl_FragColor赋值。
- 将颜色数据从js传给uniform变量。
用代码来实现下。
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body onload="main()">
<canvas id="canvas" height="400" width="400">
你的浏览器不支持WebGL,请更换新的浏览器
</canvas>
</body>
<script src="../lib/webgl-util.js" ></script>
<script src="../lib/webgl-debug.js" ></script>
<script src="../lib/cuon-utils.js" ></script>
<script>
//顶点着色器程序
var VSHADER_SOURCE="" +
"attribute vec4 a_Position;\n" +
"void main(){\n" +
" gl_Position = a_Position;\n" +//设置坐标
" gl_PointSize = 10.0;\n" +//设置尺寸
"}\n";
//片元着色器程序
var FSHADER_SOURCE = "" +
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // unifrom变量
"void main(){\n" +
" gl_FragColor = u_FragColor;\n" +//设置颜色
"}\n";
function main() {
//首先获取到canvas的dom对象
var canvas = document.getElementById("canvas");
//获取到WebGL的上下文
var gl = getWebGLContext(canvas);
//不支持WebGL的浏览器将打印一个错误,并结束代码运行
if (!gl) {
console.log("浏览器不支持WebGL");
return;
}
//初始化着色器
if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log("初始化着色器失败");
return;
}
// 获取attribute变量的存储位置
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
// 将顶点位置传输给attribute变量
// gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
// 注册鼠标点击事件响应函数
canvas.onmousedown = function(ev) {
click(ev, gl, canvas, a_Position, u_FragColor);
}
//指定一个覆盖(清空)canvas的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//执行清空
gl.clear(gl.COLOR_BUFFER_BIT);
// //绘制一个点
// gl.drawArrays(gl.POINTS,0,1);
}
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.width/2)/(canvas.height/2);
y = (canvas.height/2 - (y-rect.top)) / (canvas.width/2);
// 将坐标存储到g_points数组中
g_points.push([x, y]);
// 将点的颜色存储在g_colors中
if (x >= 0 && y >= 0) { // 第一象限
g_colors.push([1.0, 0.0, 0.0, 1.0]); //红色
} else if (x < 0 && y < 0) { // 第三象限
g_colors.push([0.0, 1.0, 0.0, 1.0]) // 绿色
} else { // 其他
g_colors.push([1.0, 1.0, 1.0, 1.0]) // 白色
}
console.log(g_colors);
gl.clear(gl.COLOR_BUFFER_BIT);
var len = g_points.length;
for (let i = 0; i < len; i++) {
var xy = g_points[i];
var rgba = g_colors[i];
// 将点的位置传输到a_Position中
gl.vertexAttrib3f(a_Position, xy[0], xy[1], 0.0);
// 将点的色值传输到u_FragColor中
gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3]);
gl.drawArrays(gl.POINTS,0,1);
}
}
</script>
</html>
uniform变量
只有顶点着色器才可以使用attribute变量,使用片元着色器时,需要使用uniform变量。