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.Enthält die Maskendatei eines Block mehrere GLB-Dateien, kannst du sie in einer Software zur Erstellung digitaler Inhalte zusammenführen oder einzeln zuschneiden und exportieren. Hänge sie zur Laufzeit alle an denselben Block-Knoten.

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.Trage die Modelladresse in der Ressourcen-Konfiguration der Komponente unter
sampleAssets.occlusionMesh.srcein. Verwende für Modelle inassets/einen relativen Pfad. Für eine einzelne GLB-Datei genügt ein Eintrag; bei mehreren Teilen füge für jeden zu ladenden Teil einen Eintrag mit eigenerassetIdund passendemsrchinzu. Beispiel:const occlusionMeshAssets = [ // Eine GLB-Datei { assetId: "occlusionMesh00", type: "gltf", src: "assets/Low_Poly_occlusion.glb", options: {} }, // Mehrere GLB-Dateien { assetId: "occlusionMesh01", type: "gltf", src: "assets/Low_Poly_occlusion_part1.glb", options: {} }, { assetId: "occlusionMesh02", type: "gltf", src: "assets/Low_Poly_occlusion_part2.glb", options: {} } ];Verwende den tatsächlichen Dateinamen des heruntergeladenen oder zugeschnittenen Modells.
srckann auch eine HTTPS-URL des Hosting-Servers sein, etwahttps://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.
Lade das GLTF-Modell für die Verdeckung im xr-frame-Mini-Programm.
Sobald die Modelle geladen sind und die Lokalisierung mindestens einmal erfolgreich war, erstelle einen gemeinsamen
XRNodeunter dem ersten Block-Knoten. Erstelle für jeden geladenen Teil einXRGLTFund ersetze dessen Mesh-Material durcheasyar-occlusionaus dem Mega-Plugin. Die folgende vollständige Methode verbindet Modell-Anbindung und Materialaustausch und kannshowOcclusionMesh()im Beispiel ersetzen:showOcclusionMesh() { if (!scene) { console.error("Empty scene"); return; } const blockHolder = session?.blockHolder; if (!blockHolder) { console.warn("Empty block holder. Session not initialized."); return; } if (occlusionMeshNode) { return; } const root = blockHolder.blocks[0]?.el; if (!root) { console.warn("Empty block: localization must succeed at least once before showing the occlusion mesh"); return; } const loadedMeshes = occlusionMeshAssets.filter(meshAsset => scene.assets.getAsset('gltf', meshAsset.assetId)); if (loadedMeshes.length === 0) { console.warn("Occlusion mesh asset is not loaded"); return; } const occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion"); if (!occlusionMaterial) { console.warn("Occlusion material is not loaded"); return; } const node = scene.createElement(xrFrameSystem.XRNode); root.addChild(node); for (const meshAsset of loadedMeshes) { const occlusionMesh = scene.createElement(xrFrameSystem.XRGLTF, { model: meshAsset.assetId }); node.addChild(occlusionMesh); // Knoten anhängen und Transform einstellen, bevor das Verdeckungsmaterial ersetzt wird. // Die Maskendatei des Kartierungsergebnisses behält ihre ursprünglichen Koordinaten; eine Drehung um die Y-Achse ist nicht nötig. occlusionMesh.getComponent(xrFrameSystem.GLTF).meshes.forEach((mesh: any) => { mesh.setData({ neverCull: true, material: occlusionMaterial }); }); } node.getComponent(xrFrameSystem.Transform).visible = this.data.occlusionMeshVisible; occlusionMeshNode = node; },Alle Teile nutzen den gemeinsamen übergeordneten Knoten
occlusionMeshNode. Mit dessenTransform.visiblekannst du sie gemeinsam ein- oder ausblenden, ohne ihre Positionen einzeln festzulegen.Anmerkung
AR Session steuert das Laden, Registrieren, Abmelden und Entladen von
easyar-occlusion. Rufe das Material nach dem Start der Session ab und verwende es dann.Starte das Mini-Programm am realen Standort des entsprechenden Block. Warte, bis die Ressourcen geladen sind und die Lokalisierung erfolgreich war, aktiviere Maskendatei und prüfe, ob die verbliebenen Modellteile virtuelle Objekte korrekt verdecken.
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.