Учебник. Создание пианино в WebXR с помощью Babylon.js

Создание пианино в реальном мире требует много времени, навыков и материалов. Но как насчет создания пианино для мира виртуальной или дополненной реальности?

В этой серии учебников описывается, как использовать Babylon.js для создания веб-приложения смешанной реальности, которое предоставляет работающее стоячее пианино с 88 клавишами в виртуальном мире. В готовом приложении вы сможете телепортироваться к пианино и играть на клавишах с помощью контроллеров смешанной реальности.

Из этой серии учебников вы узнаете, как выполнять следующие задачи:

  • создание, размещение и объединение сеток для создания клавиатуры пианино;
  • импорт модели Babylon.js для стоячего корпуса пианино;
  • добавление взаимодействий с помощью указателя к каждой клавише пианино;
  • включение поддержки телепортации и нескольких указателей в WebXR.

Предварительные требования

Начало работы

Начнем с настройки веб-страницы HTML, которая будет содержать сцену Babylon.js.

  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, который указывает почти полностью вниз и нацелен на начальную точку пространства. Созданный источник света — это объект HemisphericLight, который указывает вверх и полезен для имитации объемного пространства. Мы также немного приглушили свет, снизив его интенсивность.

    Если вам нужно вспомнить, как создать камеру и источник света, вернитесь к разделу "Подготовка сцены" из серии учебников по Hello World, прежде чем переходить к следующему шагу.

  4. Наконец, так как мы разрабатываем приложение для платформы WebXR, нам потребуется включить интерфейс смешанной реальности в сцене, вставив следующую строку перед return scene;:

    const xrHelper = await scene.createDefaultXRExperienceAsync();
    

    В JavaScript для использования ключевого слова await в функции async, вложенной в функцию, родительская функция также должна быть асинхронной (async). Именно поэтому мы определили функцию createScene как асинхронную ранее. Далее в этой серии учебников мы будем использовать этот xrHelper, чтобы включить и настроить разные функции WebXR, поддерживаемые Babylon.js.

  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.html загрузил файл scene.js в виде скрипта. Это нужно для того, чтобы функция createScene() была распознана в index.html. Добавьте следующую строку кода в разделе <header> HTML-файла:

    <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.

Дальнейшие действия