最有效的GLSL边缘检测着色器方法

aka*_*aru 5 iphone graphics opengl-es glsl opengl-es-2.0

我正在为视频应用寻找快速,肮脏,非常有效的边缘检测着色器或边缘网格.由于这将在移动设备上完成,因此我需要能够提高性能而不是准确性的东西.无论如何我会模糊输出,我所看到的所有边缘检测算法都倾向于通过比较原始图像和模糊图像的特定阈值来完成.我认为这种模糊往往会导致最大的性能问题.

我有这样的功能:

vec4 edge()
{

    float K00 = -1.0;
    float K01 = -2.0;
    float K02 = -1.0;
    float K10 = 0.0;
    float K11 = 0.0;
    float K12 = 0.0;
    float K20 = 1.0;
    float K21 = 2.0;
    float K22 = 1.0;

    vec2 ox = vec2 (0.0,0.0);
    ox[0] = width;
    vec2 oy = vec2 (0.0,0.0);
    oy[1] = height;

    float g00, g01, g02;
    float g10, g11, g12;
    float g20, g21, g22;
    vec4 CC;

    vec2 PP = TextureCoord - oy;
    CC = texture2D(blurredFrame, vec2(PP-ox));
    g00 = getGrey(CC);
    CC = texture2D(blurredFrame, vec2(PP));
    g01 = getGrey(CC);
    CC = texture2D(blurredFrame, vec2(PP+ox));
    g02 = getGrey(CC);


    PP = TextureCoord;
    CC = texture2D(blurredFrame, vec2(PP-ox));
    g10 = getGrey(CC);
    CC = texture2D(blurredFrame, vec2(PP));
    g11 = getGrey(CC);
    CC = texture2D(blurredFrame, vec2(PP+ox));
    g12 = getGrey(CC);

    PP = TextureCoord + oy;
    CC = texture2D(blurredFrame, vec2(PP-ox));
    g20 = getGrey(CC);
    CC = texture2D(blurredFrame, vec2(PP));
    g21 = getGrey(CC);
    CC = texture2D(blurredFrame, vec2(PP+ox));
    g22 = getGrey(CC);

    float sx = 0.0, sy = 0.0;
    sx = sx + g00 * K00;
    sx = sx + g01 * K01;
    sx = sx + g02 * K02;
    sx = sx + g10 * K10;
    sx = sx + g11 * K11;
    sx = sx + g12 * K12;
    sx = sx + g20 * K20;
    sx = sx + g21 * K21;
    sx = sx + g22 * K22;
    sy = sy + g00 * K00;
    sy = sy + g01 * K10;
    sy = sy + g02 * K20;
    sy = sy + g10 * K01;
    sy = sy + g11 * K11;
    sy = sy + g12 * K21;
    sy = sy + g20 * K02;
    sy = sy + g21 * K12;
    sy = sy + g22 * K22;

    float dist = sqrt(sx * sx + sy * sy);

    return dist > threshold ? vec4 (0,0,0,1) : vec4 (1,1,1,1);
}
Run Code Online (Sandbox Code Playgroud)

我看到的所有示例都是这样的,似乎专注于桌面平台 - 在iPhone或Android设备上获得合适的帧速率也太费力和昂贵.这仅适用于2d应用程序,速度是关键.

有什么想法可以提高效率,或者更好的选择?感谢大家.

Him*_*ury 4

不确定我是否知道不同的算法。

但是,我想到了一些建议:

  1. 在与 dist 进行比较之前不要使用 sqrt(),而是与 dist^2 进行比较
  2. 看看是否可以优化纹理加载的访问模式。纹理内存访问模式会对性能产生很大影响。您希望保持内存访问尽可能连续(即 0,1,2,3,...),而不是随机的。
  3. 关闭 mip 映射,或使用texture2DLod 手动指定 mip 映射级别。