如何在不通过序列的情况下在GPUImage中的视频上混合2个LUT的输出?

时间:2018-05-22 18:54:43

标签: ios gpuimage

我一直在努力弄清楚GPUImage是否有我想要做的开箱即用的解决方案。

我有2个LUT和一个视频文件。目前,我能够成功播放视频文件,并使用GPUImageView,GPUImageMovie,GPUImagePicture和GPUImageLookupFilter的组合通过两个LUT过滤它。

这就是我目前正在做的事情,并且效果很好:

    lutPicture1 = [[GPUImagePicture alloc] initWithImage:lutImage1];
    lutPicture2 = [[GPUImagePicture alloc] initWithImage:lutImage2];

    lutFilter1 = [[GPUImageLookupFilter alloc] init];
    lutFilter2 = [[GPUImageLookupFilter alloc] init];

    playerItem =  [[AVPlayerItem alloc] initWithURL:fileURL];
    player = [[AVPlayer alloc] initWithPlayerItem:playerItem];

    GPUImageMovie *gpuImageMovie = [[GPUImageMovie alloc] initWithPlayerItem:playerItem];

    [gpuImageMovie addTarget: lutFilter1];
    [lutPicture1 addTarget: lutFilter1];
    [lutPicture1 processImage];
    [lutFilter1 addTarget: lutFilter2];

    [lutPicture2 addTarget: lutFilter2];
    [lutPicture2 processImage];
    [lutFilter2 addTarget: gpuImageView];

    [gpuImageMovie startProcessing];
    [player play];

如果我错了,请纠正我,但输出将是首先通过名为" lutFilter1"的过滤器的结果,然后通过" lutFilter2&#34传递输出;

但是,我不想按照这样的顺序执行过滤器。

我不知道是否可能,但我希望能够做到以下几点:

  1. 给出"位置"在我的视频
  2. 从" lutImage1"
  3. 获取相应的颜色
  4. 从" lutImage2"
  5. 获取相应的颜色
  6. 混合从" lutImage1"返回的颜色和" lutImage2"
  7. 返回混合颜色作为输出。
  8. 我在框架中看到了一个名为GPUImageSoftEleganceFilter的过滤器,看起来它可能会使用两个LUT做类似的事情,但对于这些东西相对较新我喜欢它,如果有人可以帮助我说出来并告诉我我,如果我尝试做的事情是使用GPUImage可以实现的,如果是这样,也许可以指出我正确的方向:)

    谢谢!

1 个答案:

答案 0 :(得分:1)

好的,我想出了一个类来处理我在 GPUImage 中尝试做的事情 GPUImageThreeInputFilter

我最终创建了一个 GPUImageThreeInputFilter 的子类,并在我的子类中添加了自定义顶点和片段着色器。

如果你有兴趣这样做,这里有一个基本的顶点着色器设置来启动你的工作:

UIFontTextStyle.Title1.GetConstant()

这是一个基本的片段着色器。注意:下面的片段着色器不使用在位置3处渲染的图像纹理,但如果您愿意,可以直接修改它。另请注意"强度"需要设置,你可以硬编码浮动,例如1.0用于演示目的。

attribute vec4 position;
attribute vec4 inputTextureCoordinate;
attribute vec4 inputTextureCoordinate2;
attribute vec4 inputTextureCoordinate3;

varying vec2 textureCoordinate;
varying vec2 textureCoordinate2;
varying vec2 textureCoordinate3;

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
    textureCoordinate2 = inputTextureCoordinate2.xy;
    textureCoordinate3 = inputTextureCoordinate3.xy;
}

我的Objective-C设置将这一切联系起来如下:

varying highp vec2 textureCoordinate;
varying highp vec2 textureCoordinate2;
varying highp vec2 textureCoordinate3;

uniform sampler2D inputImageTexture;
uniform sampler2D inputImageTexture2;
uniform sampler2D inputImageTexture3;

uniform lowp float intensity;

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

    highp float blueColor = textureColor.b * 63.0;

    highp vec2 quad1;
    quad1.y = floor(floor(blueColor) / 8.0);
    quad1.x = floor(blueColor) - (quad1.y * 8.0);

    highp vec2 quad2;
    quad2.y = floor(ceil(blueColor) / 8.0);
    quad2.x = ceil(blueColor) - (quad2.y * 8.0);

    highp vec2 texPos1;
    texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
    texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);

    highp vec2 texPos2;
    texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.r);
    texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * textureColor.g);

    lowp vec4 newColor1 = texture2D(inputImageTexture2, texPos1);
    lowp vec4 newColor2 = texture2D(inputImageTexture2, texPos2);

    lowp vec4 newColor = mix(newColor1, newColor2, fract(blueColor));
    gl_FragColor = mix(textureColor, vec4(newColor.rgb, textureColor.w), intensity);
}

我希望这有助于任何人尝试做同样的事情。