簡體   English   中英

在iOS的OpenGL ES着色器中混合多個紋理會導致逆行為

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

我有一個OpenGL ES 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);
} 

如果沒有覆蓋紋理,則向gl_FragColor以下內容:

gl_FragColor = vec4(rgb, 1.0);

工作正常,並且顯示了我的視頻。 現在,我要像這樣從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);

}

問題是結果是倒置的。 因此,它們看起來像這樣:

屏幕截圖
(來源: c.tro.pe

事實是它們以兩種方式倒置。 首先,文字不是Alpha,而是顯示了藍色,而是顯示了Alpha,而這正是視頻顯示的位置。 其次,文本是鏡像的。 鏡像可能是使用頂點值的結果,但是使用相同的坐標視頻是正確的。 我確定這是一個快速的重新安排,但我不確定該如何調整。 謝謝!

對於混合, mix(x, y, a)函數基於a插值xy a為0時,您將得到全部xa為1.0時,您將得到所有y 您要鎖定文本圖層的Alpha,因此對於所需的疊加層,您需要按以下順序反轉順序:

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

關於旋轉,請記住,iOS后置攝像頭是橫向安裝的,而前置攝像頭是橫向安裝的,因此對於縱向,您需要旋轉傳入的視頻幀。 您似乎正在頂點或紋理坐標中執行該旋轉。 您將需要第二組不會旋轉的紋理坐標以用於采樣疊加圖像,或者在生成其紋理時需要以匹配的橫向左旋轉繪制標簽。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM