教程:与 3D 对象交互
了解如何使用 Babylon.js 为混合现实体验创建 3D 对象和交互。 在本部分中,您将从一些简单内容开始,例如,在选择对象时为立方体面涂色。
本教程涵盖以下主题:
- 如何添加交互
- 启用 WebXR 沉浸式模式
- 在 Windows Mixed Reality 模拟器上运行应用
- 在 Android Chrome 上运行和调试应用
开始之前
在教程的上一步中,创建了一个包含场景的基本网页。 打开主页进行编辑。
<html>
<head>
<script src="https://cdn.babylonjs.com/babylon.js"></script>
<style>
body,#renderCanvas { width: 100%; height: 100%;}
</style>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<script>
const canvas = document.getElementById("renderCanvas");
const engine = new BABYLON.Engine(canvas, true);
const createScene = function() {
const scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color3.Black;
const alpha = Math.PI/4;
const beta = Math.PI/3;
const radius = 8;
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(1, 1, 0));
const box = BABYLON.MeshBuilder.CreateBox("box", {});
box.position.x = 0.5;
box.position.y = 1;
return scene;
};
const sceneToRender = createScene();
engine.runRenderLoop(function(){
sceneToRender.render();
});
</script>
</body>
</html>
添加交互
首先,让我们更新创建立方体的代码,以便使用随机颜色为立方体涂色。 为此,我们将向立方体添加材料。 材料允许我们指定颜色和纹理,并可用于覆盖其他对象。 材料显示方式取决于场景中使用的光线以及材料对光线的响应方式。 例如,diffuseColor 将颜色分布到它所附加到的网格上。 添加以下代码:
const boxMaterial = new BABYLON.StandardMaterial("material", scene); boxMaterial.diffuseColor = BABYLON.Color3.Random(); box.material = boxMaterial;
现在,立方体已经涂上了随机颜色,接下来让我们添加如下交互:
- 单击立方体时更改颜色
- 更改颜色后移动立方体
若要添加交互,应使用操作。 系统会启动操作以响应事件触发器。 例如,当用户单击立方体时。 我们只需实例化 BABYLON.ActionManager 并为特定触发器注册操作。 当有人单击立方体时,BABYLON.ExecuteCodeAction 将运行 JavaScript 函数:
box.actionManager = new BABYLON.ActionManager(scene); box.actionManager.registerAction(new BABYLON.ExecuteCodeAction( BABYLON.ActionManager.OnPickTrigger, function (evt) { const sourceBox = evt.meshUnderPointer; //move the box upright sourceBox.position.x += 0.1; sourceBox.position.y += 0.1; //update the color boxMaterial.diffuseColor = BABYLON.Color3.Random(); }));
网页的最终代码如下所示:
<html> <head> <script src="https://cdn.babylonjs.com/babylon.js"></script> <style> body,#renderCanvas { width: 100%; height: 100%;} </style> </head> <body> <canvas id="renderCanvas"></canvas> <script> const canvas = document.getElementById("renderCanvas"); const engine = new BABYLON.Engine(canvas, true); const createScene = function() { const scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3.Black; const alpha = Math.PI/4; const beta = Math.PI/3; const radius = 8; 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(1, 1, 0)); const box = BABYLON.MeshBuilder.CreateBox("box", {}); box.position.x = 0.5; box.position.y = 1; const boxMaterial = new BABYLON.StandardMaterial("material", scene); boxMaterial.diffuseColor = BABYLON.Color3.Random(); box.material = boxMaterial; box.actionManager = new BABYLON.ActionManager(scene); box.actionManager.registerAction( new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function (evt) { const sourceBox = evt.meshUnderPointer; sourceBox.position.x += 0.1; sourceBox.position.y += 0.1; boxMaterial.diffuseColor = BABYLON.Color3.Random(); })); return scene; }; const sceneToRender = createScene(); engine.runRenderLoop(function(){ sceneToRender.render(); }); </script> </body> </html>
启用 WebXR 沉浸式体验
现在,立方体正在更改颜色,我们已准备好尝试沉浸式体验。
在此步骤中,我们将介绍一个地面。 立方体将悬吊于空中,我们将在底部看到地板。 按如下所示添加地面:
const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 4, height: 4});
这会创建一个简单的 4x4 米的地板。
为了添加 WebXR 支持,我们需要调用 createDefaultXRExperienceAsync,它会产生 Promise 结果。 在 createScene 函数(而不是 return scene;)的末尾添加此代码:
const xrPromise = scene.createDefaultXRExperienceAsync({ floorMeshes: [ground] }); return xrPromise.then((xrExperience) => { console.log("Done, WebXR is enabled."); return scene; });
由于 createScene 函数现在会返回 promise 而不是场景,因此我们需要修改 createScene 和 engine.runRenderLoop 的调用方式。 将这些函数的当前调用(位于 /script<> 标记之前)替换为以下代码:
createScene().then(sceneToRender => { engine.runRenderLoop(() => sceneToRender.render()); });
网页的最终代码如下所示:
<html> <head> <script src="https://cdn.babylonjs.com/babylon.js"></script> <style> body,#renderCanvas { width: 100%; height: 100%;} </style> </head> <body> <canvas id="renderCanvas"></canvas> <script> const canvas = document.getElementById("renderCanvas"); const engine = new BABYLON.Engine(canvas, true); const createScene = function() { const scene = new BABYLON.Scene(engine); scene.clearColor = new BABYLON.Color3.Black; const alpha = Math.PI/4; const beta = Math.PI/3; const radius = 8; 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(1, 1, 0)); const box = BABYLON.MeshBuilder.CreateBox("box", {}); box.position.x = 0.5; box.position.y = 1; const boxMaterial = new BABYLON.StandardMaterial("material", scene); boxMaterial.diffuseColor = BABYLON.Color3.Random(); box.material = boxMaterial; box.actionManager = new BABYLON.ActionManager(scene); box.actionManager.registerAction( new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger, function (evt) { const sourceBox = evt.meshUnderPointer; sourceBox.position.x += 0.1; sourceBox.position.y += 0.1; boxMaterial.diffuseColor = BABYLON.Color3.Random(); })); const ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 4, height: 4}); const xrPromise = scene.createDefaultXRExperienceAsync({ floorMeshes: [ground] }); return xrPromise.then((xrExperience) => { console.log("Done, WebXR is enabled."); return scene; }); }; createScene().then(sceneToRender => { engine.runRenderLoop(() => sceneToRender.render()); }); </script> </body> </html>
上述代码在浏览器窗口中生成以下输出:
在 Windows Mixed Reality 模拟器上运行
启用 Windows Mixed Reality 模拟器(如果之前没有启用)。
选择右下角的沉浸式 VR 按钮:
此操作将启动 Windows Mixed Reality 模拟器窗口,如下所示:
使用键盘上的 W、A、S 和 D 键相应地向前、向后、向左和向右移动。 使用模拟的手对准立方体,然后按键盘上的 Enter 键执行单击操作。 立方体将更改其颜色并移动到新位置。
注意
对准立方体时,请确保手部射线末端(白色圆圈)与立方体相交,如上图所示。 详细了解用手指向和提交。
在 Android 设备上运行和调试
执行以下步骤,在 Android 设备上启用调试:
先决条件
在开发计算机上的安全上下文中提供静态 html 页面的 Web 服务器(https:// 或通过 localhost 上的端口转发)。 例如,利用 serve npm 包作为简单的轻量级 Web 服务器来提供静态 html 文件,进一步了解 npm serve
设备最初附带 Google Play Store,并且必须运行 Android 7.0 或更新版本
开发工作站和设备上均装有最新版 Google Chrome
若要验证设备是否正确配置为运行 WebXR,请在设备上浏览到示例 WebXR 页面。 应看到如下消息:
您的浏览器支持 WebXR,如果具有适当的硬件,可以运行虚拟现实和增强现实体验。
在 Android 设备上启用开发人员模式和 USB 调试。 请参阅官方文档页面配置设备上的开发人员选项,了解如何为您使用的 Android 版本执行此操作
接下来,通过 USB 线将 Android 设备连接到开发计算机或笔记本电脑
确保开发计算机上的 Web 服务器正在运行。 例如,导航到包含 Web 主页 (index.html) 的 root 文件夹,并执行以下代码(假设您使用 serve npm 包):
serve
在开发计算机上打开 Google Chrome,并在地址栏中输入以下文本:
chrome://inspect#devices
确保已启用“发现 USB 设备”复选框
单击“端口转移”按钮,确保“端口转移”已启用并包含条目 localhost:5000,如下所示:
在连接的 Android 设备中,打开 Google Chrome 窗口并浏览到 http://localhost:5000,您应该会看到立方体
在开发计算机上,如果使用 Chrome,将看到设备以及设备中当前打开的网页列表:
单击条目 http://localhost:5000 旁的“检查”按钮:
使用 Chrome DevTools 调试页面
要点
以下是本教程的内容要点:
- Babylon.js 有助于轻松地使用 JavaScript 打造沉浸式体验
- 若要创建虚拟场景,无需编写低级别代码或学习新技术
- 可以使用支持 WebXR 浏览器生成混合现实应用程序,而无需购买头戴显示设备
后续步骤
祝贺你! 你已完成 Babylon.js 系列教程并学习了如何:
- 设置开发环境
- 创建新的网页来显示结果
- 用于创建基本 3D 元素并与之交互的 Babylon.js API
- 在 Windows Mixed Reality 模拟器中运行和测试应用程序
有关混合现实 JavaScript 开发的更多信息,请参阅 JavaScript 开发概述。
如果正在查找其他 Babylon.js 教程,请查看钢琴构建教程系列,了解如何使用 Babylon.js 在 VR 空间中构建钢琴。