Occlusion mit dem Mega plugin implementieren
Occlusion ist eine Schlüsseltechnologie, um die immersive Integration von virtual und real content in AR zu verbessern. Dieser Artikel führt Sie durch die Implementierung von occlusion Effekten in der xr-frame environment mit EasyAR cloud localization und annotations.
Bevor Sie beginnen
- Sie können Mega Studio in Unity verwenden.
- Sie können annotations mit dem Unity editor erstellen und hochladen.
- Sie können content erstellen, der mit der real world ausgerichtet ist.
Wie occlusion implementiert wird
Offline modeling: Verwenden Sie den Unity editor, um im Block coordinate system 1:1 passende geometry für reale Entitäten wie Wände, Säulen und große Anlagen zu erstellen; oder erstellen Sie ein optimized model durch cropping und face reduction des Block dense model.
Runtime alignment: Zur xr-frame runtime wird das Block coordinate system durch cloud localization mit dem real space ausgerichtet und die entsprechende geometry geladen.
Material replacement: Weisen Sie diesen geometries spezielle occlusion materials zu.
Visual effect: Wenn die GPU andere virtual objects rendert, werden pixels in verdeckten Bereichen automatisch verworfen, weil sie den depth test nicht bestehen. Dadurch folgen virtual objects der occlusion Logik des realen physical space.
Occlusion mit einfacher geometry anordnen
Platzieren Sie box annotations präzise anhand des dense model und der panorama. Nach der Platzierung sieht die annotation wie eine "wall" oder "column" aus.

Ändern Sie den Namen der annotation, z. B.
occlusion_wall, notieren Sie die ID und laden Sie die annotation hoch.Verwenden Sie im xr-frame Mini Program die integrierte geometry, um die als occlusion verwendete annotation zu laden.
Im EMA-Ladecallback verwenden Sie
scene.createElement(xrFrameSystem.XRMesh,{}), um simple geometry zu erstellen und das Materialeasyar-occlusionzuzuweisen.Anmerkung
Laden, registration, deregistration und unloading des Materials
easyar-occlusionwerden von AR Session gesteuert.
```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>
> Mit occlusion kann dieser Panda hinter der Wand tanzen.
Occlusion mit complex geometry anordnen
Dies gilt für Szenarien mit hochpräziser Occlusion, etwa unregelmäßige Geräte oder Gebäude. Sie können die Maskendatei aus Mapping-Ergebnissen verwenden oder das dichte Block-Modell über Mega Studio in Unity exportieren und es dann zuschneiden und reduzieren, um ein weißes Occlusion-Modell zu erhalten.
Maskendatei aus Mapping-Ergebnissen verwenden
Laden Sie die glb-Maskendatei aus dem Mapping-Ergebnis über Mask file download in der Cloud-Localization-Datenbank herunter und schneiden Sie sie zu. Das zugeschnittene Modell muss beim Laden in xr-frame nicht um die Y-Achse gedreht werden.
Anmerkung
Dieser Weg gilt nur für Mapping-Ergebnisse ab Version 9.6.
Nachdem der Block zur Cloud-Localization-Datenbank hinzugefügt wurde, notieren Sie die Block ID und klicken Sie in der Spalte Action auf Mask file download.

Wählen Sie im Popup Low precision und klicken Sie auf Download, um die
glb-Maskendatei herunterzuladen.
Öffnen Sie das heruntergeladene Modell in einer Digital-Content-Software, z. B. Blender.

Schneiden Sie das Modell zu, behalten Sie nur den benötigten Occlusion-Bereich und speichern Sie es als
glb. Position, Rotation, Skalierung und Koordinatensystem bleiben unverändert.
Bereiten Sie die zugeschnittene
glb-Datei vor. Sie können die Datei auf einen HTTPS-hosting server hochladen, der für das Mini Program erreichbar ist, und die URL erhalten, oder die Datei im Verzeichnisminiprogram/assets/des Mini-Program-Projekts ablegen und direkt einen relativen Pfad verwenden. Wenn Sie einen hosting server verwenden, konfigurieren Sie die entsprechende zulässige Download-Domain im Mini-Program-Backend und fügen Sie die Domain der Mini-Program-Whitelist hinzu.Tragen Sie die Modelladresse in der Komponentenressourcenkonfiguration
sampleAssets.occlusionMesh.srcein. Wenn das Modell im Verzeichnisassets/liegt, verwenden Sie einen relativen Pfad, zum Beispiel:src: "assets/occlusion_mesh_sd.glb",Sie können auch eine HTTPS-URL vom hosting server eintragen, zum Beispiel
https://your-domain.example/occlusion.glb.Die Komponente sollte model loading, mounting, Zuweisung des occlusion material und resource release implementieren. Mounten Sie das Modell unter dem erfolgreich lokalisierten Block-Knoten und behalten Sie die ursprünglichen position, rotation und scale des Modells bei.
Nachdem das Modell geladen wurde und localization erfolgreich ist, erstellen Sie einen
XRNodeunter dem ersten Block-Knoten und mounten dann dasXRGLTF-Modell: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; },Nach erfolgreicher localization mounten Sie das Modell unter dem Block-Knoten. Eine manuelle Einstellung der spatial position ist nicht erforderlich.
Diese Methode zeigt direkt das heruntergeladene ursprüngliche white model an und behält die default position, rotation, scale und das visible material des Modells bei. Für resource loading und node mounting siehe 3D content in einer AR scene zur xr-frame runtime laden.
Führen Sie das Mini Program in der realen Szene des Blocks aus, zeigen Sie nach der Localization die Maskendatei an und prüfen Sie Ausrichtung und Occlusion.
Aus Unity exportiertes dichtes Modell verwenden
Klicken Sie in der Unity scene auf den node Mega Block und notieren Sie die BlockID im Inspector panel.

Wählen Sie in Block von Mega Studio export.

Ändern Sie die export options und exportieren Sie.

In der Abbildung ist 1 der LOD level. Je niedriger der level, desto einfacher das model und desto geringer die Anzahl der faces. Wenn höchste precision benötigt wird, wählen Sie 2; wenn geringere precision zur Verringerung des face count akzeptabel ist, wählen Sie 1 oder 0.
In der Abbildung ist 2 die texture export option. Da nur die white model als occlusion benötigt wird, sind textures nicht erforderlich.
Schneiden und reduzieren Sie das exportierte model in digital content creation software, z. B. Blender, und speichern Sie es als
Glb.Tipp
Im Beispiel wird Blender Decimate Modifier verwendet.

Nach cropping und reduction:

Legen Sie die für occlusion verwendete
Glb-Datei im Verzeichnisminiprogram/assets/des Mini-Program-Projekts ab und verwenden Sie einen relativen Pfad, oder stellen Sie sie auf einem zugänglichen HTTPS-Dateiserver bereit und verwenden Sie dessen URL. Wenn Sie eine Server-URL verwenden, konfigurieren Sie die entsprechende zulässige Download-Domain im Mini-Program-Backend und fügen Sie die Domain der Mini-Program-Whitelist hinzu.Laden Sie das als occlusion verwendete GLTF im xr-frame Mini Program.
Zuerst das für occlusion verwendete GLTF model laden, dann mit
scene.createElement(xrFrameSystem.XRGLTF,options)das GLTF model erstellen.Verwenden Sie
assets.getAsset("material", "easyar-occlusion"), um das material object abzurufen.Verwenden Sie
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });}, um das material des GLTF model zu ändern.Anmerkung
Laden, registration, deregistration und unloading des Materials
easyar-occlusionwerden von AR Session gesteuert.
```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" //Hier muss die Block ID eingetragen werden
if (!blockHolder.getBlockById(blockParent.id)) {
// Wenn kein Block-Knoten vorhanden ist, erstellen Sie einen
blockHolder.holdBlock({
id: blockID
})
}
// Block-Knoten in der xr-frame-Szene abrufen
let blockElement = blockHolder.getBlockById(blockParent.id).el;
// Das zugeschnittene Occlusion-Modell als untergeordneten Knoten unter dem Block-Knoten einhängen
blockElement.addChild(model);
/**
* Aufgrund des unterschiedlichen Verhaltens von GLTF-Loadern muss das Modell manchmal so ausgerichtet werden, dass seine Orientierung in xr-frame vollständig mit dem Rendering-Ergebnis in Unity übereinstimmt
* Manchmal muss das geladene Modell lokal um 180 Grad um die Y-Achse gedreht werden
*/
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);
//Hinweis: Das Material muss nach dem Ändern von Transform geändert werden
if (assetInfo.assetId == 'occlusion1') {
//Occlusion-Material abrufen, das vom Mega-Plugin bereitgestellt wird
let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
//Occlusion-Material ändern
model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
m.setData({ neverCull: true, material: occlusionMaterial });
});
}
}
```
> [!NOTE]
> Die Verwendung des Mega Block dense model nach cropping als occlusion erfordert hier keine annotation synchronization der spatial position. Das liegt daran, dass in digital content creation software wie Blender das model reduziert und zugeschnitten werden kann, ohne die coordinate system definition zu ändern.
>
> Wenn Sie ein selbst erstelltes GLTF model als occlusion präzise platzieren müssen, siehe [So platzieren Sie ein mit dem Raum ausgerichtetes occlusion model](./sample.md#wechat-mega-sample-precise-occulusion-model).
Den finalen Effekt auf einem realen Gerät sehen Sie im Video am Anfang dieses Artikels.
Erwarteter occlusion Effekt
Der occlusion Effekt in einem xr-frame Mini Program wird hauptsächlich von folgenden Faktoren beeinflusst:
- Genauigkeit des localization tracking itself
- Genauigkeit der model Platzierung
- Genauigkeit des model selbst, wenn es keine simple geometry ist
Eine Fehlanpassung von mehreren Zentimetern während localization drift ist normal.
Zu viele faces im occlusion model können leicht performance beeinträchtigen. Es wird empfohlen, es nur in notwendigen Bereichen zu verwenden und möglichst simple geometry als occlusion einzusetzen.