GPUImageLightenBlendFilter具有不透明度(GPUImageLightenBlendFilter with opacity)

系统教程 行业动态 更新时间:2024-06-14 17:04:02
GPUImageLightenBlendFilter具有不透明度(GPUImageLightenBlendFilter with opacity)

使用GPUImage我试图用不透明度复制Photoshop Lighten Blend Mode。 不幸的是,alpha通道使用GPUImageLightenBlendFilter没有任何效果。

Brad确认alpha可能存在问题: GPUImage的GPUImageOpacityFilter表现不正常,不会改变alpha通道

我已成功使用CoreImage复制了PS混合,后者尊重alpha值。

CIImage *ciImage1 = [[CIImage alloc] initWithImage:input1]; CIImage *ciImage2 = [[CIImage alloc] initWithImage:input2]; // Alpha adjustment for input1 CIFilter *alphaFilter = [CIFilter filterWithName:@"CIColorMatrix"]; CGFloat rgba[4] = { 0.0, 0.0, 0.0, 0.5 }; CIVector *alphaVector = [CIVector vectorWithValues:rgba count:4]; [alphaFilter setValue:alphaVector forKey:@"inputAVector"]; [alphaFilter setValue:ciImage1 forKey:kCIInputImageKey]; // Lighten blend CIFilter *blendFilter = [CIFilter filterWithName:@"CILightenBlendMode"]; [blendFilter setValue:alphaFilter.outputImage forKey:kCIInputImageKey]; [blendFilter setValue:ciImage2 forKey:kCIInputBackgroundImageKey];

我尝试过2个版本的GPUImage (他们使用不同的方法调整input1 alpha值)。

GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageOpacityFilter *alphaFilter = [GPUImageOpacityFilter new]; alphaFilter.opacity = 0.5; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];

要么:

GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageColorMatrixFilter *alphaFilter = [GPUImageColorMatrixFilter new]; alphaFilter.colorMatrix = (GPUMatrix4x4) { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.5 } }; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];

两个GPUImage实现都返回输出,就像input1 alpha为1.0 。

我在互联网上查看了不同来源的Lighten Blending Mode文档,他们都使用这个公式:

max(blend, base)

在实现GPUImageLightenBlendFilter着色器,它也使用相同的公式:

lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); gl_FragColor = max(textureColor, textureColor2);

但是,似乎Photoshop和CoreImage对alpha有一些额外的操作(可能类似于Gimp: https : //github.com/GNOME/gimp/blob/783bbab8a889d4eba80b6a83f2e529937a73a471/app/operations/gimpoperationlightenonlymode.c )。

任何人都有想法如何在GPUImageLightenBlendFilter公式中包含alpha通道?

Using GPUImage I am trying to replicate Photoshop Lighten Blend Mode with opacity. Unfortunately the alpha channel has no effect using the GPUImageLightenBlendFilter.

Brad confirms there might problems with alpha: GPUImage's GPUImageOpacityFilter not behaving as expected, doesn't change alpha channel

I have successfully replicated the PS blending using CoreImage which respects the alpha value.

CIImage *ciImage1 = [[CIImage alloc] initWithImage:input1]; CIImage *ciImage2 = [[CIImage alloc] initWithImage:input2]; // Alpha adjustment for input1 CIFilter *alphaFilter = [CIFilter filterWithName:@"CIColorMatrix"]; CGFloat rgba[4] = { 0.0, 0.0, 0.0, 0.5 }; CIVector *alphaVector = [CIVector vectorWithValues:rgba count:4]; [alphaFilter setValue:alphaVector forKey:@"inputAVector"]; [alphaFilter setValue:ciImage1 forKey:kCIInputImageKey]; // Lighten blend CIFilter *blendFilter = [CIFilter filterWithName:@"CILightenBlendMode"]; [blendFilter setValue:alphaFilter.outputImage forKey:kCIInputImageKey]; [blendFilter setValue:ciImage2 forKey:kCIInputBackgroundImageKey];

There are 2 versions of GPUImage I have tried (they are adjusting alpha for input1 using a different method).

GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageOpacityFilter *alphaFilter = [GPUImageOpacityFilter new]; alphaFilter.opacity = 0.5; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];

or:

GPUImagePicture *input1 = [[GPUImagePicture alloc] initWithImage:input1]; GPUImagePicture *input2 = [[GPUImagePicture alloc] initWithImage:input2]; // Alpha adjustment for input1 GPUImageColorMatrixFilter *alphaFilter = [GPUImageColorMatrixFilter new]; alphaFilter.colorMatrix = (GPUMatrix4x4) { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 0.5 } }; [input1 addTarget:alphaFilter]; // Lighten blend GPUImageLightenBlendFilter *blendFilter = [GPUImageLightenBlendFilter new]; [alphaFilter addTarget:blendFilter]; [input2 addTarget:blendFilter];

Both GPUImage implementations return output as if alpha for input1 was 1.0.

I have looked at Lighten Blending Mode documentation in different sources on the internet and they all use this formula:

max(blend, base)

Looking at the shader in implementation of GPUImageLightenBlendFilter it also uses the same formula:

lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); gl_FragColor = max(textureColor, textureColor2);

However, it seems that Photoshop and CoreImage have some extra manipulation with the alpha (probably similar to Gimp: https://github.com/GNOME/gimp/blob/783bbab8a889d4eba80b6a83f2e529937a73a471/app/operations/gimpoperationlightenonlymode.c).

Anyone has ideas how to include the alpha channel in the GPUImageLightenBlendFilter formula?

最满意答案

下面是具有不透明度和数量的GPUImageLightenBlendFilter着色器代码。

precision highp float; uniform sampler2D inputImageTexture; uniform sampler2D inputImageTexture2; uniform float alpha; // used for opacity.... uniform float amount; // amount of blend.... varying vec2 textureCoordinate; void main () { // Get samples from both layers vec4 dst = texture2D(inputImageTexture, textureCoordinate); vec4 src = texture2D(inputImageTexture2, textureCoordinate); src.a *= alpha; vec4 colour = vec4(0.0, 0.0, 0.0, 0.0); colour = vec4(max(dst, src).rgb, src.a) * src.a + dst * (1.0 - src.a); colour = clamp(colour, 0.0, 1.0); gl_FragColor.xyz = mix(dst, colour, amount).rgb; gl_FragColor.w = 1.0; }

适合我......

I found this Shader code the best for my case:

lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate); lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2); textureColor.rgb *= textureColor.a; textureColor2.rgb *= textureColor2.a; lowp vec4 textureOut = max(textureColor, textureColor2); textureOut.rgb /= textureOut.a; gl_FragColor = textureOut;

Found here: https://github.com/BradLarson/GPUImage/pull/1297

更多推荐

本文发布于:2023-04-24 20:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/8e040ca5161aead09d8e126c8e3ecbd5.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:明度   不透   GPUImageLightenBlendFilter   opacity

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!