共用方式為


教學:用 WebXR 用 Babylon.js 組裝鋼琴

在現實世界中製作鋼琴需要大量時間、技巧和材料。 那為 VR/AR 世界打造一個呢?

在這個教學系列中,你將學習如何利用 Babylon.js 創建一個Mixed Reality的網頁應用程式,裡面有一台在虛擬世界中運作的88鍵立式鋼琴。 在完成的應用程式中,你可以瞬間移動到鋼琴前,並利用混合實境控制器彈奏琴鍵。

在這個教學系列中,你將學習如何:

  • 建立、定位並合併網格來打造鋼琴鍵盤
  • 匯入一個 Babylon.js 型的立式鋼琴框架
  • 為每個鋼琴鍵新增指標互動
  • 啟用 WebXR 中的傳送與多點指標支援

必要條件

快速入門

我們先從設置包含 Babylon.js 場景的 HTML 網頁開始。

  1. 建立一個名為 babylonjs-piano-tutorial 的資料夾,然後用 Visual Studio Code 開啟該資料夾。

    注意事項

    雖然你可以使用任何程式碼編輯器來跟著操作,但為了方便,我們會全程使用 Visual Studio Code。

  2. 在資料夾中建立一個名為 index.html 的檔案,並插入以下範本:

    <html>
        <head>
            <title>Piano in BabylonJS</title>
            <script src="https://cdn.babylonjs.com/babylon.js"></script>
            <style>
                body,#renderCanvas { width: 100%; height: 100%;}
            </style>
        </head>
        <body>
            <canvas id="renderCanvas"></canvas>
            <script type="text/javascript">
                const canvas = document.getElementById("renderCanvas"); 
                const engine = new BABYLON.Engine(canvas, true); 
    
                createScene(engine).then(sceneToRender => {
                    engine.runRenderLoop(() => sceneToRender.render());
                });
    
                // Watch for browser/canvas resize events
                window.addEventListener("resize", function () {
                    engine.resize();
                });
            </script>
        </body>
    </html>
    

    如果你需要更多關於這個範本內容的說明,可以參考 Hello World 教學,這是本教學的前提。

  3. 如果你嘗試在瀏覽器中開啟這個檔案,主控台會顯示錯誤,表示找不到該 createScene() 功能。 我們來解決這個錯誤,請在下一節實作這個函式 createScene()

設置場景

  1. 在與 index.html相同的資料夾中,建立另一個名為 scene.js的檔案。 我們會把所有與場景設置和建立鋼琴相關的 JavaScript 程式碼存在這個檔案裡。

  2. 我們將函 createScene() 數加入 scene.js

    const createScene = async function(engine) {
        const scene = new BABYLON.Scene(engine);
        return scene;
    }
    

    請注意,我們正在製作 createScene() 一個非同步函式。 敬請期待,了解原因。

  3. 接下來,我們需要燈光和攝影機來讓場景對我們看見。 更新函 createScene() 式:

    const createScene = async function(engine) {
        const scene = new BABYLON.Scene(engine);
    
        const alpha =  3*Math.PI/2;
        const beta = Math.PI/50;
        const radius = 220;
        const target = new BABYLON.Vector3(0, 0, 0);
    
        const camera = new BABYLON.ArcRotateCamera("Camera", alpha, beta, radius, target, scene);
        camera.attachControl(canvas, true);
    
        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
        light.intensity = 0.6;
    
        return scene;
    }
    

    這裡,我們建立了一個 ArcRotateCamera,幾乎完全朝下,並鎖定空間的原點。 我們創造的光是一種指向天空的 半球光 ,對模擬環境空間非常有用。 我們也透過降低光線強度來稍微調暗。

    如果你需要複習如何製作攝影機和燈光,請在進入下一步前,先回訪 Hello World 教學系列的「準備場景」部分

  4. 最後,因為我們是為 WebXR 平台開發,需要在場景中return scene;插入以下行,啟用 XR 體驗

    const xrHelper = await scene.createDefaultXRExperienceAsync();
    

    在 JavaScript 中,若要在函式中的函式中使用await關鍵字,父函式也必須是 async,這也是我們之前定義createScene函式為非同步async的原因。 在本教學系列的後續,我們將利用此方法 xrHelper 啟用並配置 Babylon.js 支援的不同 WebXR 功能。

  5. 完成的 scene.js 應該是這樣的:

    const createScene = async function(engine) {
        const scene = new BABYLON.Scene(engine);
    
        const alpha =  3*Math.PI/2;
        const beta = Math.PI/50;
        const radius = 220;
        const target = new BABYLON.Vector3(0, 0, 0);
    
        const camera = new BABYLON.ArcRotateCamera("Camera", alpha, beta, radius, target, scene);
        camera.attachControl(canvas, true);
    
        const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
        light.intensity = 0.6;
    
        const xrHelper = await scene.createDefaultXRExperienceAsync();
    
        return scene;
    }
    
  6. 現在我們有一個可用的 createScene() 函式,讓我們 index.htmlscene.js 檔案載入為腳本,讓 createScene() 函式在 index.html中被識別。 在 HTML 檔案的區塊中加入這行程式碼 <header>

    <html>
        <head>
            <title>Piano in BabylonJS</title>
            <script src="https://cdn.babylonjs.com/babylon.js"></script>
            <script src="scene.js"></script>
            <style>
                body,#renderCanvas { width: 100%; height: 100%;}
            </style>
        </head>
        <body>
            <canvas id="renderCanvas"></canvas>
            <script type="text/javascript">
                const canvas = document.getElementById("renderCanvas");
                const engine = new BABYLON.Engine(canvas, true); 
    
                createScene(engine).then(sceneToRender => {
                    engine.runRenderLoop(() => sceneToRender.render());
                });
    
                // Watch for browser/canvas resize events
                window.addEventListener("resize", function () {
                    engine.resize();
                });
            </script>
        </body>
    </html>
    
  7. 在瀏覽器開啟 index.html ,你會發現之前看到的錯誤訊息已經消失,頁面中出現了一個空白的 Babylon.js 場景。

後續步驟