GLSL程序出错 - WebGL

时间:2014-10-30 23:19:49

标签: javascript glsl webgl

我试图将JavaScript代码中的统一变量传递给GSLS程序。但是我收到了这个警告,我预期的输出不会出现:

WebGL: INVALID_OPERATION: uniform3fv: location is not from current program 

我从JavaScript代码中初始化了统一值:

var lights = {
    direction: [1.0, 1.0, 1.0],
    color: [0.0, 1.0, 1.0]
};

var u_LightColor = gl.getUniformLocation(program, 'u_LightColor');
var u_LightDirection = gl.getUniformLocation(program, 'u_LightDirection');

if (u_LightColor < 0) {
    console.error("failed to get the storage location u_LightColor");
}

if (u_LightDirection < 0) {
    console.error("failed to get the storage location u_LightDirection");
}

gl.uniform3fv(u_LightColor, lights.color);
gl.uniform3fv(u_LightDirection, lights.direction);

我的片段着色器代码是这样的:

precision mediump float;
    uniform vec3 u_LightColor;
    uniform vec3 u_LightDirection;
    uniform sampler2D diffuseMap;
    varying mediump vec3 color;
    varying vec2 tCoord;
    varying vec3 n;
    void main(void) {

        vec3 normal = normalize(n);
        float nDotL = max(dot(normalize(vec3(-5.0, -0.0, -5.0)), normal), 0.0);
        diffuseVal = (u_LightColor) * diffuseVal * nDotL;
        gl_FragColor = vec4(diffuseVal, 1.0);
    }

我不知道为什么我会收到这个警告。虽然程序正在运行,但u_LightColoru_LightDirection的值未传递到片段着色器中;结果输出都是黑暗的。

另外要指出的是,我在GLSL程序中有其他uniform变量,其中使用uniformSetter函数传递数据;那些工作正常。

有人可以帮助我知道,为什么数据不会进入u_LightColoru_LightDirection

1 个答案:

答案 0 :(得分:2)

在致电gl.useProgram(program)之前,您是否致电gl.uniform3fv

制服是特定于程序的。换句话说,如果我制作2个着色器程序,即使它们使用的是完全相同的源,也可以查找为它们查找的位置。

示例:给定这些始终使用相同源的函数。

 function makeShader(type, source) {
    var s = gl.createShader(type);
    gl.shaderSource(s, source);
    gl.compileShader(s);
    return s;
 }

 function makeProgram() {
    var vs = makeShader(gl.VERTEX_SHADER, vertexShaderSource);
    var fs = makeShader(gl.FRAGMENT_SHADER, fragmentShaderSource);
    var prg = gl.createProgram();
    gl.attachShader(vs);
    gl.attachShader(fs);
    gl.linkShader(prg);
    return prg;
 }    

此代码将生成错误

 var prg1 = makeProgram();
 var prg2 = makeProgram();
 var u_someUniformLocation = gl.getUniformLocation(prg1, "u_someUniform");

 gl.useProgram(prg2);
 gl.uniform3fv(u_someUniformLocation, [1,2,3]);  // ERROR!

u_someUniformLocation适用于prg1而不是prg2,即使着色器程序相同,它们也是单独的程序,并且需要单独的WebGLUniformLocation个对象。