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
- Dapat menggunakan Mega Studio di Unity.
- Dapat membuat dan meng-upload annotations dengan Unity editor.
- Dapat membuat content yang align dengan real world.
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
Letakkan box annotations secara akurat dengan membandingkan dense model dan panorama. Setelah ditempatkan, annotation terlihat seperti "wall" atau "column".

Ubah nama annotation, seperti
occlusion_wall, catat ID, lalu upload annotation.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 materialeasyar-occlusion.Catatan
Loading, registration, deregistration, dan unloading material
easyar-occlusiondikontrol 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.
Setelah Block ditambahkan ke cloud localization database, catat Block ID yang sesuai, lalu klik Mask file download pada kolom Action di baris Block.

Pada popup, pilih Low precision dan klik Download untuk mengunduh file mask berformat
glb.
Buka model yang diunduh dalam software pembuatan konten digital, misalnya Blender.

Crop model, sisakan bagian yang diperlukan untuk occlusion, lalu simpan sebagai
glb. Pertahankan position, rotation, scale, dan sistem koordinat asli.
Siapkan file
glbyang 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 direktoriminiprogram/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.Isi alamat model dalam konfigurasi resource komponen
sampleAssets.occlusionMesh.src. Jika model ditempatkan di direktoriassets/, 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
XRNodedi bawah node Block pertama, lalu mount modelXRGLTF: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.
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
Di Unity scene, klik node Mega Block, lalu catat BlockID di panel Inspector.

Pilih export di Block pada Mega Studio.

Ubah export options lalu export.

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.
Crop dan reduce model hasil export dalam digital content creation software, seperti Blender, lalu simpan sebagai
Glb.Kiat
Contoh menggunakan Blender Decimate Modifier.

Setelah cropping dan reduction:

Letakkan file
Glbyang digunakan untuk occlusion di direktoriminiprogram/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.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-occlusiondikontrol 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.