Table of Contents

Verwendung des mega-plugins zur implementierung von verdeckung

Verdeckung (Occlusion) ist eine Schlüsseltechnologie zur Verbesserung der Immersion bei der Verschmelzung von AR und Realität. Dieser Artikel führt Sie durch die Implementierung von Verdeckungseffekten in der xr-frame-Umgebung mithilfe von EasyAR-Cloud-Positionierung und Annotationen.

Voraussetzungen

Verdeckungsmethoden

  • Offline-Modellierung: Verwenden Sie den Unity-Editor, um im Block-Koordinatensystem geometrische Körper zu erstellen, die 1:1 mit physischen Objekten in der realen Welt (wie Wände, Säulen, große Geräte) übereinstimmen; oder durch Zuschneiden und Polygonreduzierung des dichten Block-Modells ein optimiertes Modell zu erhalten.

  • Laufzeitausrichtung: Zur Laufzeit in xr-frame wird das Block-Koordinatensystem mittels Cloud-Positionierung mit dem realen Raum ausgerichtet und die entsprechenden geometrischen Körper geladen.

  • Materialersatz: Diese geometrischen Körper erhalten ein spezielles Verdeckungsmaterial.

  • Visuelle Effekte: Wenn die GPU andere virtuelle Objekte rendert, werden Pixel in verdeckten Bereichen automatisch aufgrund nicht bestandener Tiefentests entfernt, wodurch virtuelle Objekte der Verdeckungslogik des physischen Raums folgen.

Anordnung einfacher geometrischer verdeckung

  1. Platzieren Sie Würfel-Annotationen präzise entlang des dichten Modells und Panoramabilder. Nach der Platzierung sollte die Annotation wie eine "Wand" oder "Säule" aussehen.

    Annotation als verdeckung

  2. Ändern Sie den Namen der Annotation (z.B. occlusion_wall), notieren Sie die ID und laden Sie die Annotation hoch.

  3. Verwenden Sie in der xr-frame-Miniapp die integrierte Geometrie, um die Annotation als Verdeckung zu laden.

    Verwenden Sie im EMA-Lade-Callback scene.createElement(xrFrameSystem.XRMesh,{}), um einen einfachen geometrischen Körper zu erstellen und ihm das Material easyar-occulusion zuzuweisen.

    Anmerkung

    Das Laden, Registrieren, Deregistrieren und Entladen des Materials easyar-occulusion wird von der AR-Sitzung gesteuert.

handleEmaResult(ema: easyar.ema.v0_5.Ema) {
    let blockHolder: easyar.BlockHolder = session.blockHolder;
    ema.blocks.forEach(emaBlock => {
        const blockInfo: easyar.BlockInfo = {
            id: emaBlock.id
        };
        // Falls der Block-Knoten nicht existiert, Block-Knoten erstellen
        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-Teil
        } else {
            model = scene.createElement(
                xrFrameSystem.XRMesh,
                {
                    // Verwendung des registrierten Okklusionsmaterials des Plugins
                    material: "easyar-occlusion",
                    // Verwendung der integrierten Geometrie von xr-frame, hier kann auch direkt "cube" verwendet werden
                    geometry: geometryStr,
                    name: emaName,
                    "receive-shadow": "false",
                    "cast-shadow": "false"
                    // Skalierung nicht ändern
                }
            );
            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 der Verdeckung kann dieser Panda nun hinter der Wand tanzen.

Anordnung komplexer geometrischer verdeckung

Geeignet für Szenarien mit hoher Präzision wie unregelmäßige Geräte oder Gebäude.

Sie können das dichte Modell eines Blocks zuschneiden und reduzieren, um das benötigte Weißmodell für die Verdeckung zu erhalten.

  1. Klicken Sie in der Unity-Szene auf den Knoten Mega Block und notieren Sie die BlockID im Inspector-Bereich.

    BlockID notieren

  2. Wählen Sie in Mega Studio unter Block den Export.

    Export auswählen

  3. Ändern Sie die Exportoptionen und exportieren Sie.

    Exportoptionen

    Nummer 1 im Bild zeigt die LOD-Stufe. Niedrigere Stufen bedeuten einfachere Modelle mit weniger Polygonen. Für höchste Präzision wählen Sie Stufe 2, für weniger Präzision bei reduzierter Polygonanzahl Stufe 1 oder 0.

    Nummer 2 im Bild ist die Option zum Exportieren von Texturen. Da wir nur ein Weißmodell für die Verdeckung benötigen, sind keine Texturen erforderlich.

  4. Schneiden Sie das exportierte Modell in einer digitalen Inhaltserstellungssoftware (z.B. Blender) zu, reduzieren Sie die Polygonanzahl und speichern Sie es als Glb.

    Tipp

    Das Beispiel verwendet Blenders Decimate-Modifier.

    Vor dem zuschneiden

    Nach dem Zuschneiden und der Polygonreduzierung:

    Nach dem zuschneiden

  5. Hängen Sie die Glb-Datei für die Verdeckung an einen Dateiserver an, um eine ladbare URL zu erhalten.

  6. Laden Sie das GLTF als Verdeckung in der xr-frame-Miniapp.

    Laden Sie zunächst das GLTF-Modell für die Verdeckung. Verwenden Sie dann scene.createElement(xrFrameSystem.XRGLTF,options), um das GLTF-Modell zu erstellen.

    Verwenden Sie assets.getAsset("material", "easyar-occlusion"), um das Materialobjekt zu erhalten.

    Verwenden Sie model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {m.setData({ neverCull: true, material: occlusionMaterial });}, um das Material des GLTF-Modells zu ändern.

    Anmerkung

    Das Laden, Registrieren, Deregistrieren und Entladen des Materials easyar-occulusion wird von der AR-Sitzung gesteuert.

const sampleAssets = {
    occlusion1: {
        assetId: "occlusion1",
        type: "gltf",
        src: "url/occlusion1.glb",
        options: {}
    }
}
async loadAsset() {
    if (!scene) {console.error("Leere Szene"); return;}
    try {
        await scene.assets.loadAsset(sampleAssets.occlusion1);
    } catch (err) {
        console.error(`Fehler beim Laden der 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: "baum"
        }
    );
    const blockID = "aaaa1234-bbbb-cccc-dddd-eeeeee123456" //Hier sollte die Block-ID eingetragen werden
    if (!blockHolder.getBlockById(blockParent.id)) {
        // Falls kein existierender Block-Knoten vorhanden ist, erstelle einen
        blockHolder.holdBlock({
            id: blockID
        })
    }
    // Hole den Block-Knoten aus der xr-frame-Szene
    let blockElement = blockHolder.getBlockById(blockParent.id).el;
    // Füge das zugeschnittene Verdeckungsmodell als untergeordneten Knoten zum Block-Knoten hinzu
    blockElement.addChild(model);
    /**
     * Aufgrund unterschiedlichen Verhaltens von GLTF-Ladern, um sicherzustellen, dass die Ausrichtung des Modells auf xr-frame exakt mit dem Rendering-Ergebnis von Unity übereinstimmt,
    * muss das geladene Modell manchmal 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);
    //Achtung: Material muss nach Änderung des Transform geändert werden
    if (assetInfo.assetId == 'occlusion1') {
        //Hole das Verdeckungsmaterial, bereitgestellt durch das Mega-Plugin
        let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
        //Ändere das Verdeckungsmaterial
        model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
            m.setData({ neverCull: true, material: occlusionMaterial });
        });
    }
}
> [!NOTE]
> Die Verwendung eines zugeschnittenen dichten Mega-Block-Modells für die Verdeckung erfordert keine Annotationen zur Synchronisierung der Position, da in digitalen Inhaltserstellungsprogrammen (wie Blender) die Koordinatendefinition beim Reduzieren und Zuschneiden beibehalten wird.
>
> Für die präzise Platzierung eines selbst erstellten GLTF-Verdeckungsmodells siehe [Anordnung eines raumgenau ausgerichteten verdeckungsmodells](./sample.md#wechat-mega-sample-precise-occulusion-model)

Das finale Ergebnis auf dem Gerät ist im Video am Anfang des Artikels zu sehen.

Erwartetes ergebnis der verdeckung

Die Verdeckungswirkung in der xr-frame-Miniapp wird hauptsächlich durch folgende Faktoren beeinflusst:

  • Die Genauigkeit der Positionsverfolgung selbst
  • Die Genauigkeit der Modellplatzierung
  • Die Präzision des Modells selbst (wenn es kein einfacher geometrischer Körper ist)

Eine Abweichung von einigen Zentimetern bei Positionsdrift ist normal.

Verdeckungsmodelle mit zu vielen Polygonen können die Leistung beeinträchtigen. Es wird empfohlen, sie nur in notwendigen Bereichen zu verwenden und möglichst einfache geometrische Körper für die Verdeckung einzusetzen.

Nächste schritte

Verwandte themen