1.demo效果
如上图,这个demo实现在黑色区域内点用鼠标点击,会在不同的区域画出不同颜色的小方块,第一象限的画红色方块,第三象限画绿色方块,第二、四象限画蓝色方块。
2 片元着色器的uniform变量
uniform变量是一种被用来从外部着色器传输数据的变量。先介绍一下uniform变量的声明,该跟顶点着色器attribute变量命名规范类似,uniform类型的变量已U开头:<存储限定符><类型><变量名>
3 gl.getUniformLocation()方法
与attribute一样,要通过js获取偏远着色的变量地址可以通过此方法
函数功能:获取由name指定的uniform变量的存储地址
--------------------------------------------------------------------------
调用示例:gl.getUniformLocation(program, name)
--------------------------------------------------------------------------
参数
program 指定包含顶点着色器和片元着色器的着色器程序对象
name 指定想要获取其存储地址的uniform变量名称
--------------------------------------------------------------------------
返回值 non-null uniform变量的存储地址
null 指定的uniform变量不存在,或命名具有gl_或webgl_前缀
--------------------------------------------------------------------------
错 误 INVALID_OPERATION 程序对象未能连接成功
INVALID_VALUE name参数的长度大于uniform变量名的最大长度,默认256字节
示例代码
//获取片元着色器uniform变量u_FragColor的存储地址
const u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
4 gl.uniform4f()方法
与attribute类似,当我们通过getUniformLocation获取地址后,可以通过gl.unform4f将这个值传给uniform
函数功能:将数据v0, v1, v2, v3 传给由location参数指定的uniform变量
---------------------------------------------------------------------------------
调用示例:gl.uniform4f(location, v0, v1, v2, v3)
---------------------------------------------------------------------------------
参数
location 指定将要修改的uniform变量的存储地址
v0 指定填充uniform变量第一个分量的值
v1 指定填充uniform变量第二个分量的值
v2 指定填充uniform变量第三个分量的值
v2 指定填充uniform变量第四个分量的值
---------------------------------------------------------------------------------
返回值 无
---------------------------------------------------------------------------------
错 误 INVALID_OPERATION 没有当前的program对象,或者location是非法的存储位置
示例代码
//向片元着色器uniform变量u_FragColor传值
gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0)
4 gl.uniform4f的同族函数
gl.uniform4f() 方法是一系列同族函数中的一个,该系列函数的任务就是从JavaScript程序中向着色器中的uniform变量传值
函数功能:将数据[1~4个分量]传给由location参数指定的uniform变量
------------------------------------------------------------------------------
gl.uniform1f(location, v0)
gl.uniform2f(location, v0, v1)
gl.uniform3f(location, v0, v1, v2)
gl.uniform4f(location, v0, v1, v2, v3)
------------------------------------------------------------------------------
参数
location 指定将要修改的uniform变量的存储地址
v0,v1,v2,v3 指定传输给uniform变量的四个分量的值
------------------------------------------------------------------------------
返回值 无
友情提示:
gl.uniform1f()只需要传输一个值,这个值将被填充到uniform变量的第一个分量中,第二、第三个分量将被设置为0.0,第四个分量将被设置为1.0,其他同族函数类推
5 demo代码
// 顶点着色器程序
var VSHADER_SOURCE =
`attribute vec4 a_Position;
attribute float a_Size;
void main() {
gl_Position = a_Position;
gl_PointSize = a_Size;
}`;
// 片元着色器程序
var FSHADER_SOURCE =
`precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}`;
const main = () => {
let count = 0.1
//获取绘制dom
const canvas = document.getElementById('webgl');
//获取canvas上下文
const gl = canvas.getContext('webgl');
//初始化着色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
return console.log('Failed to initialize shaders.')
}
const aPosition = gl.getAttribLocation(gl.program, 'a_Position');
const aColor = gl.getUniformLocation(gl.program, 'u_color');
const aSize = gl.getAttribLocation(gl.program, 'a_Size');
const points = [];
const colors = [];
const click = (ev, gl, canvas, aPosition) => {
//坐标归一化;
let x = ev.offsetX;
let y = ev.offsetY;
x = (x - canvas.height / 2) / (canvas.height / 2);
y = (canvas.width / 2 - y) / (canvas.width / 2);
points.push(x, y);
console.log(x, y)
if (x >= 0 && y >= 0) {
colors.push([1.0, 0.0, 0.0, 1.0])
} else if (x < 0 && y < 0) {
colors.push([0.0, 1.0, 0.0, 1.0])
} else {
colors.push([1.0, 1.0, 1.0, 1.0])
}
gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < points.length; i += 2) {
const rgba = colors[(i / 2) | 0];
console.log('rgba', rgba)
gl.vertexAttrib3f(aPosition, points[i], points[i + 1], 0.0);
gl.uniform4f(aColor, rgba[0], rgba[1], rgba[2], rgba[3])
gl.drawArrays(gl.POINTS, 0, 1)
}
}
canvas.onmousedown = (ev) => {
click(ev, gl, canvas, aPosition)
}
console.log('aPosition', aPosition);
gl.vertexAttrib3f(aPosition, 0.0, 0.3, 0.0)
// setInterval(() => {
// count += 0.1
// console.log(count);
// gl.clear(gl.COLOR_BUFFER_BIT);
// gl.vertexAttrib3f(aPosition, 0.0, count, 0.0);
// gl.vertexAttrib3f(aPosition, 0.2, count, 0.0);
// //绘制一个点
// gl.drawArrays(gl.POINTS, 0, 1);
// gl.drawArrays(gl.POINTS, 0, 2);
// }, 1000)
gl.vertexAttrib3f(aPosition, 0.0, 0.2, 0.0);
gl.vertexAttrib1f(aSize, 15);
//设置canvas的背景色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//清空canvas
gl.clear(gl.COLOR_BUFFER_BIT);
//绘制一个点
gl.drawArrays(gl.POINTS, 0, 1);
}
main()