1

mix関数を使用してビデオフレームにオーバーレイを配置するOpenGL ESシェーダーフラグメントシェーダーがあります。これは私のシェーダーです:

#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 )

実際には、それらは 2 つの点で逆になっています。まず、青がアルファ化されて動画が透けて見えるのではなく、テキストがアルファになり、そこから動画が透けて見えます。次に、テキストがミラーリングされます。ミラーリングは、使用されている頂点値の結果である可能性がありますが、ビデオは同じ座標を使用して正しいです。これは簡単な再配置だと確信していますが、何を調整すればよいかわかりません。ありがとう!

4

1 に答える 1

1

ミックスの場合、関数は に基づいてと の間をmix(x, y, a)補間します。of 0 はすべてを提供し、of 1.0 はすべてを提供します。テキストレイヤーのアルファをキーオフしているため、必要なオーバーレイについては、次のように順序を逆にする必要があります。xyaaxay

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

回転に関しては、iOS の背面カメラは左に横向きに、前面カメラは右に横向きに取り付けられていることに注意してください。縦向きの場合は、着信ビデオ フレームを回転させる必要があります。頂点またはテクスチャ座標でその回転を実行しているようです。オーバーレイ画像のサンプリングに使用する回転されていないテクスチャ座標の 2 番目のセットが必要になるか、テクスチャを生成するときに、一致するランドスケープの左回転でラベルを描画する必要があります。

于 2012-06-06T16:23:50.920 に答える