GPUImage创建一个自定义过滤器,用于更改所选颜色

时间:2013-01-15 09:08:39

标签: ios image-processing opengl-es gpuimage


使用惊人的GPU图像框架,我正在尝试使用自定义片段着色器创建自定义过滤器,该着色器将一些颜色向量作为制服传递,详细说明每个片段用制服中的一个替换选择的颜色。我使用Quartz制作它并且它可以工作,但是由于我正在使用这个框架在OpenGL世界中迈出第一步,我想尝试GPU处理。
我制作的片段着色器似乎工作正常,但输出中存在问题。我发布了一个调试porpoise的样本

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;


bool compareVectors (lowp vec3 x,lowp vec3 y){
    bool result;
    if (x.r != y.r) {
        return result = false;
    }
    if (x.b != y.b) {
       return result = false;
    }
    if (x.g  != y.g ) {
       return result = false;
    }
    return result = true;
}

void main()
{
    lowp vec3 tc = vec3(0.0, 0.0, 0.0);

    lowp vec4 pixcol = texture2D(inputImageTexture, textureCoordinate).rgba;
    lowp vec3 sampleColors[3];
    lowp vec3 newColors[3];
    sampleColors[0] = vec3(0.2, 0.2, 0.2);
    sampleColors[1] = vec3(0.0, 0.0, 0.0);
    sampleColors[2] = vec3(1.0, 1.0, 1.0);

    newColors[0] = vec3(0.4, 0.4, 1.0);
    newColors[1] = vec3(0.3, 0.4, 1.0);
    newColors[2] = vec3(0.6, 0.7, 0.5);
    if (pixcol.a >= 0.2) {
        if (compareVectors (sampleColors[0],pixcol.rgb))
            tc = newColors[0];
        else if (compareVectors (sampleColors[1],pixcol.rgb))
            tc = newColors[1];
        else if (compareVectors (sampleColors[2],pixcol.rgb))
            tc = newColors[2];
        else
            tc = pixcol.rgb;
    }
    else
        tc = pixcol.rgb;

    gl_FragColor = vec4(tc.rgb, pixcol.a);
}

生成的图像有很多伪影。它似乎在屏幕上像素化,如果写入磁盘则不能很好地创建。这是一些屏幕 Start Image Filtered Image from screen Filtered Image from disk

第一个图像是起始图像,第二个是iphone屏幕上过滤图像的屏幕截图,第三个是写入磁盘的过滤图像。 深入研究我记得texel和像素不是一回事,所以可能我没有正确映射它们。我想要1:1的比例,可能没有发生。
我怎样才能做到这一点?
谢谢,Andrea

1 个答案:

答案 0 :(得分:5)

如Brad的评论中所述,解决方案是简单地在一系列值中面对纹理颜色。这是由于浮动精度(我现在感觉很愚蠢,很明显)。起始图像具有固定的受控颜色,但由于原始图像被采样,因此信息可能与起始图像不相等。 这是正确的片段着色器:

varying highp vec2 textureCoordinate;
uniform sampler2D inputImageTexture;


bool compareVectors (lowp vec3 sample,lowp vec3 texel){
    bool result;
    if ( abs(texel.r-sample.r) > 0.1 ) {
        return result = false;
    }
    if ( abs(texel.g-sample.g) > 0.1 ) {
        return result = false;
    }
    if ( abs(texel.b-sample.b) > 0.1 ) {
        return result = false;
    }

    return result = true;
}

void main()
{
    lowp vec3 tc = vec3(0.0, 0.0, 0.0);

    lowp vec4 pixcol = texture2D(inputImageTexture, textureCoordinate).rgba;
    lowp vec3 sampleColors[3];
    lowp vec3 newColors[3];
    sampleColors[0] = vec3(0.5, 0.5, 0.5);
    sampleColors[1] = vec3(0.0, 0.0, 0.0);
    sampleColors[2] = vec3(1.0, 1.0, 1.0);

    newColors[0] = vec3(0.4, 0.4, 1.0);
    newColors[1] = vec3(0.3, 0.4, 1.0);
    newColors[2] = vec3(0.6, 0.7, 0.5);

    if (pixcol.a >= 0.2) {
        if (compareVectors (sampleColors[0],pixcol.rgb))
            tc = newColors[0];
        else if (compareVectors (sampleColors[1],pixcol.rgb))
            tc = newColors[1];
        else if (compareVectors (sampleColors[2],pixcol.rgb))
            tc = newColors[2];
        else
            tc = pixcol.rgb;
    }
    else
        tc = pixcol.rgb;

    gl_FragColor = vec4(tc.rgb, pixcol.a);
}

我要感谢Brad找到答案。希望这会有所帮助。