改变点的颜色
现在,我们对如何将数据从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变量。
