xr-frame WeChat Mini Program で透明動画を再生する
開始する前に
再生する透明動画を準備します。透明動画をファイルサーバーにアップロードし、xr-frame で読み込むための URL を取得します。
透明動画の再生はシーン内のテクスチャ置換に依存するため、透明動画を再生する位置を事前に注釈する必要があります。 Unity Editor を使用して注釈を作成しアップロードできる必要があります。
透明動画とは
透明動画 は、H.264/AVC や H.265/HEVC など、透明チャンネルをネイティブにサポートしない動画エンコード形式で透明背景効果を実現するための技術方案です。
この方式では、動画画面の 色情報(RGB) と 透明度情報(Alpha) を分離し、特定の空間レイアウトに従って同じフレーム画像内に結合することで、白黒マスク付きの通常の動画ファイルを生成します。再生側では、グラフィックスレンダリングパイプラインがリアルタイムにサンプリングし、2 つの部分を合成して、透明背景を持つ動的画面を復元します。
カラー領域と Alpha 領域の結合方式によって、主に 2 つの形式に分かれます。
Side-by-Side (SBS)
Side-by-Side は、RGB カラーフレームと Alpha マスクフレームを 水平方向 に並べて結合する形式です。通常、左側がカラー領域、右側が対応するグレースケール Alpha 領域とされます。
Top-by-Bottom (TBB)
Top-by-Bottom は、RGB カラーフレームと Alpha マスクフレームを 垂直方向 に積み重ねて結合する形式です。通常、上半分がカラー領域、下半分が対応するグレースケール Alpha 領域とされます。
xr-frame Mini Program の注釈位置で透明動画を再生する
まず、タイプが video-texture の動画リソースを読み込みます。
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 が読み込まれた callback 内で scene.createElement(xrFrameSystem.XRMesh,{}) を使用して簡単な geometry を作成し、easyar-video-tsbs material を割り当て、uniform を u_baseColorMap:video-{$assetId} に変更します。
注記
easyar-video-tsbs と easyar-video-ttbb material の読み込み、登録、登録解除、アンロードは 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 という警告が表示された場合は無視してください。
WeChat 公式チームと確認した結果、この警告は使用に影響しません。