浏览器中的虚拟现实和增强现实
myzbx 2024-12-12 13:39 53 浏览
介绍
这篇关于渐进式 Web 应用程序的文章是教你如何在Web 应用程序中实现虚拟现实 (VR) 和增强现实 (AR)。因此,我们使用A-Frame和 WebXR Web API来实现。通过阅读该文章,我们将学习到虚拟现实和增强现实是如何应用到我们的浏览器,了解实现框架A-Frame、WebXR设备接口的相关知识点。
何为VR、AR
VR 将用户带到另一个世界,给予身临其境的感受,如同自己身处在这个虚拟世界中一样。另一方面,AR 提供了将现实世界和虚拟世界相互融合的可能性。VR 和AR 为行为改变、知识转移、培训和研究提供独特的体验。例如,想想VR 直播、社交 VR,这一切现在也可以在浏览器中实现!
什么是A-Frame?
图1
A-Frame 是一个用于构建 VR 体验和 AR 体验的 Web 框架。A-Frame 基于 HTML(这我喜欢),它的核心是一个强大的实体框架,提供了可扩展和可重用的结构,建立在WebXR 和 Three.js 之上,开发人员可以无限制地访问 JavaScript、DOM API、three.js、WebXR 和 WebGL。
WebXR 是一个用于在浏览器中创建 VR/AR 体验的 Web API。
Three.js 是一个 VR/AR 框架
WebGL 负责渲染
A-Frame学习地址:https://aframe.io/aframe-school/#/
A-Frame其实内部使用Web Components自定义了HTML标签,内置WebXR 和 Three.js,以致我们使用如同HTML标签一般丝滑!如果想入门 A-Frame 可以阅读Glitch上的入门示例:传送门。Glitch就是 类似Codepen的平台。
图2
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>
从入门示例中可以看到,A-Frame提供了一些a-*自定义标签协助我们完成构建 VR/AR程序。
A-Frame 中的 ECS
A-frame 是基于实体-组件-系统 (ECS) 架构。
ECS 架构是 3D 和游戏开发中遵循组合优于继承原则的常见模式。也就是说,每个实体都由组件组成(参见:实体的抽象示例)。
实体是标明哪些组件可以链接到的容器对象。组件又是可重用的模块,可以链接到实体以此向实体提供功能。
而所有逻辑都是通过组件实现的,我们通过配置或组装组件来定义不同类型的实体。A-Frame 拥有代表 ECS 各个部分的 API:
实体由<a-entity>元素表示
组件由<a-entity> 上的HTML 属性 表示。
实体的抽象示例
下面你会看到一些抽象示例,说明如何使用组件组成实体。上面入门示例中的球体就是一个实体。而位置、几何和材料是这个实体的组成部分。
Sphere = Position + Geometry + Material (球体 = 位置 + 几何 + 材质)
Ball = Position + Velocity + Physics + Geometry + Material (球 = 位置 + 速度 + 物理 + 几何 + 材料)
A-Frame 中的实体语法
根据前面的示例,球体的实体语法如下所示:
<a-entity geometry="primitive: sphere; radius: 1.5"
material="color: white; shader: flat; src: glow.jpg"
position="0 0 -5"></a-entity>
因此,要绘制这个球体,你需要定义一个 <a-entity>组件(Html扩展标签), 并将组件添加为 HTML 属性。大多数组件都有多个属性,由类似于 CSS 的语法表示。
Primitives
中文意思就是非派生原始的意思,其实Primitives就是 A-Frame 提供易于使用的HTML自定义元素,包装底层实体组件,说到底就是进行分类了,衍生了上面示例的<a-box>、<a-sphere>等HTML自定义元素,意在使开发者们更容易接受。
下面的是<a-box>与<a-entity>的用法比较:
Primitive:
<a-box color="red" width="3"></a-box>
Entity:
<a-entity geometry="primitive: box; width: 3" material="color: red"></a-entity>
在浏览器中构建 VR 场景
我们开始使用实体和动画构建一个基本的 A-Frame VR 场景:
图3
创建index.html
创建index.html,
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
</a-scene>
</body>
</html>
场景
上述代码,出现了一个<a-scene>标签,场景是一切发生的地方,所有实体和组件都必须添加到要渲染的场景中,在 A-Frame 中,场景由 <a-scene> 实体标签表示。
<a-scene> 相当是为我们提供处理所有three.js 和 WebXR 的容器,例如设置 WebGL(它负责渲染)、画布、相机、灯光、渲染器、渲染循环和 out-of-the-box WebXR - 支持 HTC Vive、Oculus Rift、三星 GearVR 等平台。
场景实体继承Entity 类,因此继承了Entity 类的所有属性、链接组件的能力以及等待开始渲染循环之前其所有子实体和节点(例如 <a-assets> 和 <a-entity> )加载的行为。
添加实体
在创建好的<a-scene>中,可以使用 A-Frame 的内置的Primitives添加 3D 实体,例如<a-box>。以下代码同时定义了<a-box> 的颜色。
<a-scene>
<a-box color="red"></a-box>
</a-scene>
图4
但是,由于默认相机和 位于 0 0 0原点的默认位置,除非移动它,否则您将无法看到该框,你可以通过使用位置组件将盒子转换为 3D 空间来做到这一点。
在 3D 中转换实体
我们先来看看 3D 空间。A-Frame 使用右手坐标系(如下图)。使用默认相机方向:X 轴正向向右延伸,Y 轴正向向上延伸,Z 轴正向向我们伸出屏幕外:
图5
让<a-box>对相机可见
让我们让盒子对相机可见,旋转和缩放它。要使其可见,您可以使用位置组件在负 Z 轴上将框向后滑动 5 米。同时还应该在正 Y 轴上将盒子向上移动 2 米,这样盒子就不会与地面相交。
<a-scene>
<a-box color="red" position="0 2 -5" rotation="0 45 45" scale="2 2 2">
</a-box>
</a-scene>
A-Frame 的距离单位是米,因为 WebXR API 返回以米为单位的位置。在为 VR 设计场景时,重要的是要考虑实体的真实世界规模。height="10" 的框在你的桌面上可能看起来很正常,但在 VR 世界中该框会显得很大。
旋转的单位是度,尽管在转换到 three.js 时它会在内部转换为弧度。
父子转换
A-Frame HTML 表示 3D 场景图。在场景图中,实体可以有一个父级和多个子级。子实体会从其父实体继承变换(即位置、旋转和缩放)。
可以将球体作为盒子的子项,
<a-scene>
<a-box position="0 2 0" rotation="0 45 45" scale="2 4 2">
<a-sphere position="1 0 3"></a-sphere>
</a-box>
</a-scene>
如果我们计算球体的位置,它将是 1 2 3。这是通过将球体的父位置与其自身位置组合计算来实现的。同样,球体将继承盒子的旋转和缩放。
使用环境组件添加环境
A-Frame允许开发人员创建其他人可以轻松使用的可重用组件。
接下来我们来使用环境组件,这个组件用一行 HTML 为我们生成了各种环境。环境组件是一种直观地启动我们的 VR 应用程序的简单方法,它提供了十几个具有众多参数的环境。
首先,添加带有脚本标签的环境组件。
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js">
</script>
</head>
然后,我们添加一个 a-entity实体将环境组件链接到的 <a-scene> 标记中。你可以指定预设环境(例如,预设:森林)。以及许多其他参数,例如通过设置dressingAmount参数来获得树木数量:
<a-scene>
<a-box color="red" position="0 2 -5" rotation="0 45 45"
scale="2 2 2"></a-box>
<!-- Out of the box environment! -->
<a-entity environment="preset: forest; dressingAmount: 500"></a-entity>
</a-scene>
图6
预设是定义特定样式的参数值的组合,它们是你可以自定义的起点。
你可以使用Inspector(ctrl + alt + i)调整这些参数。Inspector是用于检查和调整实体/组件的工具。Inspector 类似于浏览器的 DOM 检查器,但专为 3D 和 A-Frame 量身定制。
添加资产管理系统
你可以使用 <img> 元素将图片资源应用到场景中去,
资产管理 可以在渲染场景之前加载和缓存图像和视频。预加载和缓存可以提高性能。以下是如何将资产管理应用于图像的示例:
<a-scene>
<a-assets>
<img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg">
</a-assets>
<a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2">
<a-sphere position="1 0 3"></a-sphere>
</a-box>
<a-entity environment="preset: forest; dressingAmount: 500"></a-entity>
</a-scene>
图7
定义了一个<a-assets> 标签,其中定义了带有图像的<img>标签 。这个 img 也有一个 id=" boxTexture "。
图8
最后在<a-box>引用此 id。
添加动画
可以使用动画组件为盒子和球体设置动画,
要使盒子上下移动,请设置以下内容:
- 要将框在 Y 轴上移动 2 到 2.2 米,请使用属性进行设置:object3D.position.y;至:2.2。
- 方向(dir)是交替的。即交替上升和下降。
- 持续时间表示一个周期持续多长时间(2000 毫秒)。
- 并且,循环执行指定动画。
<a-scene>
<a-assets>
<img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg">
</a-assets>
<a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"
animation="property: object3D.position.y; to: 2.2; dir: alternate; dur: 2000; loop: true">
<a-sphere position="1 0 3"></a-sphere>
</a-box>
<a-entity environment="preset: forest; dressingAmount: 500"></a-entity>
</a-scene>
上述的最终结果可以自己开启一个HTML页面查看效果。
增强现实
通过 A-Frame 还可以实现 AR 体验。
AR 实施的可以从 Glitch上的入门示例(https://glitch.com/~aframe)开始
图9
<!DOCTYPE html>
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
</head>
<body>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>
接下来我们可以针对上述应用程序为其添加hittesting(命中测试), 其实现也可以在以下位置找到实现 AR-hittesting,代码如下:
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="/ar-components.js"></script>
</head>
<body>
<a-scene webxr="optionalFeatures: hit-test">
<a-entity id="world" scale="0.1 0.1 0.1">
<a-box position="-1 0.5 0" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -2" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -0" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -1" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
</a-entity>
<a-entity ar-hit-test="target:#world;">
<a-plane rotation="-90 0 0" width="0.2" height="0.2" src="./arrow.png" material="transparent:true"></a-plane>
</a-entity>
</a-scene>
<script>
const reticle = document.querySelector("[ar-hit-test]");
</script>
</body>
</html>
你可以使用此URL https://ar-basic-hittest.glitch.me/在你的手机上测试最终版本。
通过命中测试,您可以将虚拟对象与真实世界的对象(例如地板、桌子和墙壁)对齐。通过下面的示例,您可以将图 9中的对象与例如桌子对齐,方法是通过你的相机(使用十字线)瞄准桌子,然后触摸该桌子(命中测试)。
我们发现,要在 AR 中进行命中测试,你首先需要在脚本标签中包含ar-components.js。你可以从最终的 Glitch 实现中复制这个库(上述已经提过)。
在场景a-scene组件中,我们需要表明要使用WebXR 功能:命中测试,webxr="optionalFeatures: hit-test"。
然后通过 实体a-entity组件 设置对象的真实比例scale="0.1 0.1 0.1"。
最后,定义了一个新实体:ar-hit-test。该组件可以将虚拟对象内嵌在你通过相机看到的真实对象上(图 10)。要支持命中测试,请在20 厘米可见区中定义一个标线。你可以通过a-plane 组件执行此操作。
备注:我的iphone手机体现不出效果
结语
这篇文章主要介绍了如何使用A-Frame框架在浏览器中来实现虚拟现实 (VR) 和增强现实 (AR),内容也相对简单,容易理解,可以说只是入门,想了解更多,可以深入了解A-Frame知识,以及WebXRWEB 标准,感谢阅读!
译自Virtual Reality and Augmented Reality in the Browser
文章来自公众号@前端晚间课
- 上一篇:使用属性中的 XSS 负载绕过白名单
- 下一篇:没人愿意使用这些 HTML 标记
相关推荐
- 如何设计一个优秀的电子商务产品详情页
-
加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...
- 怎么在JS中使用Ajax进行异步请求?
-
大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...
- 中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革
-
前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...
- 前端监控 SDK 开发分享_前端监控系统 开源
-
一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...
- Ajax 会被 fetch 取代吗?Axios 怎么办?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...
- 前端面试题《AJAX》_前端面试ajax考点汇总
-
1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...
- Ajax 详细介绍_ajax
-
1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...
- 6款可替代dreamweaver的工具_替代powerdesigner的工具
-
dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...
- 我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊
-
接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...
- 福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光
-
时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...
- 2021年超详细的java学习路线总结—纯干货分享
-
本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...
- 不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!
-
Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...
- 2025 年 Python 爬虫四大前沿技术:从异步到 AI
-
作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...
- 最贱超级英雄《死侍》来了!_死侍超燃
-
死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...
- 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
-
一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)
