Table of Contents

Menggunakan Mega plugin untuk menerapkan occlusion

Occlusion adalah teknologi utama untuk meningkatkan immersion integrasi virtual dan real content dalam AR. Artikel ini memandu Anda menerapkan efek occlusion di environment xr-frame melalui EasyAR cloud localization dan annotations.

Sebelum mulai

Cara implementasi occlusion

  • Offline modeling: gunakan Unity editor untuk membuat geometry yang cocok 1:1 dalam Block coordinate system untuk entitas real-world seperti wall, column, dan large equipment; atau dapatkan optimized model dengan cropping dan face reduction pada Block dense model.

  • Runtime alignment: saat runtime xr-frame, align Block coordinate system dengan real space melalui cloud localization dan load geometry yang sesuai.

  • Material replacement: berikan occlusion materials khusus pada geometry ini.

  • Visual effect: saat GPU merender virtual object lain, pixel pada bagian yang ter-occlude otomatis di-cull karena tidak lolos depth test, sehingga virtual object mengikuti occlusion logic dari physical space nyata.

Cara menyusun occlusion dengan simple geometry

  1. Letakkan box annotations secara akurat dengan membandingkan dense model dan panorama. Setelah ditempatkan, annotation terlihat seperti "wall" atau "column".

    Annotation as occlusion

  2. Ubah nama annotation, seperti occlusion_wall, catat ID, lalu upload annotation.

  3. Di xr-frame Mini Program, gunakan built-in geometry untuk load annotation yang digunakan sebagai occlusion.

    Dalam callback loading EMA, gunakan scene.createElement(xrFrameSystem.XRMesh,{}) untuk membuat simple geometry dan memberi material easyar-occlusion.

    Catatan

    Loading, registration, deregistration, dan unloading material easyar-occlusion dikontrol oleh AR Session.

```ts
handleEmaResult(ema: easyar.ema.v0_5.Ema) {
    let 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 emaName: string = nodeAnnotation.name;
        const geometryStr: string = nodeAnnotation.geometry === "cube" ? "cube" : "sphere";
        const assetInfo = AnnotationMetaData[nodeAnnotation.id as keyof typeof AnnotationMetaData];
        let model: xrfs.Element;

        if (assetInfo) {
            // GLTF部分
        } else {
            model = scene.createElement(
                xrFrameSystem.XRMesh,
                {
                    // 使用插件注册好的遮挡材质
                    material: "easyar-occlusion",
                    // 使用 xr-frame 内置几何体,此处也可以直接使用 "cube"
                    geometry: geometryStr,
                    name: emaName,
                    "receive-shadow": "false",
                    "cast-shadow": "false"
                    // 注意不要修改 Scale 
                }
            );
            xrNode.addChild(model);
        }
    })
}
```
<video src="https://doc-asset.easyar.com/develop/wechat/mega/media/occlusion03.mp4" style="width:480px; max-width:100%; height:auto;" muted playsinline controls></video>

> Dengan occlusion, panda ini dapat menari di balik wall.

Cara menyusun occlusion dengan complex geometry

Ini berlaku untuk skenario yang memerlukan occlusion presisi tinggi, seperti perangkat berbentuk khusus dan bangunan tidak beraturan. Anda dapat menggunakan file mask dari hasil mapping, atau mengekspor dense model Block melalui Mega Studio di Unity, lalu melakukan crop dan pengurangan face untuk mendapatkan white model occlusion.

Menggunakan file mask dari hasil mapping

Unduh file mask glb dari hasil mapping melalui Mask file download di cloud localization database dan crop sesuai kebutuhan. Model hasil crop tidak perlu diputar pada sumbu Y saat dimuat di xr-frame.

Catatan

Cara unduh ini hanya berlaku untuk hasil mapping versi 9.6 atau yang lebih baru.

  1. Setelah Block ditambahkan ke cloud localization database, catat Block ID yang sesuai, lalu klik Mask file download pada kolom Action di baris Block.

    Entri unduh file mask

  2. Pada popup, pilih Low precision dan klik Download untuk mengunduh file mask berformat glb.

    Unduh file mask

  3. Buka model yang diunduh dalam software pembuatan konten digital, misalnya Blender.

    File mask sebelum crop

    Crop model, sisakan bagian yang diperlukan untuk occlusion, lalu simpan sebagai glb. Pertahankan position, rotation, scale, dan sistem koordinat asli.

    File mask setelah crop

  4. Siapkan file glb yang telah dipotong. Anda dapat mengunggah file tersebut ke server hosting HTTPS yang dapat diakses oleh Mini Program dan mendapatkan URL-nya, atau meletakkan file di direktori miniprogram/assets/ proyek Mini Program dan menggunakan path relatif secara langsung. Saat menggunakan server hosting, konfigurasikan domain unduhan legal yang sesuai di backend Mini Program dan tambahkan domain tersebut ke whitelist Mini Program.

  5. Isi alamat model dalam konfigurasi resource komponen sampleAssets.occlusionMesh.src. Jika model ditempatkan di direktori assets/, gunakan path relatif, misalnya:

    src: "assets/occlusion_mesh_sd.glb",
    

    Anda juga dapat mengisi URL HTTPS dari server hosting, seperti https://your-domain.example/occlusion.glb.

    Komponen harus mengimplementasikan logika loading model, mounting, pemberian material occlusion, dan pelepasan resource. Mount model di bawah node Block yang berhasil dilokalisasi dan pertahankan posisi, rotasi, serta skala asli model.

    Setelah model dimuat dan localization berhasil, buat XRNode di bawah node Block pertama, lalu mount model XRGLTF:

    showOcclusionMesh() {
        if (!scene) { console.error("Empty scene"); return; }
        const blockHolder = session?.blockHolder;
        if (!blockHolder) { console.warn("Session not initialized"); return; }
        if (occlusionMeshNode) { return; }
        const root = blockHolder.blocks[0]?.el;
        if (!root) { console.warn("Localization must succeed before showing the occlusion mesh"); return; }
        if (!scene.assets.getAsset("gltf", sampleAssets.occlusionMesh.assetId)) {
            console.warn("Occlusion mesh asset is not loaded");
            return;
        }
        const node = scene.createElement(xrFrameSystem.XRNode);
        root.addChild(node);
        const model = scene.createElement(xrFrameSystem.XRGLTF, {
            model: sampleAssets.occlusionMesh.assetId
        });
        node.addChild(model);
        node.getComponent(xrFrameSystem.Transform).visible = this.data.occlusionMeshVisible;
        occlusionMeshNode = node;
    },
    

    Setelah localization berhasil, mount model di bawah node Block. Tidak perlu mengatur posisi spasial secara manual.

    Metode ini langsung menampilkan white model asli yang diunduh dan mempertahankan posisi, rotasi, skala, serta material visible bawaan model. Untuk resource loading dan node mounting, lihat Cara memuat konten 3D dalam AR scene pada runtime xr-frame.

  6. Jalankan Mini Program di lokasi nyata Block, tampilkan file mask setelah localization berhasil, dan periksa apakah model cocok dengan scene serta menghalangi objek virtual.

Menggunakan dense model yang diekspor dari Unity

  1. Di Unity scene, klik node Mega Block, lalu catat BlockID di panel Inspector.

    Record BlockID

  2. Pilih export di Block pada Mega Studio.

    Select export

  3. Ubah export options lalu export.

    Export options

    Pada gambar, 1 adalah LOD level. Semakin rendah level, semakin sederhana model dan semakin sedikit face. Pilih 2 jika membutuhkan precision tertinggi, atau pilih 1 atau 0 jika dapat menerima precision yang lebih rendah untuk mengurangi face count.

    Pada gambar, 2 adalah texture export option. Karena kita hanya membutuhkan white model sebagai occlusion, texture tidak diperlukan.

  4. Crop dan reduce model hasil export dalam digital content creation software, seperti Blender, lalu simpan sebagai Glb.

    Kiat

    Contoh menggunakan Blender Decimate Modifier.

    Before cropping

    Setelah cropping dan reduction:

    After cropping

  5. Letakkan file Glb yang digunakan untuk occlusion di direktori miniprogram/assets/ proyek Mini Program dan gunakan path relatif, atau pasang di server file HTTPS yang dapat diakses dan gunakan URL-nya. Saat menggunakan URL server, konfigurasikan domain unduhan legal yang sesuai di backend Mini Program dan tambahkan domain tersebut ke whitelist Mini Program.

  6. Load GLTF yang digunakan sebagai occlusion dalam xr-frame Mini Program.

    Pertama load GLTF model untuk occlusion, lalu gunakan scene.createElement(xrFrameSystem.XRGLTF,options) untuk membuat GLTF model.

    Gunakan assets.getAsset("material", "easyar-occlusion") untuk mendapatkan material object.

    Gunakan model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });} untuk mengubah material GLTF model.

    Catatan

    Loading, registration, deregistration, dan unloading material easyar-occlusion dikontrol oleh AR Session.

```ts
const sampleAssets = {
    occlusion1: {
        assetId: "occlusion1",
        type: "gltf",
        src: "url/occlusion1.glb",
        options: {}
    }
}
async loadAsset() {
    if (!scene) {console.error("Empty scene"); return;}
    try {
        await scene.assets.loadAsset(sampleAssets.occlusion1);
    } catch (err) {
        console.error(`Failed to load assets: ${err.message}`);
    }
},
addOcclusion() {
    model = scene.createElement(
        xrFrameSystem.XRGLTF,
        {
            "model": assetInfo.assetId,
            "anim-autoplay": assetInfo.animation ? assetInfo.animation : "",
            "scale": assetInfo.scale ? assetInfo.scale : "1 1 1",
            name: "tree"
        }
    );
    const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456" //Isi Block ID di sini
    if (!blockHolder.getBlockById(blockParent.id)) {
        // Jika node Block belum ada, buat satu
        blockHolder.holdBlock({
            id: blockID
        })
    }
    // Mendapatkan node Block di scene xr-frame
    let blockElement = blockHolder.getBlockById(blockParent.id).el;
    // Pasang model occlusion yang telah dipotong di bawah node Block sebagai child node
    blockElement.addChild(model);
    /**
     * Karena perilaku loader GLTF berbeda-beda, agar orientasi model di xr-frame benar-benar konsisten dengan hasil rendering Unity
    * Terkadang model yang dimuat perlu diputar 180 derajat di tempat pada sumbu Y
    */
    let modelTransform = model.getComponent(xrFrameSystem.Transform);
    let currentRotation = modelTransform.quaternion.clone();
    let targetRotation = currentRotation.multiply(new xrFrameSystem.Quaternion().setValue(0, 1, 0, 0));
    modelTransform.quaternion.set(targetRotation);
    //Perhatikan: material harus diubah setelah Transform dimodifikasi
    if (assetInfo.assetId == 'occlusion1') {
        //Mendapatkan material occlusion yang disediakan plugin Mega
        let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
        //Memodifikasi material occlusion
        model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
            m.setData({ neverCull: true, material: occlusionMaterial });
        });
    }
}
```
> [!NOTE]
> Di sini, menggunakan Mega Block dense model setelah cropping sebagai occlusion tidak memerlukan annotation synchronization untuk spatial position. Ini karena dalam digital content creation software, seperti Blender, model dapat direduce dan dicrop tanpa mengubah coordinate system definition.
>
> Jika Anda perlu menempatkan GLTF model occlusion buatan sendiri secara presisi, lihat [Cara menempatkan occlusion model yang align dengan space](./sample.md#wechat-mega-sample-precise-occulusion-model).

Final real-device running effect dapat dilihat pada video di bagian atas artikel.

Expected occlusion effect

Efek occlusion pada xr-frame Mini Program terutama dipengaruhi oleh hal berikut:

  • Accuracy localization tracking itu sendiri
  • Accuracy penempatan model
  • Accuracy model itu sendiri, jika bukan simple geometry

Ketika terjadi localization drift, misalignment beberapa sentimeter adalah normal.

Face count model occlusion yang terlalu banyak mudah memengaruhi performance. Disarankan hanya menggunakannya di area yang diperlukan dan sebisa mungkin menggunakan simple geometry sebagai occlusion.

Langkah berikutnya

Topik terkait