使用 GPUImage Swift 库实现自定义过滤器

Implementing custom filters using GPUImage Swift library

这可能是个愚蠢的问题,但我被这个问题困扰了一段时间所以还是要问一下。

我正在尝试对一个宠物项目实施 Hudson/Nashville 过滤器。我在 google 上搜索了一下,查看了一些开源项目,发现了一些基于 Objective-C(我不明白)的项目。他们确实使用 GPUImage2 实现了过滤器,但我不确定他们的方法。

我有他们使用的覆盖图和其他图像以及 GLSL 文件。

所以我的问题是如何使用这些图像和着色器文件来实现自定义滤镜?

注意:我尝试按照建议使用 LookupFilter 方法,但结果不是很好。如果您能给我一些代码,那将非常有帮助。谢谢

更新:

我想了解这个。给定如下所示的自定义着色器,我应该如何传递 uniform inputImageTexture2inputImageTexture3inputImageTexture4 的输入图像。我是否通过子类化将其作为 PictureInput 传递给 BasicOperation?如果是这样,如何?我错过了什么?由于缺少适当的文档,我无法深入了解代码。我现在已经阅读了有关着色器及其不同组件的内容,但仍然无法找到在 GPUImage2 上使用自定义滤镜的方法。请帮忙。

precision highp float;

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2; //blowout;
uniform sampler2D inputImageTexture3; //overlay;
uniform sampler2D inputImageTexture4; //map

uniform float strength;

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

    vec4 texel = texture2D(inputImageTexture, textureCoordinate);

    vec3 bbTexel = texture2D(inputImageTexture2, textureCoordinate).rgb;

    texel.r = texture2D(inputImageTexture3, vec2(bbTexel.r, texel.r)).r;
    texel.g = texture2D(inputImageTexture3, vec2(bbTexel.g, texel.g)).g;
    texel.b = texture2D(inputImageTexture3, vec2(bbTexel.b, texel.b)).b;

    vec4 mapped;
    mapped.r = texture2D(inputImageTexture4, vec2(texel.r, .16666)).r;
    mapped.g = texture2D(inputImageTexture4, vec2(texel.g, .5)).g;
    mapped.b = texture2D(inputImageTexture4, vec2(texel.b, .83333)).b;
    mapped.a = 1.0;

    mapped.rgb = mix(originColor.rgb, mapped.rgb, strength);

    gl_FragColor = mapped;
}

GPUImage 惯例是着色器的第一个输入纹理称为 inputTextureCoordinate,第二个称为 inputTextureCoordinate2,依此类推。在 GPUImage 的原始 Objective-C 版本中,您可以手动子 class 与着色器中的输入纹理数量相匹配的滤镜类型。

在 Swift GPUImage 2 中,我做了这样你只需要使用 BasicOperation class 或 subclass,它会自动将纹理附加到数字着色器所需的输入。您可以通过初始化 BasicOperation 并设置输入数来执行此操作:

let myOperation = BasicOperation(fragmentShaderFile:myFragmentShader, numberOfInputs:4)

以上将 numberOfInputs 设置为 4,与您上面的着色器相匹配。通过将 vertexShaderFile 参数保留为 nil(默认值),BasicOperation 将选择一个具有四个纹理输入的适当的简单顶点着色器。

然后您需要做的就是将您的输入设置为该过滤器,就像您设置任何其他过滤器一样,方法是将新的 BasicOperation 添加为图像源的目标。附加输入的顺序很重要,因为它将从着色器中的第一个纹理开始,然后向下推进。

在大多数情况下,BasicOperation 本身就足够灵活,因此您不需要子class。至多,您可能需要提供一个自定义顶点着色器,但上面的片段着色器代码不需要。