Table of Contents

xr-frame WeChat Mini Program에서 transparent video 재생

시작하기 전에

  • 재생할 transparent video를 준비합니다. Transparent video를 file server에 upload하고 xr-frame에서 load하는 데 사용할 URL을 얻습니다.

  • Transparent video playback은 scene의 texture replacement에 의존하므로, transparent video를 재생할 위치를 사전에 annotation해야 합니다. Unity Editor를 사용해 annotation을 생성하고 upload할 수 있어야 합니다.

Transparent video란

Transparent video는 H.264/AVC, H.265/HEVC처럼 alpha channel을 native로 지원하지 않는 video encoding format에서 transparent background 효과를 구현하기 위한 기술적 방안입니다.

이 방안은 video image의 color information (RGB)transparency information (Alpha) 를 분리하고, 특정 spatial layout에 따라 같은 frame image에 이어 붙여 black-and-white mask가 포함된 일반 video file을 생성합니다. Playback 측에서는 graphics rendering pipeline이 real time으로 sampling하고 두 부분을 합성하여 transparent background를 가진 dynamic image를 복원합니다.

Color area와 Alpha area의 결합 방식에 따라 주로 두 가지 format으로 나뉩니다.

  1. Side-by-Side (SBS)

    Side-by-Side는 RGB color frame과 Alpha mask frame을 horizontal direction으로 나란히 결합하는 format입니다. 일반적으로 왼쪽은 color area, 오른쪽은 해당 grayscale Alpha area로 약속합니다.

  2. Top-by-Bottom (TBB)

    Top-by-Bottom은 RGB color frame과 Alpha mask frame을 vertical direction으로 쌓아 결합하는 format입니다. 일반적으로 위쪽 절반은 color area, 아래쪽 절반은 해당 grayscale Alpha area로 약속합니다.

xr-frame Mini Program에서 annotation 위치에 transparent video 재생

먼저 video-texture type의 video resource를 load합니다.

async loadAsset() {
    const videoTexture = {
        assetId: "fireball",
        type: "video-texture",
        // 비디오 리소스 URL
        src: "url/video-resource.mp4",
        options: {
            autoPlay: true,
            loop: true,
        }
    };
    try {
        // video-texture 타입 리소스 로드
        await scene.assets.loadAsset(videoTexture);
    } catch (err) {
        console.error(`Failed to load video texture: ${err.message}`);
    }
}

EMA가 load된 callback에서 scene.createElement(xrFrameSystem.XRMesh,{})를 사용해 simple geometry를 만들고, easyar-video-tsbs material을 부여한 뒤 uniformu_baseColorMap:video-{$assetId}로 수정합니다.

참고

easyar-video-tsbseasyar-video-ttbb material의 loading, registration, deregistration, unloading은 AR Session이 제어합니다.

handleEmaResult(ema: easyar.ema.v0_5.Ema) {
    const blockHolder: easyar.BlockHolder = session.blockHolder;
    ema.blocks.forEach(emaBlock => {
        const blockInfo: easyar.BlockInfo = {
            id: emaBlock.id
        };
        // Block 노드가 없으면 Block 노드 생성
        blockHolder.holdBlock(blockInfo, easyarPlugin.toXRFrame(emaBlock.transform));
    });
    ema.annotations.forEach(annotation => {
        if (annotation.type !== mega.EmaV05AnnotationType.Node) {
            return;
        }
        const nodeAnnotation = annotation as easyar.ema.v0_5.Node;
        const xrNode: xrfs.XRNode = easyarPlugin.createXRNodeFromNodeAnnotation(nodeAnnotation, blockHolder);
        const assetInfo = AnnotationMetaData[nodeAnnotation.id as keyof typeof AnnotationMetaData];
        let model: xrfs.Element;

        if (assetInfo) {
            // GLTF 부분
        } else {
            // 내장 Mesh를 사용해 렌더링용 지오메트리 생성
            model = scene.createElement(xrFrameSystem.XRMesh, {
                geometry: "cube",
                material: "easyar-video-tsbs",
                uniforms: "u_baseColorMap:video-fireball",
            });
            xrNode.addChild(model);
        }
    });
}
참고

video-texture 사용 시 console에 wx.createVideoDecoder with type: 'wemedia' is deprecated warning이 나타나면 무시하십시오.

WeChat official team과 확인한 결과, 이 warning은 사용에 영향을 주지 않습니다.

후속 단계

관련 항목