Android 为什么以下内容会影响片段着色器的性能(Open GL ES 2.0)
片段着色器中有以下代码:Android 为什么以下内容会影响片段着色器的性能(Open GL ES 2.0),android,performance,opengl-es-2.0,frame-rate,fragment-shader,Android,Performance,Opengl Es 2.0,Frame Rate,Fragment Shader,片段着色器中有以下代码: precision lowp float; varying vec2 v_texCoord; uniform sampler2D s_texture; uniform bool color_tint; uniform float color_tint_amount; uniform vec4 color_tint_color; void main(){ float gradDistance; vec4 texColor, gradColor;
precision lowp float;
varying vec2 v_texCoord;
uniform sampler2D s_texture;
uniform bool color_tint;
uniform float color_tint_amount;
uniform vec4 color_tint_color;
void main(){
float gradDistance;
vec4 texColor, gradColor;
texColor = texture2D(s_texture, v_texCoord);
if (color_tint){
gradColor = color_tint_color;
gradColor.a = texColor.a;
texColor = gradColor * color_tint_amount + texColor * (1.0 - color_tint_amount);
}
gl_FragColor = texColor;
}
代码运行良好,但有趣的是,即使我传入的所有color\u tint
都是false,上面的代码仍然会导致性能严重下降。与以下内容相比:
void main(){
float gradDistance;
vec4 texColor, gradColor;
texColor = texture2D(s_texture, v_texCoord);
if (false){
gradColor = color_tint_color;
gradColor.a = texColor.a;
texColor = gradColor * color_tint_amount + texColor * (1.0 - color_tint_amount);
}
gl_FragColor = texColor;
}
后者可以达到40+fps,而前者约为18 fps。我反复检查,第一个中传递的所有color\u tint
都是false,因此该块永远不会执行
顺便说一句,我正在使用GLES20在Android 2.2中对上述内容进行编程
任何专家都知道着色器有什么问题吗?分支在片段着色器上非常慢。如果可能,请避免使用它们。使用“颜色着色”数量0表示“无着色”。预倍增颜色着色并保存每像素的倍增。使颜色着色数量=1.0-颜色着色数量。(所以现在1.0意味着没有gradColor)这些着色器每秒运行数百万次,你必须尽可能保存每个循环。我不是片段着色器的专家,但我认为第二个会更快,因为整个if语句可以在编译时删除,因为它永远不会为真。在第一个例子中,直到运行时,它才知道
color\u tint
始终为false,因此每次都需要检查并进行分支。分支可能很昂贵,尤其是在通常为可预测的串行编程而设计的图形硬件上
我建议您尝试将其改写为无分支-Darren的答案在这方面有一些很好的建议。谢谢您的提示。但是我不明白为什么
if()
中的两个代码都没有执行(因为我传递的是false),后面的代码比第一个快?因为在第一种情况下,仍然必须执行if()语句来计算表达式。另一个解决方案是简单地使用两个不同的片段着色器,一个应用颜色着色,另一个不应用。例如,这就是Android 3.0中2D硬件加速管道所做的。@Romain,似乎不同的着色器将是最好的解决方案。谢谢。我做了另一个测试,发现分支非常昂贵:它甚至比一些distance()计算还要重。