Joehot200
Joehot200

Reputation: 1090

Am I able to initiate blank variables and declare them afterwards?

I would like to do something like this:

vec4 text;
if (something){
  text = texture(backgroundTexture, pass_textureCoords);
}
if (somethingElse){
  text = texture(anotherTexture, pass_textureCoords);
}

Is this valid GLSL code, and if not, is there any suitable alternative?

Upvotes: 0

Views: 38

Answers (1)

BDL
BDL

Reputation: 22167

The answer depends on what something and somethingElse actually are.

  • If this is a uniform control flow, which means that all shader invocations execute the same branch, then this is perfectly valid.

  • If they are non uniform expressions, then there are some limitations:

    When a texture uses mipmapping or anisotropic filtering of any kind, then any texture function that requires implicit derivatives will retrieve undefined results.

To sum it up: Yes, this is perfectly valid glsl code but textures in non-uniform controls flow have some restrictions. More details on this can be found here.

Side note: In the code sample you are not declaring the variables afterwards. You are just assigning values to them.

Edit (more info)

To elaborate a bit more on what uniform and non-uniform control flow is: Shaders can (in general) have two types of inputs. Uniform variables like uniform vec3 myuniform; and varyings like in vec3 myvarying. The difference is where the data comes from and how it can change during an invocation:

  • Uniforms are set from application side, and are (due to this) constant over an invocation (where invocation simplified means draw command).
  • Varyings are read from vertex inputs (in the vertex shader) or are passed and interpolated from previous shader stages (e.g. in the fragment shader).

Uniform control flow now means, that the condition of the corresponding if statement only depends on uniforms. Everything else is non-uniform control flow. Let's have a look at this fragment shader example:

//Uniforms
uniform vec3 my_uniform;
uniform sampler2D my_sampler;

/Varyings
in vec2 tex_coord;
in vec2 ndc_coords;

void main()
{
    vec3 result = vec3(0,0,0);

    if (my_uniform.y > 0.5) //Uniform control flow
        result += texture(my_sampler, tex_coord).rgb;

    if (ndc_coords.y > 0.5) //Non-uniform control flow
        result += texture(my_sampler, tex_coord).rgb;

    float some_value = ndc_coords.y + my_uniform.y;
    if (some_value > 0.5) //Still non-uniform control flow
        result += texture(my_sampler, tex_coord).rgb;
}

In this shader only the first texture read happens in uniform control flow (since the if condition only depends on a uniform variable). The other two reads are in non-uniform control flow since the if condition also depends on an varying (ndc_coords).

Upvotes: 3

Related Questions