simple but slow Shader?

Hi all,
I’ve got a problem with the performance of my shaderprogram. All it does is texturemapping for 4 texture units, but it runs very slow (~15 FPS with an Object with about 6000 Triangles consisting out of 20 submeshes). I think the fragmentshader is the problem, because when I’m very far away from the object, so that it’s only some pixels large, the object renders at 60 fps. My device is a SE Satio with SGX530.

VertexShader:

uniform highp mat4 u_Modelmat;
uniform highp mat4 u_Viewmat;
uniform highp mat4 u_Projectionmat;

attribute highp vec4 a_position;
attribute lowp vec3 a_normal;

uniform mediump vec4 u_posbiasscale;

attribute lowp vec4 a_color;


uniform mediump vec4 u_texbiasscale_0;
uniform mediump vec4 u_texbiasscale_1;
uniform mediump vec4 u_texbiasscale_2;
uniform mediump vec4 u_texbiasscale_3;

uniform int u_texmode_0;
uniform int u_texmode_1;
uniform int u_texmode_2;
uniform int u_texmode_3;

attribute mediump vec3 a_texcoord_0;
attribute mediump vec3 a_texcoord_1;
attribute mediump vec3 a_texcoord_2;
attribute mediump vec3 a_texcoord_3;

varying lowp vec4 v_color;
varying mediump vec2 v_texcoord_0;
varying mediump vec2 v_texcoord_1;
varying mediump vec2 v_texcoord_2;
varying mediump vec2 v_texcoord_3;


void main(void){

   
    mat4 mvmat=u_Viewmatu_Modelmat;
    mat4 mvpmat=u_Projectionmat
mvmat;
   
    gl_Position=mvpmata_position;
   
    //convert normal to eye space
    lowp vec3 eyenormal = normalize((mvmat
vec4(a_normal,0)).xyz);
   
    //calculate spheremap texture coordinates
    lowp vec3 refvec = normalize(reflect(gl_Position.xyz,eyenormal));
    //P=sqrt(R.x²+R.y²+(R.z+1)²)
    mediump float spheremapP=sqrt(refvec.xrefvec.x+refvec.yrefvec.y+(refvec.z+1.0)(refvec.z+1.0));
    mediump vec2 spheremaptexcoord = vec2(refvec.x/spheremapP
0.5+0.5,refvec.y/spheremapP0.5+0.5);
   
    if(u_texmode_0==1)
        v_texcoord_0=(a_texcoord_0
u_texbiasscale_0.w+u_texbiasscale_0.xyz ).xy;
    else if(u_texmode_0==2)
        v_texcoord_0=spheremaptexcoord;
   
    if(u_texmode_1==1)
        v_texcoord_1=(a_texcoord_1u_texbiasscale_1.w+u_texbiasscale_1.xyz ).xy;
    else if(u_texmode_1==2)
        v_texcoord_1=spheremaptexcoord;
   
    if(u_texmode_2==1)
        v_texcoord_2=(a_texcoord_2
u_texbiasscale_2.w+u_texbiasscale_2.xyz ).xy;
    else if(u_texmode_2==2)
        v_texcoord_2=spheremaptexcoord;
   
    if(u_texmode_3==1)
        v_texcoord_3=(a_texcoord_3*u_texbiasscale_3.w+u_texbiasscale_3.xyz ).xy;
    else if(u_texmode_3==2)
        v_texcoord_3=spheremaptexcoord;
   
    v_color=a_color;
   
}
[/CODE]

Fragment Shader:
<br>const int TOP_REPLACE = 0; <br>const int TOP_MODULATE = 1;<br>const int TOP_DECAL = 2;<br>const int TOP_BLEND = 3;<br>const int TOP_ADD = 4;<br>const int TOP_SUBTRACT = 5;<br>const int TOP_ADDSIGNED_ALPHA_MODULATE= 6;<br>const int TOP_LERP = 7;<br><br><br>varying lowp vec4 v_color;<br>varying mediump vec2 v_texcoord_0;<br>varying mediump vec2 v_texcoord_1;<br>varying mediump vec2 v_texcoord_2;<br>varying mediump vec2 v_texcoord_3;<br><br>uniform lowp sampler2D s_tex2D_0;<br>uniform lowp sampler2D s_tex2D_1;<br>uniform lowp sampler2D s_tex2D_2;<br>uniform lowp sampler2D s_tex2D_3;<br><br>uniform int u_texmode_0;<br>uniform int u_texmode_1;<br>uniform int u_texmode_2;<br>uniform int u_texmode_3;<br><br>uniform int u_texBlending_0;<br>uniform int u_texBlending_1;<br>uniform int u_texBlending_2;<br>uniform int u_texBlending_3;<br><br>uniform lowp vec4 u_texConstColor_0;<br>uniform lowp vec4 u_texConstColor_1;<br>uniform lowp vec4 u_texConstColor_2;<br>uniform lowp vec4 u_texConstColor_3;<br><br>void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor);<br><br>void main(void){<br>&nbsp;&nbsp;&nbsp; //gl_FragColor=v_color;<br>&nbsp;&nbsp;&nbsp; //for testing purposes:<br>&nbsp;&nbsp;&nbsp; gl_FragColor=vec4(0.8,0.8,0.8,1);<br>&nbsp;&nbsp;&nbsp; if(u_texmode_0!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_0,texture2D(s_tex2D_0,v_texcoord_0),u_texConstColor_0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if(u_texmode_1!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_1,texture2D(s_tex2D_1,v_texcoord_1),u_texConstColor_1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if(u_texmode_2!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_2,texture2D(s_tex2D_2,v_texcoord_2),u_texConstColor_2);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if(u_texmode_3!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_3,texture2D(s_tex2D_3,v_texcoord_3),u_texConstColor_3);<br>&nbsp;&nbsp;&nbsp; }<br>}<br><br>//might the many branches be the problem?<br>void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor){<br>&nbsp;&nbsp;&nbsp; if(blendMode==TOP_MODULATE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor*=color;<br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_REPLACE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_ADD){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor+=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_SUBTRACT){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor-=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_DECAL){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.a)+color.rgb*color.a,gl_FragColor.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_BLEND){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.rgb)+color.rgb*constColor.rgb,gl_FragColor.a*color.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_ADDSIGNED_ALPHA_MODULATE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb+(color.rgb-0.5),gl_FragColor.a*color.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_LERP){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=color*constColor+gl_FragColor*(1.0-constColor);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>}<br>
Do you have any optimization tips for me or any idea what causes the problem?
BTW: The object is rendered with lightning and texturing enabled via the fixed-function pileline at 80 fps.

Thanks in advance Smile

<br>uniform highp mat4 u_Modelmat;<br>uniform highp mat4 u_Viewmat;<br>uniform highp mat4 u_Projectionmat;<br><br>attribute highp vec4 a_position;<br>attribute lowp vec3 a_normal;<br><br>uniform mediump vec4 u_posbiasscale;<br><br>attribute lowp vec4 a_color;<br><br><br>uniform mediump vec4 u_texbiasscale_0;<br>uniform mediump vec4 u_texbiasscale_1;<br>uniform mediump vec4 u_texbiasscale_2;<br>uniform mediump vec4 u_texbiasscale_3;<br><br>uniform int u_texmode_0;<br>uniform int u_texmode_1;<br>uniform int u_texmode_2;<br>uniform int u_texmode_3;<br><br>attribute mediump vec3 a_texcoord_0;<br>attribute mediump vec3 a_texcoord_1;<br>attribute mediump vec3 a_texcoord_2;<br>attribute mediump vec3 a_texcoord_3;<br><br>varying lowp vec4 v_color;<br>varying mediump vec2 v_texcoord_0;<br>varying mediump vec2 v_texcoord_1;<br>varying mediump vec2 v_texcoord_2;<br>varying mediump vec2 v_texcoord_3;<br><br><br>void main(void){<br><br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; mat4 mvmat=u_Viewmat*u_Modelmat;<br>&nbsp;&nbsp;&nbsp; mat4 mvpmat=u_Projectionmat*mvmat;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; gl_Position=mvpmat*a_position;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; //convert normal to eye space<br>&nbsp;&nbsp;&nbsp; lowp vec3 eyenormal = normalize((mvmat*vec4(a_normal,0)).xyz);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; //calculate spheremap texture coordinates<br>&nbsp;&nbsp;&nbsp; lowp vec3 refvec = normalize(reflect(gl_Position.xyz,eyenormal));<br>&nbsp;&nbsp;&nbsp; //P=sqrt(R.x²+R.y²+(R.z+1)²)<br>&nbsp;&nbsp;&nbsp; mediump float spheremapP=sqrt(refvec.x*refvec.x+refvec.y*refvec.y+(refvec.z+1.0)*(refvec.z+1.0));<br>&nbsp;&nbsp;&nbsp; mediump vec2 spheremaptexcoord = vec2(refvec.x/spheremapP*0.5+0.5,refvec.y/spheremapP*0.5+0.5);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if(u_texmode_0==1)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_0=(a_texcoord_0*u_texbiasscale_0.w+u_texbiasscale_0.xyz ).xy;<br>&nbsp;&nbsp;&nbsp; else if(u_texmode_0==2)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_0=spheremaptexcoord;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if(u_texmode_1==1) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_1=(a_texcoord_1*u_texbiasscale_1.w+u_texbiasscale_1.xyz ).xy;<br>&nbsp;&nbsp;&nbsp; else if(u_texmode_1==2) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_1=spheremaptexcoord;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if(u_texmode_2==1) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_2=(a_texcoord_2*u_texbiasscale_2.w+u_texbiasscale_2.xyz ).xy;<br>&nbsp;&nbsp;&nbsp; else if(u_texmode_2==2) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_2=spheremaptexcoord;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if(u_texmode_3==1) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_3=(a_texcoord_3*u_texbiasscale_3.w+u_texbiasscale_3.xyz ).xy;<br>&nbsp;&nbsp;&nbsp; else if(u_texmode_3==2)<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; v_texcoord_3=spheremaptexcoord;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; v_color=a_color;<br>&nbsp;&nbsp;&nbsp; <br>}<br>

Fragment Shader:

const int TOP_REPLACE = 0;
const int TOP_MODULATE = 1;
const int TOP_DECAL = 2;
const int TOP_BLEND = 3;
const int TOP_ADD = 4;
const int TOP_SUBTRACT = 5;
const int TOP_ADDSIGNED_ALPHA_MODULATE= 6;
const int TOP_LERP = 7;


varying lowp vec4 v_color;
varying mediump vec2 v_texcoord_0;
varying mediump vec2 v_texcoord_1;
varying mediump vec2 v_texcoord_2;
varying mediump vec2 v_texcoord_3;

uniform lowp sampler2D s_tex2D_0;
uniform lowp sampler2D s_tex2D_1;
uniform lowp sampler2D s_tex2D_2;
uniform lowp sampler2D s_tex2D_3;

uniform int u_texmode_0;
uniform int u_texmode_1;
uniform int u_texmode_2;
uniform int u_texmode_3;

uniform int u_texBlending_0;
uniform int u_texBlending_1;
uniform int u_texBlending_2;
uniform int u_texBlending_3;

uniform lowp vec4 u_texConstColor_0;
uniform lowp vec4 u_texConstColor_1;
uniform lowp vec4 u_texConstColor_2;
uniform lowp vec4 u_texConstColor_3;

void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor);

void main(void){
    //gl_FragColor=v_color;
    //for testing purposes:
    gl_FragColor=vec4(0.8,0.8,0.8,1);
    if(u_texmode_0!=0){
        blendColorToDest(u_texBlending_0,texture2D(s_tex2D_0,v_texcoord_0),u_texConstColor_0);
    }
    if(u_texmode_1!=0){
        blendColorToDest(u_texBlending_1,texture2D(s_tex2D_1,v_texcoord_1),u_texConstColor_1);
    }
    if(u_texmode_2!=0){
        blendColorToDest(u_texBlending_2,texture2D(s_tex2D_2,v_texcoord_2),u_texConstColor_2);
    }
    if(u_texmode_3!=0){
        blendColorToDest(u_texBlending_3,texture2D(s_tex2D_3,v_texcoord_3),u_texConstColor_3);
    }
}

//might the many branches be the problem?
void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor){
    if(blendMode==TOP_MODULATE){
        gl_FragColor*=color;
    }else if(blendMode==TOP_REPLACE){
        gl_FragColor=color;       
    }else if(blendMode==TOP_ADD){
        gl_FragColor+=color;       
    }else if(blendMode==TOP_SUBTRACT){
        gl_FragColor-=color;       
    }else if(blendMode==TOP_DECAL){
        gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.a)+color.rgbcolor.a,gl_FragColor.a);       
    }else if(blendMode==TOP_BLEND){
        gl_FragColor=vec4(gl_FragColor.rgb
(1.0-color.rgb)+color.rgbconstColor.rgb,gl_FragColor.acolor.a);       
    }else if(blendMode==TOP_ADDSIGNED_ALPHA_MODULATE){
        gl_FragColor=vec4(gl_FragColor.rgb+(color.rgb-0.5),gl_FragColor.acolor.a);       
    }else if(blendMode==TOP_LERP){
        gl_FragColor=color
constColor+gl_FragColor*(1.0-constColor);       
    }
}
[/CODE]
Do you have any optimization tips for me or any idea what causes the problem?
BTW: The object is rendered with lightning and texturing enabled via the fixed-function pileline at 80 fps.

Thanks in advance Smile

<br>const int TOP_REPLACE = 0; <br>const int TOP_MODULATE = 1;<br>const int TOP_DECAL = 2;<br>const int TOP_BLEND = 3;<br>const int TOP_ADD = 4;<br>const int TOP_SUBTRACT = 5;<br>const int TOP_ADDSIGNED_ALPHA_MODULATE= 6;<br>const int TOP_LERP = 7;<br><br><br>varying lowp vec4 v_color;<br>varying mediump vec2 v_texcoord_0;<br>varying mediump vec2 v_texcoord_1;<br>varying mediump vec2 v_texcoord_2;<br>varying mediump vec2 v_texcoord_3;<br><br>uniform lowp sampler2D s_tex2D_0;<br>uniform lowp sampler2D s_tex2D_1;<br>uniform lowp sampler2D s_tex2D_2;<br>uniform lowp sampler2D s_tex2D_3;<br><br>uniform int u_texmode_0;<br>uniform int u_texmode_1;<br>uniform int u_texmode_2;<br>uniform int u_texmode_3;<br><br>uniform int u_texBlending_0;<br>uniform int u_texBlending_1;<br>uniform int u_texBlending_2;<br>uniform int u_texBlending_3;<br><br>uniform lowp vec4 u_texConstColor_0;<br>uniform lowp vec4 u_texConstColor_1;<br>uniform lowp vec4 u_texConstColor_2;<br>uniform lowp vec4 u_texConstColor_3;<br><br>void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor);<br><br>void main(void){<br>&nbsp;&nbsp;&nbsp; //gl_FragColor=v_color;<br>&nbsp;&nbsp;&nbsp; //for testing purposes:<br>&nbsp;&nbsp;&nbsp; gl_FragColor=vec4(0.8,0.8,0.8,1);<br>&nbsp;&nbsp;&nbsp; if(u_texmode_0!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_0,texture2D(s_tex2D_0,v_texcoord_0),u_texConstColor_0);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if(u_texmode_1!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_1,texture2D(s_tex2D_1,v_texcoord_1),u_texConstColor_1);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if(u_texmode_2!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_2,texture2D(s_tex2D_2,v_texcoord_2),u_texConstColor_2);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; if(u_texmode_3!=0){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_3,texture2D(s_tex2D_3,v_texcoord_3),u_texConstColor_3);<br>&nbsp;&nbsp;&nbsp; }<br>}<br><br>//might the many branches be the problem?<br>void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor){<br>&nbsp;&nbsp;&nbsp; if(blendMode==TOP_MODULATE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor*=color;<br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_REPLACE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_ADD){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor+=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_SUBTRACT){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor-=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_DECAL){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.a)+color.rgb*color.a,gl_FragColor.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_BLEND){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.rgb)+color.rgb*constColor.rgb,gl_FragColor.a*color.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_ADDSIGNED_ALPHA_MODULATE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb+(color.rgb-0.5),gl_FragColor.a*color.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_LERP){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=color*constColor+gl_FragColor*(1.0-constColor);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>}<br>
Do you have any optimization tips for me or any idea what causes the problem?
BTW: The object is rendered with lightning and texturing enabled via the fixed-function pileline at 80 fps.

Thanks in advance Smile

From my understanding of how dynamic branching works in shaders , your code executes more less in this way:





blendColorToDest(u_texBlending_0,texture2D(s_tex2D_0,v_texcoord_0),u_texConstColor_0);


if(u_texmode_0==0)


{


   discard result      


}








blendColorToDest(u_texBlending_1,texture2D(s_tex2D_1,v_texcoord_1),u_texConstColor_1);


if(u_texmode_1==0)


{


   discard result


}





and so on …





In other words, I tbink you will need to create separate shaders for different blending modes to make this perform.




oh ok, i thought the gpu would do it like cpus an would simply skip the code. Thank you

EDIT: I read the OGLES 2.0 Application Recommandations again, it says that static branches can be used to skip possibly expensive code but:
Quote:

Don't use texture lookups without explicit LOD in a conditionally executed part of a shader


I'll create 4 shaders with one, two,  three and four texture units , maybe this helps.
3DGamer2010-04-24 11:14:49

I’ve rewritten the fragment and the vertex shader:


#define NUM_TEXTURE_UNITS 1

const int TOP_REPLACE = 0;
const int TOP_MODULATE = 1;
const int TOP_DECAL = 2;
const int TOP_BLEND = 3;
const int TOP_ADD = 4;
const int TOP_SUBTRACT = 5;
const int TOP_ADDSIGNED_ALPHA_MODULATE= 6;
const int TOP_LERP = 7;


varying lowp vec4 v_color;

#if NUM_TEXTURE_UNITS >= 1   
varying mediump vec2 v_texcoord_0;
uniform lowp sampler2D s_tex2D_0;
uniform int u_texmode_0;
uniform int u_texBlending_0;
uniform lowp vec4 u_texConstColor_0;
#endif

#if NUM_TEXTURE_UNITS >= 2   
varying mediump vec2 v_texcoord_1;
uniform lowp sampler2D s_tex2D_1;
uniform int u_texmode_1;
uniform int u_texBlending_1;
uniform lowp vec4 u_texConstColor_1;
#endif


#if NUM_TEXTURE_UNITS >= 3   
varying mediump vec2 v_texcoord_2;
uniform lowp sampler2D s_tex2D_2;
uniform int u_texmode_2;
uniform int u_texBlending_2;
uniform lowp vec4 u_texConstColor_2;
#endif

#if NUM_TEXTURE_UNITS >= 4   
varying mediump vec2 v_texcoord_3;
uniform lowp sampler2D s_tex2D_3;
uniform int u_texmode_3;
uniform int u_texBlending_3;
uniform lowp vec4 u_texConstColor_3;
#endif


void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor);

void main(void){
    //gl_FragColor=v_color;
    //for testing purposes:
    gl_FragColor=vec4(0.6,0.6,0.6,1);
   
#if NUM_TEXTURE_UNITS >= 1   
    blendColorToDest(u_texBlending_0,texture2D(s_tex2D_0,v_texcoord_0),u_texConstColor_0);
#endif

#if NUM_TEXTURE_UNITS >= 2   
    blendColorToDest(u_texBlending_1,texture2D(s_tex2D_1,v_texcoord_1),u_texConstColor_1);
#endif

#if NUM_TEXTURE_UNITS >= 3   
    blendColorToDest(u_texBlending_2,texture2D(s_tex2D_2,v_texcoord_2),u_texConstColor_2);
#endif

#if NUM_TEXTURE_UNITS >= 4   
    blendColorToDest(u_texBlending_3,texture2D(s_tex2D_3,v_texcoord_3),u_texConstColor_3);
#endif

}

void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor){
    if(blendMode==TOP_MODULATE){
        gl_FragColor*=color;
    }else if(blendMode==TOP_REPLACE){
        gl_FragColor=color;       
    }else if(blendMode==TOP_ADD){
        gl_FragColor+=color;       
    }else if(blendMode==TOP_SUBTRACT){
        gl_FragColor-=color;       
    }else if(blendMode==TOP_DECAL){
        gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.a)+color.rgbcolor.a,gl_FragColor.a);       
    }else if(blendMode==TOP_BLEND){
        gl_FragColor=vec4(gl_FragColor.rgb
(1.0-color.rgb)+color.rgbconstColor.rgb,gl_FragColor.acolor.a);       
    }else if(blendMode==TOP_ADDSIGNED_ALPHA_MODULATE){
        gl_FragColor=vec4(gl_FragColor.rgb+(color.rgb-0.5),gl_FragColor.acolor.a);       
    }else if(blendMode==TOP_LERP){
        gl_FragColor=color
constColor+gl_FragColor*(1.0-constColor);       
    }
}
[/CODE]
There’s only one problem: when i define “NUM_TEXTURE_UNITS” with 2, the compiler just says “compile failed.” and nothing else. It works with any other number from zero to four.

<br><br>#define NUM_TEXTURE_UNITS 1<br><br>const int TOP_REPLACE = 0; <br>const int TOP_MODULATE = 1;<br>const int TOP_DECAL = 2;<br>const int TOP_BLEND = 3;<br>const int TOP_ADD = 4;<br>const int TOP_SUBTRACT = 5;<br>const int TOP_ADDSIGNED_ALPHA_MODULATE= 6;<br>const int TOP_LERP = 7;<br><br><br>varying lowp vec4 v_color;<br><br>#if NUM_TEXTURE_UNITS &gt;= 1&nbsp;&nbsp;&nbsp; <br>varying mediump vec2 v_texcoord_0;<br>uniform lowp sampler2D s_tex2D_0;<br>uniform int u_texmode_0;<br>uniform int u_texBlending_0;<br>uniform lowp vec4 u_texConstColor_0;<br>#endif<br><br>#if NUM_TEXTURE_UNITS &gt;= 2&nbsp;&nbsp;&nbsp; <br>varying mediump vec2 v_texcoord_1;<br>uniform lowp sampler2D s_tex2D_1;<br>uniform int u_texmode_1;<br>uniform int u_texBlending_1;<br>uniform lowp vec4 u_texConstColor_1;<br>#endif<br><br><br>#if NUM_TEXTURE_UNITS &gt;= 3&nbsp;&nbsp;&nbsp; <br>varying mediump vec2 v_texcoord_2;<br>uniform lowp sampler2D s_tex2D_2;<br>uniform int u_texmode_2;<br>uniform int u_texBlending_2;<br>uniform lowp vec4 u_texConstColor_2;<br>#endif<br><br>#if NUM_TEXTURE_UNITS &gt;= 4&nbsp;&nbsp;&nbsp; <br>varying mediump vec2 v_texcoord_3;<br>uniform lowp sampler2D s_tex2D_3;<br>uniform int u_texmode_3;<br>uniform int u_texBlending_3;<br>uniform lowp vec4 u_texConstColor_3;<br>#endif<br><br><br>void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor);<br><br>void main(void){<br>&nbsp;&nbsp;&nbsp; //gl_FragColor=v_color;<br>&nbsp;&nbsp;&nbsp; //for testing purposes:<br>&nbsp;&nbsp;&nbsp; gl_FragColor=vec4(0.6,0.6,0.6,1);<br>&nbsp;&nbsp;&nbsp; <br>#if NUM_TEXTURE_UNITS &gt;= 1&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_0,texture2D(s_tex2D_0,v_texcoord_0),u_texConstColor_0);<br>#endif<br><br>#if NUM_TEXTURE_UNITS &gt;= 2&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_1,texture2D(s_tex2D_1,v_texcoord_1),u_texConstColor_1);<br>#endif<br><br>#if NUM_TEXTURE_UNITS &gt;= 3&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_2,texture2D(s_tex2D_2,v_texcoord_2),u_texConstColor_2);<br>#endif<br><br>#if NUM_TEXTURE_UNITS &gt;= 4&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; blendColorToDest(u_texBlending_3,texture2D(s_tex2D_3,v_texcoord_3),u_texConstColor_3);<br>#endif<br><br>}<br><br>void blendColorToDest(in int blendMode, in lowp vec4 color, in lowp vec4 constColor){<br>&nbsp;&nbsp;&nbsp; if(blendMode==TOP_MODULATE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor*=color;<br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_REPLACE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_ADD){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor+=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_SUBTRACT){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor-=color;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_DECAL){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.a)+color.rgb*color.a,gl_FragColor.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_BLEND){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb*(1.0-color.rgb)+color.rgb*constColor.rgb,gl_FragColor.a*color.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_ADDSIGNED_ALPHA_MODULATE){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=vec4(gl_FragColor.rgb+(color.rgb-0.5),gl_FragColor.a*color.a);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }else if(blendMode==TOP_LERP){<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gl_FragColor=color*constColor+gl_FragColor*(1.0-constColor);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; }<br>}<br>
There’s only one problem: when i define “NUM_TEXTURE_UNITS” with 2, the compiler just says “compile failed.” and nothing else. It works with any other number from zero to four.

warmi wrote:
From my understanding of how dynamic branching works in shaders , your code executes more less in this way:

This is only the case for very short conditional blocks. For longer blocks the GPU actually skips the conditional code.



3DGamer wrote:
//might the many branches be the problem?

Yes, these are indeed part of the problem. Branches and comparisons are not free, and in this shader the branching overhead is much higher than the cost of the operations you want to perform for any specific setup.

To emulate fixed function fragment processing you really should create a branch-free fragment shader for every combination of texture enables and texture combine operations used in your application.



Quote:
There's only one problem: when i define "NUM_TEXTURE_UNITS" with 2, the compiler just says "compile failed." and nothing else. It works with any other number from zero to four.


Which compiler (platform, version) are you referring to?

Xmas wrote:

Which compiler (platform, version) are you referring to?


I use the online compiler on a Sony Ericsson Satio (Symbian S60v5, latest firmware, TI OMAP3430 + SGX530), but I don't know the compiler version (Is there any way to get it via OPENGL?). However, I'm now redesigning my engine so that these problems don't occur anymore, I'm removing all backward compatibility.

BTW: Is there any problem with for loops with an uniform in the stop condition?
3DGamer2010-04-27 15:21:36