Tweeted twitter.com/#!/StackGameDev/status/319717992554438656
2 edited tags
| link
1
source | link

iPhone GLSL shader dynamic branching issue

I am trying to pass an array of vec3 as uniform and then iterate through them on each pixel. The size of array varies on situations so I can't make the loop with constant number of iterations.

Here is the code:

precision highp float;
precision highp int;

varying vec4 v_fragmentColor;

varying vec4 v_pos;

uniform int u_numberOfParticles;

const int numberOfAccumsToCapture = 3;
const float threshold = 0.15;              
const float gooCoeff = 1.19;

uniform mat4 u_MVPMatrix;
uniform vec3 u_waterVertices[100];

void main()
{
    vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0);

    vec2 currPos = v_pos.xy;

    float accum = 0.0;
    vec3 normal = vec3(0, 0, 0);

    for ( int i = 0; i < u_numberOfParticles; ++i )
    {
        vec2 dir2 = u_waterVertices[i].xy - currPos.xy;
        vec3 dir3 = vec3(dir2, 0.1);
        float q = dot(dir2, dir2);

        accum += u_waterVertices[i].z / q;
    }

    float normalizeToEdge = 1.0 - (accum - threshold) / 2.0;

    if (normalizeToEdge < 0.4)
        finalColor = vec4( 0.1, normalizeToEdge + 0.5, 0.9-normalizeToEdge*0.4, 1.0);

    if ( normalizeToEdge < 0.2 )
    {
        finalColor = vec4( 120.0/255.0, 245.0/255.0, 245.0/255.0, 1.0);
        float shade = mix( 0.7, 1.0, normal.x);
        finalColor *= shade;
    }

    gl_FragColor = vec4(finalColor);
}

The problem is here:

for ( int i = 0; i < u_numberOfParticles; ++i )
{
    vec2 dir2 = u_waterVertices[i].xy - currPos.xy;
    vec3 dir3 = vec3(dir2, 0.1);
    float q = dot(dir2, dir2);

    accum += u_waterVertices[i].z / q;
}

When I make the for-loop like this

for ( int i = 0; i < 2; ++i )
{
    //...
}

I get double the framerate even though u_numberOfParticles is also 2

Making it like this

for ( int i = 0; i < 100; ++i )
{
    if (i == u_numberOfParticles)
        break;
    //...
}

gives no improvement.

The only way I know to cope with this situation is to create multiple shaders. But The size of array may vary from 1 to 40 and making 40 different shaders just because of the for-loop is stupid. Any help or ideas how to deal with this situation ?