Table of Contents

如何在 XRFame 小程序运行时修改 AR 場景下的 3D 內容

本文提供了 AR 追蹤下的顯隱策略控制、執行時 Transform 變換以及 GLTF 材質動態更新的實踐指南。

開始之前

如何配置執行時 Block 的可見性控制策略

BlockController 元件的可見性控制策略 visibleStrategy 一共有三種:

策略 說明
VisibleWhileTracked 預設值。僅當 Block 被成功跟蹤時顯示,遺失追蹤則隱藏。
VisibleAfterFirstTracked 只要 Block 被成功跟蹤過一次,之後即便遺失追蹤也保持顯示。
None 不由引擎控制顯隱,由開發者自行維護。

BlockHolder 呼叫 holdBlock() 在 ShadowRoot 下建立 Block 節點之後可以修改其可見性策略。

如何查到 BlockID 可以參考不使用標註直接掛載內容

const blockInfo: easyar.BlockInfo = { id: blockId };
blockHolder.holdBlock(blockInfo);
const block = blockHolder.getBlockById(blockInfo.id);

// 修改策略為:一旦跟蹤到就永久顯示
block.visibleStrategy = BlockVisibleStrategy.VisibleAfterFirstTracked;

預設的 VisibleStrategy 是 VisibleWhileTracked 也就是說當且僅當 Block 處於 MegaTracker 追蹤下,其內容(包括子節點的)顯示。

內容編輯和修改方法

  • 修改物體的 Transform

    對於場景中的 Element 需要呼叫其 getComponent() 方法以取得相應的 Component 才能修改。

    const xrFrameSystem = wx.getXrFrameSystem();
    let transform = model.getComponent(xrFrameSystem.Transform);
    transform.position.setValue(1.0, 0.0, -1.0);
    /** 拷貝原本的四元數 */
    let originalQuaternion = modelTF.quaternion.clone();
    /** 繞Y旋轉 180 度 */
    let targetQuaternion = originalQuaternion.multiply(new xrFrameSystem.Quaternion().setValue(0, 1, 0, 0));
    transform.quaternion.setValue(targetQuaternion);
    

    這個例子中,程式獲取了 modelxrFrameSystem.Transform,然後對齊位置和旋轉角度進行了修改

  • 替換貼圖

    替換貼圖前需要對貼圖資源本身透過使用 xr-frame 場景的資源管理系統呼叫 loadAsset 手動加載。

    之後取得模型的 GLTF 屬性,對其每個 meshmaterial 呼叫 setTexture() 方法。

    const textureAsset = await scene.assets.loadAsset({
        type: 'texture',
        assetId: `texture01`,
        src: 'some-texture-url.png',
    });
    model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
        m.material.setTexture('u_baseColorMap', textureAsset.value);
    });
    

    這個例子中,程式先使用場景的資源管理器加載了一個 textureAsset,然後用其替換了 GLTF 模型的貼圖。

  • 替換已註冊材質

    替換已註冊材質需要先使用 xr-frame 場景的資源管理系統呼叫 getAsset() 取得材質資源。

    之後取得模型的 GLTF 屬性,對其每個 mesh 呼叫 setDatamaterial 屬性修改為目標材質。

    let occlusionMaterial = scene.assets.getAsset("material", "easyar-occlusion");
    model.getComponent(xrFrameSystem.GLTF).meshes.forEach((m: any) => {
        m.setData({ material: occlusionMaterial });
    });
    

    這個例子中,程式先使用場景的資源管理器加載了 EasyAR 註冊的遮擋材質 easyar-occlusion,然後被設置為 GLTF 模型的材質。