我用OpenGL ES 2着色器重新实现了Apple的GLImageProcessing。效果是完美的,但是“锐度”滤镜的性能却不如它—仅以20 FPS运行。
着色器代码很简单:
基本上,第2遍中的纹理混合是速度较慢的原因,因为第0遍和第1遍仅执行一次,不会导致性能下降。
如何提高性能?
顶点着色器:
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying highp vec2 v_texCoord;
varying highp vec2 v_texCoord1;
varying highp vec2 v_texCoord2;
varying highp vec2 v_texCoord1_;
varying highp vec2 v_texCoord2_;
uniform mat4 u_modelViewProjectionMatrix;
uniform lowp int u_pass;
const highp float blurSizeH = 1.0 / 320.0;
const highp float blurSizeV = 1.0 / 480.0;
void main()
{
v_texCoord = a_texCoord;
if (u_pass == 0) {
v_texCoord1 = a_texCoord + vec2(1.3846153846 * blurSizeH, 0.0);
v_texCoord1_ = a_texCoord - vec2(1.3846153846 * blurSizeH, 0.0);
v_texCoord2 = a_texCoord + vec2(3.2307692308 * blurSizeH, 0.0);
v_texCoord2_ = a_texCoord - vec2(3.2307692308 * blurSizeH, 0.0);
} else if (u_pass == 1) {
v_texCoord1 = a_texCoord + vec2(0.0, 1.3846153846 * blurSizeV);
v_texCoord1_ = a_texCoord - vec2(0.0, 1.3846153846 * blurSizeV);
v_texCoord2 = a_texCoord + vec2(0.0, 3.2307692308 * blurSizeV);
v_texCoord2_ = a_texCoord - vec2(0.0, 3.2307692308 * blurSizeV);
}
gl_Position = u_modelViewProjectionMatrix * a_position;
}
片段着色器:
varying highp vec2 v_texCoord;
varying highp vec2 v_texCoord1;
varying highp vec2 v_texCoord2;
varying highp vec2 v_texCoord1_;
varying highp vec2 v_texCoord2_;
uniform lowp int u_pass;
uniform sampler2D u_texture;
uniform sampler2D u_degenTexture;
uniform mediump mat4 u_filterMat;
void main()
{
if (u_pass == 0) {
gl_FragColor = texture2D(u_texture, v_texCoord) * 0.2270270270;
gl_FragColor += texture2D(u_texture, v_texCoord1) * 0.3162162162;
gl_FragColor += texture2D(u_texture, v_texCoord1_) * 0.3162162162;
gl_FragColor += texture2D(u_texture, v_texCoord2) * 0.0702702703;
gl_FragColor += texture2D(u_texture, v_texCoord2_) * 0.0702702703;
} else if (u_pass == 1) {
gl_FragColor = texture2D(u_degenTexture, v_texCoord) * 0.2270270270;
gl_FragColor += texture2D(u_degenTexture, v_texCoord1) * 0.3162162162;
gl_FragColor += texture2D(u_degenTexture, v_texCoord1_) * 0.3162162162;
gl_FragColor += texture2D(u_degenTexture, v_texCoord2) * 0.0702702703;
gl_FragColor += texture2D(u_degenTexture, v_texCoord2_) * 0.0702702703;
} else {
gl_FragColor = u_filterMat * texture2D(u_texture, v_texCoord) + (mat4(1.0) - u_filterMat) * texture2D(u_degenTexture, v_texCoord);
}
}
最佳答案
在继续之前,我是否建议您看一下我的开源GPUImage项目?我在那里有几个手动优化的锐化效果,包括您在此处尝试的不清晰蒙版。我还使引入图像和视频源变得相当容易。
对于您的特定问题,着色器的运行速度比预期的慢有两个原因。首先是您正在片段着色器中使用分支。这会破坏iOS设备上的性能,应尽可能避免使用。如果确实需要针对不同的传递使用不同的条件,请将它们分成单独的着色器程序,然后根据需要交换出程序,而不要使用统一的控制流。
我也不确定重复写入gl_FragColor是您在这里可以做的最快的事情。我将使用lowp或mediump中间颜色变量,向其中添加您的高斯分量,然后在完成后将最终结果写入gl_FragColor。
我确实看到您已将采样偏移量计算移至顶点着色器,然后将这些偏移量传递给片段着色器,这是人们通常会错过的一件好事。一旦实现了上述调整(或尝试让我的框架了解如何处理),您的过滤效果就会更好。