我在 fragment 着色器中有以下代码:
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_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_tint
都是假的,所以这个 block 永远不应该执行。
顺便说一句,我正在使用 GLES20 在 Android 2.2 中对上述内容进行编程。
哪位专家能知道着色器出了什么问题吗?
最佳答案
我不是 fragment 着色器方面的专家,但我认为第二个会更快,因为整个 if 语句可以在编译时删除,因为它永远不会为真。在第一个中,它无法判断 color_tint
在运行时之前始终为 false,因此每次都需要检查并分支。分支可能很昂贵,尤其是在通常设计用于可预测串行编程的图形硬件上。
我建议您尝试将其重写为无分支 - Darren 的回答在这方面提供了一些很好的建议。
关于android - 为什么下面会拖Fragment Shader的性能(Open GL ES 2.0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5879037/