三、js与着色器传递数据--attribute变量

321 阅读2分钟

一、介绍

GLSL ES允许js与着色器传递数据,通过在着色器中绑定变量,在js中获取变量的存储位置,将数据传输给变量,来实现动态的数据渲染。这样我们就可以通过js动态地设置着色器中数据的值,来实现交互更丰富的场景。

js和着色器之间传输数据的方式包括以下几种

1、attribute变量

(1)传输顶点相关数据
(2)只有顶点着色器能够使用

2、uniform变量和varying变量

(1) 传输对于所有顶点都相同(与顶点无关)的数据
(2) 可用于片元着色器

二、代码示例

#顶点着色器
var VSHADER_SOURCE = 
    # 声明attribute变量,attribute为存储限定符
    'attribute vec4 a_Position;\n' + 
    'void main() {\n' +
    # 给attribute变量赋值
    '  gl_Position = a_Position;\n' +
    '  gl_PointSize = 10.0;\n' +
    '}\n'; 

#片元着色器
var FSHADER_SOURCE = 
    'void main() {\n' +
    '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
    '}\n';

function main() {
    var canvas = document.getElementById('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;
    }

    # 获取attribute变量的存储位置
    var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    if (a_Position < 0) {
        console.log('Failed to get the storage location of a_Position');
        return;
    }

    # 将顶点位置传输给attribute变量
    gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.POINTS, 0, 1);
}

内置方法说明

1、声明attribute变量

语法

    attribute  vec4   a_Position\
     存储限定符  类型   变量名

2、gl.getAttributeLocation(program, name)

获取用name参数指定的attribute变量的存储地址
program参数指定包含顶点着色器和片元着色器的着色器程序对象

gl.getAttribLocation(gl.program, 'a_Position');

其中,gl.program是一个程序对象,包括顶点着色器和片元着色器,
gl.program在initShader()方法中创建

注意

每个变量都具有一个存储地址,以便通过存储地址向变量传输数据

3、 gl.vertexAttrib3f(location, v0, v1, v2);

向attribute变量赋值
参数:
location:存储位置,本例中从gl.getAttributeLocation(program, name)方法中获得

注意

location是vec4类型,却赋值3个变量
如果省略第4个参数,默认将第4个分量设为1.0

4、 gl.vertexAttrib3f()的同族函数

作用:从js向顶点着色器中的attribute变量传值
gl.vertexAttrib1f(location, v0)
gl.vertexAttrib1f(location, v0, v1)
gl.vertexAttrib1f(location, v0, v1, v2)
gl.vertexAttrib1f(location, v0, v1, v2, v3)\

注:

(1)如果未设值,v0, v1, v2的默认值为0.0, v3的默认值为1.0
(2)这些方法的矢量版本,名字以‘v’结尾
(3)接受类型化数组作为参数,如Float32Array
(4)函数名中的数字表示数组中的元素个数

var Position = new Float32Array([1.0, 2.0, 3.0, 1.0])\
gl.vertexAttrib4f(a_Position, position)