1
votes

I have this piece of code:

var FSHADER_SOURCE = `
  precision mediump float;
  uniform vec4 u_FragColor;

  void main() {
    gl_FragColor = u_FragColor;
  }`;

Also a function to change color for fragment shader:

var gl = getWebGLContext(canvas);
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');

// lines to set rgb
gl.uniform4f(u_FragColor, rgb[0], rgb[1], rgb[2], rgb[3]);

Weirdly, I can see rgb is set to something like [0,1,0,1] but color for fragment shader is black anyway. Even if I change the code to:

// still black
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1.0);

The only way to change color is to directly modify rgb channels without using u_FragColor. What am I missing here?


Also complete code is on gist if helpful.

2
I don't see the gl.program value being set anywhere in your gist so the gl.getUniformLocation call is not doing what you think it should do. gl.program is not a built-in value in WebGL so unless you set it, it has no value. Probably you meant to pass in the compiled program? - Huy Nguyen
@HuyNguyen It's set by initShaders, which is a helper provided by the book WebGL Programming Guide. I can inspect it using console.log. And if it's not set, how could vertex shader work? It's only fragment shader uniform parameter not passing to it. - knh190

2 Answers

1
votes

It works for me if I am doing something like this:

var color = new Float32Array([rgb[0], rgb[1], rgb[2], rgb[3]]);

...and then:

gl.uniform4fv(program.uniforms['u_fragColor'], color);

So, I believe the issue here is just only the conversion inside uniform4f instead of uniform4fv.

Please note, later on You can just set the color components directly to the Float32Array, no need to allocate every time a new one.

1
votes

An active program resource, like the location of a uniform variable, can be get after the program was linked:

gl.linkProgram(gl.program);
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor'); 

But, to set the value of a uniform variable, the program has to installed as the current program. uniform* sets a values to the uniform which is associated to the location of the currently used program. Note, gl.uniform4f has no parameter for the program, the affected program is the current program:

gl.useProgram(gl.program);
gl.uniform4f(u_FragColor, rgb[0], rgb[1], rgb[2], rgb[3]);