2 Different Shaders Require 2 Different Uniform Definitions

In my quest for the perfect wave generator, I am trying to combine a couple of wave-generating shaders. Each works fine, but when I try to combine them, I get a blank screen with no error message (which indicates there is a problem with the shaders).

It appears that the problem is due to a single variable, which is defined differently in the uniforms used by each shader. Both programs are in CodePen.

The first program contains an update of an old program that used to require WebGL1Render (compatible with old shaders) but now seems to work fine with WebGLRender.

line 43 says: “let GrdSiz = 804.67;”

line 48 (part of uniform “waves_”) currently reads: “GrdSiz: GrdSiz,”
This program won’t work if I change this line to: “GrdSiz: {value: GrdSiz},”

The second program contains a single set of shaders.

line 6 says: “let GrdSiz = 804.67;”
line 19 (part of uniform “gu”) currently says: “grid: {value: GrdSiz},”
This program won’t work if I change this line to: “GrdSiz: GrdSiz,”

I suspect that this incompatibility has to do with changes in OpenGL (GLSL) standards. But I am not sure what instructions might be causing this incompatibility.

Is there a way to change these shader programs to make them compatible with each other?

Which of the two methods of designating variables is preferrable?

The issue with GrdSiz and {value: GrdSiz} is that both programs use different styles for one and the same thing. Uniforms’s values are object instances, e.g. {value:...}.

In the first program there is:

let GrdSiz = 804.67; // line 43
let Waves_ = { GrdSiz: GrdSiz, ... }; // line 48
this.GrdSiz = Waves_.GrdSiz; // line 83
this.materialInitialSpectrum.uniforms.u_grdsiz.value = this.GrdSiz; // line 245

so, 804.67 goes in the value property of the u_grdsiz uniform.

In the second program there is:

let GrdSiz = 804.67; // line 6
let gu = { grid: {value: GrdSiz},... } // line 19
shader.uniforms.grid = gu.grid; // line 96

so, the value 804.67 goes in the value property of grid uniform. Practically it does the same thing as the first program, but tunnels the value through a different path and end up into differently named uniforms.

My suggestion is make both programs more consistent with each other before combining them. This includes not only consistent ways of passing values, but also consistent names of variables (both JS and GSLS). I believe this will reduce the confusion, and may even eliminate it.

3 Likes

Thanks for taking the time to really dig into this! The diagrams are helpful in showing the difference between passing on a variable and a uniform value.

From re-reading the three.js, it appears that my first example is not a proper “uniform”, but is simply a variable that has been pressed into service as a uniform. In contrast, the second example is more of a proper uniform.

The first program did not work with the uniform definition because it wanted a variable and the second program could not work with a variable because it wanted a uniform definition.

I resolved the problem by giving each what they wanted - a variable for the first program which generates displacement and normal maps; and a uniform for the second program which defines the texture that uses those maps. GrdSiz appears in both places.

1 Like