1

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? Commented Mar 19, 2019 at 18:45
  • @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. Commented Mar 20, 2019 at 2:48

2 Answers 2

2

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]);
Sign up to request clarification or add additional context in comments.

Comments

1

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.

2 Comments

You don't need to use a Float32Array with gl.uniform. A native JavaScript array will work just fine
Probably it's browser related? Thanks for help but both solutions don't work for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.