正如 Hammer 所指出的,我的开源GPUImage框架中的 GPUImageDifferenceBlendFilter 就是这样做的。它使用以下片段着色器来获得红色、绿色和蓝色通道的绝对差异:
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
mediump vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4(abs(textureColor2.rgb - textureColor.rgb), textureColor.a);
}
如果您需要比较连续的视频帧,您还可以使用 GPUImageBuffer 来延迟较旧的帧与当前视频帧一起处理。我在框架内的 FilterShowcase 示例应用程序中有一个示例。
我不太确定“结果想要具有负 RGB 值”是什么意思。当前 iOS 设备上唯一支持纹理支持的帧缓冲区(您的渲染目标)的纹理格式是 32 位 BGRA。这意味着每个颜色通道的范围为 0-255,不允许有负值。不过,您可以将该颜色范围的下半部分用于负值,将上半部分用于正值。
您可以修改我的 GPUImageSubtractBlendFilter 来做到这一点,使用如下片段着色器:
varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
void main()
{
lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);
gl_FragColor = vec4((textureColor.rgb - textureColor2.rgb + 1.0) * 0.5, textureColor.a);
}
然后,在您读出像素后,您需要将 0-255 输出转换为 -128 - 128(或任何您的范围)。