Shader value issue

found some shader made by Yojimbo2000 here: https://codea.io/talk-archive/discussion/6772/multiple-step-colour-gradient-shader
With my currently very limited shader knowledge I’ve tried to eliminate a hardcoded value from it.
Clearly there was a reason it is hardcoded because trying to send it to the shader it doesn’t work for some reason.
Outside of the shader I’m passing the value to it just like all other things were passed to it:

    local n = #Gradient.mesh.shader.gradationPositions
    Gradient.mesh.shader.numberOfGradationPoints = n

inside the shader (I left the vertex part unchanged):

--fragment
[[
precision highp float;
    
    // the number of gradation points you want to have
    uniform int numberOfGradationPoints; //-- why doesn't this work?
    //const int numberOfGradationPoints = 7; //-- original, the value is hardcoded, this works.
    
    //--transition points between colours, 0.0 - 1.0
uniform float gradationPositions[numberOfGradationPoints];  
uniform lowp vec4 colors[numberOfGradationPoints]; // colours to grade between
uniform float repeats;

uniform lowp sampler2D texture;

//varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying float vDistance;

void main()
{
lowp vec4 col = colors[0];
for (int i=1; i<numberOfGradationPoints; ++i) {
    col = mix(col, colors[i], smoothstep(gradationPositions[i-1], gradationPositions[i], fract(vTexCoord.y*repeats)));
}
gl_FragColor = texture2D( texture, vTexCoord ) * col;
}
]]

how would one do this?
is it because I’m trying to use the value right after ?
isn’t there some way to get an array’s length inside the shader?

@Amber

You cannot do what you are attempting to do directly as all uniforms need to be a known size at shader compile time (as I understand it), which a dynamically sized array like you are attempting to use would not adhere to.

Try instead to define the colors and gradationPositions arrays to the maximum number of gradation points you wish to use and just use the numberOfGradationPoints to control the number of iterations. This will allow you to pass any valid value up to the maximum defined without adding additional computation to the shader.

Like this (with other code stripped for the example):

…

uniform int numberOfGradationPoints;
const int MAX_GRADATION_POINTS = 32;

uniform float gradationPositions[MAX_GRADATION_POINTS];
uniform lowp vec4 colors[MAX_GRADATION_POINTS];

…

for (int i=1; i<numberOfGradationPoints; ++i) {
    col = mix(col, colors[i], smoothstep(gradationPositions[i-1],
}

…

Hope this helps!
Steppers

1 Like

thank you, this works and taught me something ^^

1 Like