你真的应该尝试使用自定义着色器。它非常容易上手,如果你投入足够的精力,就能很快地变得强大。
话虽如此,我认为你是想要达到以下结果:
![Edge Detection on a pile of Lego's](https://istack.dev59.com/OQN1U.webp)
有很多可行的方法可以实现这一点,但编写一个GPUImageTwoInputFilter子类的自定义着色器,并将其定位于原始图像和边缘检测图像,是我实现这个图片的方法。
这个子类看起来应该像这样:
#import "OriginalColorEdgeMixer.h"
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
NSString *const kOriginalColorEdgeMixer = SHADER_STRING
(
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
lowp float threshold;
mediump float resultingRed;
mediump float resultingGreen;
mediump float resultingBlue;
void main()
{
mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
threshold = step(0.3, textureColor2.r);
resultingRed = threshold * textureColor.r;
resultingGreen = threshold * textureColor.g;
resultingBlue = threshold *textureColor.b;
gl_FragColor = vec4(resultingRed, resultingGreen, resultingBlue, textureColor.a);
}
);
#else
NSString *const kGPUImageDifferenceBlendFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
float threshold;
float resultingRed;
float resultingGreen;
float resultingBlue;
void main()
{
vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
threshold = step(0.3,textureColor2.r);
resultingRed = threshold * textureColor.r;
resultingGreen = threshold * textureColor.g;
resultingBlue = threshold *textureColor.b;
gl_FragColor = vec4(resultingRed, resultingGreen, resultingBlue, textureColor.a);
}
);
#endif
@implementation OriginalColorEdgeMixer
- (id)init;
{
if (!(self = [super initWithFragmentShaderFromString:kOriginalColorEdgeMixer]))
{
return nil;
}
return self;
}
@end
在我写作的时候,我们期望边缘检测滤镜的输出是这个自定义滤镜的第二个输入。
我任意选择了一个阈值为0.3的数值来控制边缘检测图像上的强度,以便原始颜色可以显示出来。通过将它与从应用程序的 UISlider 获取到的 GLint 相关联(Brad 的示例代码中有很多这样的例子),这很容易实现动态调整。
为了让那些刚开始使用 GPUImage 的人更加清晰易懂,使用你编写的自定义滤镜非常容易。我像这样做:
[self configureCamera];
edgeDetection = [[GPUImageSobelEdgeDetectionFilter alloc] init];
edgeMixer = [[OriginalColorEdgeMixer alloc] init];
[camera addTarget:edgeDetection];
[camera addTarget:edgeMixer];
[edgeDetection addTarget:edgeMixer];
[edgeMixer addTarget:_previewLayer];
[camera startCameraCapture];
总之,不要害怕开始编写自定义着色器!学习曲线很短,调试器抛出的错误非常有帮助,可以让您准确地知道语法出了什么问题。最后,
这是一个关于OpenGL特定函数的语法和用法的文档资源。