简体   繁体   English

在iOS的OpenGL ES着色器中混合多个纹理会导致逆行为

[英]Mixing Multiple Textures in OpenGL ES Shader on iOS Results in Inverse Behavior

I have an OpenGL ES Shader fragment shader that is using the mix function to place an overlay over a videoframe. 我有一个OpenGL ES Shader片段着色器,它使用混合功能在视频帧上放置覆盖。 This is my shader: 这是我的着色器:

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 textureCoordinate;

uniform sampler2D videoFrameY; 
uniform sampler2D videoFrameUV;
uniform sampler2D overlay;

const mat3 yuv2rgb = mat3(
                          1,        1,          1,
                          0,        -.21482,    2.12798,
                          1.28033,  -.38059,    0
                          );

void main() {

    vec3 yuv;
    vec4 ovr;

    yuv.x = texture2D(videoFrameY, textureCoordinate).r;
    yuv.yz = texture2D(videoFrameUV, textureCoordinate).rg - vec2(0.5, 0.5);
    ovr = texture2D(overlay, textureCoordinate);

    vec3 rgb = yuv2rgb * yuv;

    gl_FragColor = mix(ovr, vec4(rgb, 1.0), ovr.a);
} 

Without the overlay texture, feeding gl_FragColor this: 如果没有覆盖纹理,则向gl_FragColor以下内容:

gl_FragColor = vec4(rgb, 1.0);

works just fine and my video is displayed. 工作正常,并且显示了我的视频。 Now I'm creating my overlay texture from a CATextLayer like this: 现在,我要像这样从CATextLayer创建覆盖纹理:

- (void)generateOverlay {
    CATextLayer *textLayer = [CATextLayer layer];
    [textLayer setString:@"Sample test string"];
    [textLayer setFont:(__bridge CFStringRef)@"Helvetica"];
    [textLayer setFontSize:(_videoHeight / 6)];
    [textLayer setAlignmentMode:kCAAlignmentLeft];
    [textLayer setBounds:CGRectMake(0, 0, _videoWidth, _videoHeight)];

    CGSize layerSize = textLayer.bounds.size;
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    void *imageData = malloc(layerSize.height * layerSize.width * 4);
    CGContextRef context = CGBitmapContextCreate(imageData, layerSize.width, layerSize.height, 8, 4 * layerSize.width, colorspace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorspace);
    CGContextClearRect(context, CGRectMake(0, 0, layerSize.width, layerSize.height));
    CGContextTranslateCTM(context, 0, layerSize.height - layerSize.height);
    [textLayer renderInContext:context];

    glActiveTexture(GL_TEXTURE2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layerSize.width, layerSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

    CGContextRelease(context);
    free(imageData);

}

The problem is the results are inverted. 问题是结果是倒置的。 So therefore they look like this: 因此,它们看起来像这样:

屏幕截图
(source: c.tro.pe ) (来源: c.tro.pe

The fact is they are are inverted in two ways. 事实是它们以两种方式倒置。 First, instead of the blue being alpha'ed out and the video showing through, the text is the alpha and that is where the video is showing through. 首先,文字不是Alpha,而是显示了蓝色,而是显示了Alpha,而这正是视频显示的位置。 Second, the text is mirrored. 其次,文本是镜像的。 The mirroring could be the results of the vertex values being used however the video is correct using the same coords. 镜像可能是使用顶点值的结果,但是使用相同的坐标视频是正确的。 I'm sure this is a quick rearrange but I'm not sure what to tweak. 我确定这是一个快速的重新安排,但我不确定该如何调整。 Thanks! 谢谢!

For the mix, the mix(x, y, a) function interpolates between x and y based on a . 对于混合, mix(x, y, a)函数基于a插值xy a of 0 gives you all x , and a of 1.0 gives you all y . a为0时,您将得到全部xa为1.0时,您将得到所有y You're keying off of the alpha of your text layer, so for the overlay you want, you need to reverse your ordering as follows: 您要锁定文本图层的Alpha,因此对于所需的叠加层,您需要按以下顺序反转顺序:

gl_FragColor = mix(vec4(rgb, 1.0), ovr, ovr.a);

In regards to the rotation, remember that the iOS rear cameras are mounted landscape left and the front cameras landscape right, so for a portrait orientation you need to rotate the incoming video frames. 关于旋转,请记住,iOS后置摄像头是横向安装的,而前置摄像头是横向安装的,因此对于纵向,您需要旋转传入的视频帧。 You appear to be performing that rotation in either your vertices or texture coordinates. 您似乎正在顶点或纹理坐标中执行该旋转。 You're going to need a second set of texture coordinates that aren't rotated to use for sampling your overlay image, or you'll need to draw your label at a matching landscape left rotation when generating its texture. 您将需要第二组不会旋转的纹理坐标以用于采样叠加图像,或者在生成其纹理时需要以匹配的横向左旋转绘制标签。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM