3


使用令人惊叹的 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);
}

生成的图像有很多伪影。如果写入磁盘,它在屏幕上似乎是像素化的,并且创建得不好。这是一些屏幕。
开始图像 从屏幕过滤的图像 从磁盘过滤的图像

第一张是起始图,第二张是过滤后的法师在iphone屏幕上的截图,第三张是写入磁盘的过滤后的图像。深入研究我记得纹素和像素不是一回事,所以可能我没有正确映射它们。我想要一个 1:1 的位置比率,但可能不会发生。
我怎样才能做到这一点?
谢谢,安德里亚

4

1 回答 1

5

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

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);
}

我要感谢布拉德找到了答案。希望这可以帮助。

于 2013-01-17T07:43:19.030 回答