WebGL编程指南03-在javaScript程序通过uniform变量向片元着色器传值

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()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值