片段着色器有时间限制吗? iOS使用Brad Larson的GPUImage过滤器

时间:2015-05-02 21:46:37

标签: opengl-es gpuimage fragment-shader

我在iOS 8上使用Brad Larson优秀的图书馆GPUImage 我遇到了一个问题过滤器,它只完成了3/4的任务/片段,在单个图像上运行,但是有多个过滤器:

从我正在进行的测试来看,似乎我违反了时间限制或缓冲区大小,但奇怪的是看起来更像是一个时间限制......即使可能不是这样,我更有可能在某处溢出。

看到下图,我正在GPUImage中运行一些普通的过滤器,然后应用我在最后创建的新过滤器,这需要5到8秒才能完成。我可以调整新过滤器片段着色器内部的循环量,看它运行得更快,然后最后一个过滤器完成,即使它占用相同数量的缓冲区空间(我相信)。

(另见下面片段着色器的代码)

如果我按照我想要的方式离开过滤器,下面的图像是停止大约3/4完成的结果,你可以奇怪地看到下面的倒数第三个过滤器(GPUImageDirectionalSobelEdgeDetectionFilter过滤器,而不是倒数第二个过滤器,GPUImageDirectionalNonMaximumSuppressionFilter过滤器

我在Brad Larson的代码中找不到任何限制缓冲区或时间的“限制”。

看起来我是在溢出缓冲区还是遇到其他限制?记住我可以通过简单地减少最后一个片段着色器中的一些循环来完成这个过滤器,而不是改变任何其他东西..并且循环没有填充任何缓冲区,只计算一些浮点数和vecs(可能以某种方式溢出一个?)

(编辑:可能有些缓冲区/图像空间被释放或其他,因为这个过程需要很长时间才能解除分配/释放?)

enter image description here

下面是Brad的一些调试代码,用于链接和编译程序/过滤器的时间量

核心图形绘制时间:731.258035

GLProgram编制于5.171001 ms

GLProgram编译于2.515018 ms

GLProgram链接于5.878985 ms

GLProgram编译时间为0.092983毫秒

GLProgram编译于0.181973 ms

GLProgram链接于1.731992 ms

GLProgram编译时间为0.275016 ms

GLProgram编译时间为0.414014 ms

GLProgram链接在1.176000毫秒

GLProgram编译时间为0.074029 ms

GLProgram编译时间为0.380039 ms

GLProgram链接在0.957966 ms

GLProgram编译时间为0.078022 ms

GLProgram编译于1.359999 ms

GLProgram链接于5.873978毫秒

这里是片段着色器的一部分,循环部分,我可以通过任意数量的方式调整,以使它花费更短的时间,并完成过滤器,我遗漏(由...等) ..etc ...)在新过滤器的这个片段着色器的循环中更加相同:

    [sourcePicture addTarget:theNewFilter];
    [theNewFilter useNextFrameForImageCapture];

    [sourcePicture processImage];

    UIImage *currentFilteredVideoFrame = [theNewFilter imageFromCurrentFramebuffer];

    [self.zoomView setImage:currentFilteredVideoFrame];

和片段着色器:

(
    precision mediump float;

    uniform sampler2D inputImageTexture;
    varying mediump vec2 textureCoordinate;

    uniform mediump float texelWidth;
    uniform mediump float texelHeight;

    uniform mediump float texelWidthX2;
    uniform mediump float texelHeightX2;

    const int numOfConvolutions = 7;

    uniform int sAMPLES[numOfConvolutions];


    const int sAMPLES0 = 17;
    const int sAMPLES1 = 32;
    const int sAMPLES2 = 30;
    const int sAMPLES3 = 32;
    const int sAMPLES4 = 32;
    const int sAMPLES5 = 32;
    const int sAMPLES6 = 32;


    uniform mediump float convolutionCriteria[numOfConvolutions];

    uniform mediump vec3 pos0Weight[sAMPLES0];
    uniform mediump vec3 pos1Weight[sAMPLES1];
    uniform mediump vec3 pos2Weight[sAMPLES2];
    uniform mediump vec3 pos3Weight[sAMPLES3];
    uniform mediump vec3 pos4Weight[sAMPLES4];
    uniform mediump vec3 pos5Weight[sAMPLES5];
    uniform mediump vec3 pos6Weight[sAMPLES6];


 void main()
 {
    mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);

    mediump vec3 weightStep;

    mediump vec2 currentStep1;
    mediump vec2 currentStep2;

    mediump vec2 sideStepRight;
    mediump vec2 sideStepLeft;
    mediump vec2 bottomStep;
    mediump vec2 topStep;

    mediump float currentColorf;
    mediump float finalColorf1 = 0.0;
    mediump float finalColorf2 = 0.0;

    mediump float totalColor1f = 0.0;
    mediump float totalColor2f = 0.0;


    mediump float rightSideColorBotf;
    mediump float rightSideColorTopf;
    mediump float leftSideColorBotf;
    mediump float leftSideColorTopf;

    mediump float bottomRightSideColorf;
    mediump float topRightSideColorf;
    mediump float bottomLeftSideColorf;
    mediump float topLeftSideColorf;

    mediump vec2 currentCoordinate;


    if (textureColor.r > 0.02)
    {
        for (int j = 0; j < (numOfConvolutions - 1); j++)
        {
            totalColor2f = 0.0;
            totalColor1f = 0.0;
            for (int i = 2; i < sAMPLES[j]; i++)
            {
                     if (j == 0) weightStep = pos0Weight[i];
                else if (j == 1) weightStep = pos1Weight[i];
                else if (j == 2) weightStep = pos2Weight[i];
                else if (j == 3) weightStep = pos3Weight[i];
                else if (j == 4) weightStep = pos4Weight[i];
                else if (j == 5) weightStep = pos5Weight[i];



                sideStepLeft  = vec2(weightStep.x - texelWidthX2,  weightStep.y);
                currentStep1  = vec2(weightStep.x,                 weightStep.y);
                sideStepRight = vec2(weightStep.x + texelWidthX2,  weightStep.y);

                topStep      = vec2(weightStep.y,  -weightStep.x - texelHeightX2);
                currentStep2 = vec2(weightStep.y,  -weightStep.x);
                bottomStep   = vec2(weightStep.y,  -weightStep.x + texelHeightX2);




                //------------ Bottom first arm Side step right ---------------
                currentCoordinate = textureCoordinate.xy + sideStepRight;
                rightSideColorBotf = texture2D(inputImageTexture, currentCoordinate).r * weightStep.z;

                //------------ top half first arm Side step right ---------------
                currentCoordinate = textureCoordinate.xy - sideStepRight;
                rightSideColorTopf = texture2D(inputImageTexture, currentCoordinate).r * weightStep.z;



                //------------ Bottom first arm Side step left ----------

etc.... etc.... etc.....
                //------------ left half second arm ---------------
                currentCoordinate = textureCoordinate.xy - currentStep2;
                currentColorf = texture2D(inputImageTexture, currentCoordinate).r * weightStep.z;

                totalColor2f += currentColorf - (bottomLeftSideColorf + topLeftSideColorf);
            }

                 if (totalColor2f > convolutionCriteria[j]) {finalColorf2 = totalColor2f; break;}
            else if (totalColor1f > convolutionCriteria[j]) {finalColorf1 = totalColor1f; break;}
        }

    if ((finalColorf2 < 0.01) && (finalColorf1 < 0.01))
    {
        for (int j = 1; j < (numOfConvolutions - 1); j++)
        {
            totalColor2f = 0.0;
            totalColor1f = 0.0;

            for (int i = 2; i < sAMPLES[j]; i++)
            {
                     if (j == 1) weightStep = pos1Weight[i];
                else if (j == 2) weightStep = pos2Weight[i];
                else if (j == 3) weightStep = pos3Weight[i];
                else if (j == 4) weightStep = pos4Weight[i];
                else if (j == 5) weightStep = pos5Weight[i];


                sideStepLeft  = vec2(-weightStep.x - texelWidthX2,  weightStep.y);
                currentStep1  = vec2(-weightStep.x,                 weightStep.y);
                sideStepRight = vec2(-weightStep.x + texelWidthX2,  weightStep.y);

                topStep      = vec2(weightStep.y,   weightStep.x - texelHeightX2);
                currentStep2 = vec2(weightStep.y,   weightStep.x);
                bottomStep   = vec2(weightStep.y,   weightStep.x + texelHeightX2);



                //------------ Bottom first arm Side step right ---------------
                currentCoordinate = textureCoordinate.xy + sideStepRight;
                rightSideColorBotf = texture2D(inputImageTexture, currentCoordinate).r * weightStep.z;

                //------------ top half first arm Side step right ---------------
                currentCoordinate = textureCoordinate.xy - sideStepRight;
                rightSideColorTopf = texture2D(inputImageTexture, currentCoordinate).r * weightStep.z;



                //------------ Bottom first arm Side step left ---------------
etc.......etc......etc.....
                //------------ left half second arm ---------------
                currentCoordinate = textureCoordinate.xy - currentStep2;
                currentColorf = texture2D(inputImageTexture, currentCoordinate).r * weightStep.z;

                totalColor2f += currentColorf - (bottomLeftSideColorf + topLeftSideColorf);
            }

                 if (totalColor2f > convolutionCriteria[j]) {finalColorf2 = totalColor2f; break;}
            else if (totalColor1f > convolutionCriteria[j]) {finalColorf1 = totalColor1f; break;}
        }
    }
    }

if (finalColorf2 > 0.01)
{
    gl_FragColor = vec4(textureColor.r * 1.6,0.0,0.0,1.0);
} else if (finalColorf1 > 0.01) {
    gl_FragColor = vec4(0.0,0.0,textureColor.r * 1.6,1.0);
} else {
    gl_FragColor = textureColor;
}

} );

1 个答案:

答案 0 :(得分:1)

好吧我终于确定它是某种类型的硬件限制,例如:GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,但不是这一个,有很多和变化/组合我无法确定哪个,但片段着色器从未失败过在设备上编译,如果超过这个限制,我错误地认为会发生这种情况。

我确定这是问题的方式,就是我在带有视网膜显示器的iPad mini2和iPad mini 1上运行了相同的代码,iPad mini2完成了碎片着色器没有问题,甚至还拍了一张照片比上面的图片大两倍没有问题,代码没有变化,我将不得不限制应用程序在其上运行的硬件看起来像我。