2017-07-02 14 views
0

Dies ist wahrscheinlich eine dumme Frage, aber ich bin für eine Weile mit dieser Sache fest, so werde es sowieso fragen.Implementieren benutzerdefinierter Filter mit GPUImage Swift-Bibliothek

Ich versuche, einen Hudson/Nashville Filter auf einem Haustier Projekt zu implementieren. Ich habe ein wenig gegoogelt und ein paar Open-Source-Projekte ausprobiert und einige Objective-C (die ich nicht verstehe) Projekte gefunden. Sie haben die Filter implementiert mit GPUImage2, aber ich war mir nicht sicher über ihren Ansatz.

Ich habe das Overlay und andere Bilder, die sie verwendet haben und die GLSL Dateien.

Also meine Frage ist, wie gehe ich über die Verwendung dieser Bilder und Shader-Dateien, um einen benutzerdefinierten Filter zu implementieren?

Hinweis: Ich habe versucht, mit der LookupFilter Ansatz wie vorgeschlagen, aber das Ergebnis war nicht so gut. Es wäre super hilfreich, wenn Sie mir Code zeigen könnten. Dank

Update:

Was ich dies zu verstehen versuchen. Wenn ich einen benutzerdefinierten Shader wie den folgenden verwende, wie soll ich die Eingabebilder für uniform inputImageTexture2, inputImageTexture3 & inputImageTexture4 übergeben. Übergebe ich es als PictureInput an BasicOperation durch Unterklasse? Wenn das so ist, wie? Was vermisse ich? Ich war nicht in der Lage, den Code wegen des Fehlens einer ordnungsgemäßen Dokumentation viel durchzulaufen. Ich habe jetzt über Shader und seine verschiedenen Komponenten gelesen, bin aber immer noch nicht in der Lage, einen Weg zu finden, mit benutzerdefinierten Filtern auf GPUImage2 zu arbeiten. Bitte helfen Sie.

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

Antwort

3

GPUImage Die Konvention ist, dass der erste Eingang an einen Textur-Shader inputTextureCoordinate aufgerufen wird, die zweite inputTextureCoordinate2, und so weiter. In der ursprünglichen Objective-C-Version von GPUImage können Sie einen Filtertyp manuell ableiten, der mit der Anzahl der Eingabetexturen in Ihrem Shader übereinstimmt.

In der Swift GPUImage 2 habe ich es so gemacht, dass Sie nur eine BasicOperation-Klasse oder Unterklasse verwenden müssen, und es fügt Texturen automatisch an die Anzahl der für Ihren Shader benötigten Eingaben an. Sie tun dies, indem Sie eine BasicOperation Initialisierung und Einstellung der Anzahl der Eingänge:

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

Die obigen Sätze numberOfInputs-4, Ihr oben Shader entsprechen. Wenn Sie das Argument vertexShaderFile als nil (Standard) belassen, wählt die BasicOperation einen geeigneten einfachen Vertex-Shader mit vier Textureingaben aus.

Alles, was Sie dann tun müssen, ist Ihre Eingaben für diesen Filter wie bei jedem anderen, indem Sie Ihre neue BasicOperation als Ziel einer Bildquelle hinzufügen. Die Reihenfolge, in der Sie die Eingaben anhängen, ist von Bedeutung, da diese mit der ersten Textur in Ihrem Shader beginnt und weiter nach unten geht.

In den meisten Fällen ist BasicOperation flexibel genug, so dass Sie keine Unterklasse benötigen. Möglicherweise müssen Sie möglicherweise einen benutzerdefinierten Vertex-Shader bereitstellen, der jedoch für den obigen Fragment-Shader-Code nicht benötigt wird.

Verwandte Themen