毕加索塔360º之旅,使用A-Frame

360º之旅是指模拟亲临现场的体验,通过周围空间进行参观。这种“漫游”参观由多个场景组成,在每个场景中都可以环顾四周,就像在谷歌街景中一样。在360º之旅中,不同的场景可以通过离散的热点访问,用户可以启用或跳入这些热点,将自己传送至旅程中的另一个地方。

The magenta octahedron represents the user’s point of view. The image covers the inner surface of the sphere.

品红色八面体代表用户的视角。图像覆盖球体的内表面。

使用A-Frame,创建这样的体验是一项非常简单的任务。

360º全景

在摄影中,全景本质上是广角图像。广角意味着广阔的视野,因此相机捕获的物理空间区域比普通图片更广。360º全景捕获了相机周围的所有空间。

就像广角摄影需要特殊的镜头一样,360º全景也需要特殊的相机。你可以阅读Kevin Ngo的360º摄影指南,获取创建全景的建议和推荐。

试图以矩形格式表示球体会导致我们所说的投影。投影会引入失真——直线会变成曲线。你可能能够通过全景视图在二维空间中表示时产生的失真效应来识别全景图片。

要消除失真,你必须将矩形投影回球体。使用A-Frame,这意味着将全景作为面向相机的球体的纹理使用。最简单的方法是使用a-sky基元。为了在此设置中正常工作,图像的投影必须是等距矩形

通过添加一些JavaScript代码,你可以修改天空基元的src属性,以更改全景纹理,并让用户传送到场景中的另一个位置

获得等距矩形图像实际上取决于捕获设备。例如,三星Gear 360相机需要使用三星官方拼接软件将原生双鱼眼输出合并成等距矩形版本;而理光Theta S会同时输出等距矩形和双鱼眼图像,无需进一步操作。

A dual-fisheye image arranges two fisheye images side by side

双鱼眼图像通常是360º相机的输出。拼接软件可以将其转换为等距矩形图像。

360º之旅模板

要创建这样的体验,你可以使用aframe-cli附带的360之旅模板aframe-360-tour-template将上述概念封装在可重用的组件和有意义的基元中,使开发人员能够只需几个步骤即可编写语义化的360º之旅。

aframe-cli尚未发布(这是A-Frame的最前沿工具),但你可以使用npm安装预发布版本,运行以下命令

npm install -g aframevr-userland/aframe-cli

现在你可以使用aframe命令访问aframe-cli。转到你的工作区目录,并通过指定项目文件夹的名称和模板来启动一个新项目

$ aframe new tour --template 360-tour
$ cd tour

使用以下命令启动体验

$ aframe serve

然后访问http://127.0.0.1:3333体验旅程。

添加全景

访问我的毕加索塔360相册在Flickr上并下载完整的相册。(图像为公有领域,因此不用担心许可问题。)

解压缩文件并将图像粘贴到app/assets/images/文件夹中。在本例中,我将只使用三张图片。阅读完本文后,你可以尝试完整的旅程。请注意,全景顺序与命名匹配:360_0071_stitched_injected_35936080846_o360_0072_stitched_injected_35936077976_o之前,360_0072_stitched_injected_35936077976_o360_0073_stitched_injected_35137574104_o之前,依此类推……

编辑index.html以找到a-tour基元内的全景部分。通过修改src属性更改当前的全景,或通过编写新的a-panorama基元添加新的全景。将当前的全景替换为以下全景

<a-panorama id="garden" src="images/360_0071_stitched_injected_35936080846_o.jpg"></a-panorama>
<a-panorama id="corner" src="images/360_0074_stitched_injected_35936077166_o.jpg"></a-panorama>
<a-panorama id="facade" src="images/360_0077_stitched_injected_35137573294_o.jpg"></a-panorama>

保存并重新加载浏览器选项卡以查看新结果。

你可能需要调整全景的旋转,以使用户面向你想要的方向。更改全景的rotation组件来执行此操作。(请记住保存并重新加载以查看更改。)

<a-panorama id="garden" src="images/360_0071_stitched_injected_35936080846_o.jpg" rotation=”0 90 0”></a-panorama>

现在你需要使用定位的热点将新的序列连接到其他全景。将当前的热点替换为以下热点,并通过重新加载选项卡查看结果

<a-hotspot id="garden-to-corner" for="garden" to="corner" mixin="hotspot-target" position="-3.86 -0.01 -3.18" rotation="-0.11 50.47 -0.00">
  <a-text value="CORNER" align="center" mixin="hotspot-text"></a-text>
</a-hotspot>

请记住,为了激活热点,在桌面模式下,你必须将黑色圆圈放在品红色八面体上,然后点击屏幕。

放置热点

定位热点可能是一项令人沮丧的任务。幸运的是,模板提供了一个有用的组件来帮助完成此任务。只需将hotspot-helper组件添加到你的旅程中,并将你要放置的热点的引用作为target属性的值:<a-tour hotspot-helper="target: #corner-to-garden">。该组件会在你环顾四周时移动热点,并在左上角显示一个小部件,显示热点的世界位置和旋转,允许你将这些值复制到剪贴板。

自定义热点

你可以使用mixin自定义热点。编辑index.html并找到assets部分内的hotspot-texthotspot-target混合基元。

例如,为了避免需要复制世界旋转值,我们将使用ngokevin的lookAt组件,该组件已包含在模板中。

修改具有hotspot-text ID的实体,使其看起来像这样

<a-mixin id="hotspot-text" look-at="[camera]" text="font: exo2bold; width: 5" geometry="primitive: plane; width: 1.6; height: 0.4" material="color: black;" position="0 -0.6 0"></a-mixin>

光标反馈

如果你进入VR模式,你会发现传送到一个新地方需要你将视线固定在你想要到达的热点上,持续一段时间。我们可以通过修改cursor组件更改此间隔的持续时间。尝试将超时时间增加到两秒

<a-entity cursor="fuse: true; fuse-timeout: 2000" position="0 0 -1"
          geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
          material="color: black; shader: flat">

fuse: true添加到你的光标组件后,即使在非VR模式下,你也不需要点击屏幕。click事件将在fuse-timeout毫秒后触发。

遵循关于cursor组件的文章中的建议,你可以通过在光标实体内附加一个a-animation基元来创建即将发生某事的感知

<a-entity cursor="fuse: true; fuse-timeout: 2000" position="0 0 -1"
          geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
          material="color: black; shader: flat">
      <a-animation begin="fusing" end="mouseleave" easing="ease-out" attribute="scale"
                   fill="backwards" from="1 1 1" to="0.2 0.2 0.2"
                   dur="2000"></a-animation>
</a-entity>
Fix the gaze on a hotspot for 2 seconds to activate the hotspot and teleport.

点击上面的图片以查看保险丝和动画反馈的实际效果。

环境音效

声音是增强存在感的强大工具。你可以在互联网上找到许多提供免版税声音的地方,例如soundbible.com。当你决定好为你创建的体验选择合适的环境噪声后,获取文件URL或下载它(如果不可用)并将其本地服务。在app/assets下创建一个名为sounds的新文件夹,并将音频文件放入其中。

添加一个audio标签,该标签指向<a-assets>元素内的音频文件URL,以便文件可以加载

<a-assets>
   ...
   <audio id="ambient-sound" src="sounds/environment.mp3"></audio>
</a-assets>

并使用sound组件引用audio元素ID来开始播放音频

<a-tour sound="src: #ambient-sound; loop: true; autoplay: true; volume: 0.4"></a-tour>

通过修改volume属性来调整音量,该属性的范围为0到1。

结论

360º之旅为首次接触WebVR的创作者提供了一个完美的入门项目,无需使用奇特或昂贵的设备即可开始VR开发。全景360º场景自然而然地回退到桌面或移动屏幕上的常规2D可视化,并且使用纸板眼镜或VR头戴式显示器,用户将享受更强的沉浸感。

使用 aframe-cli 和 360º 旅游模板,您可以快速设置自定义和发布 360º VR 旅游的基本要素。创建一个新项目来展示您最喜欢的地方(真实或虚构!),添加全景视图,或开始修改模板以扩展其基本功能。无论哪种方式,都不要忘记与 A-Frame 社区在 Slack 上Twitter 上分享您的项目。

关于 Salva

Mozilla 的前端开发人员。开放式网络和 WebVR 支持者,我热爱编程语言、电影、音乐、电子游戏和啤酒。

更多 Salva 的文章...


5 条评论

  1. Amos

    感谢您的文章。您知道我们是否/何时能够在 AFrame/WebVR 中四处走动并与浏览器内容互动吗?

    所有的努力似乎都集中在将 VR 带入网络浏览器,但我更感兴趣的是将网络带入 VR。基本上,一个完全功能的 div 容器作为纹理表面将是各种创意的良好开端。

    2017 年 7 月 18 日 18:44

    1. Salva

      对此已经进行了讨论,但还没有最终结论。现在最好的选择是使用 aframe-html-shader
      https://github.com/mayognaise/aframe-html-shader

      2017 年 7 月 20 日 08:24

  2. Stephanie Hallberg

    喜欢!

    Codepen 太酷了。只有 5 行代码 + 图片。这太棒了,太棒了!

    2017 年 7 月 28 日 12:05

  3. Utopiah

    很酷,我不知道 aframe-cli 存在!

    很高兴看到组件,因为它是一种反复出现的需求,但也使其在生产方面更高效。

    PS:对于三星,他们的工具是可选的,另一种选择是使用 gear360pano 脚本用于 hugin cf https://github.com/ultramango/gear360pano (CLI)。

    2017 年 7 月 29 日 00:08

    1. Salva

      哦!感谢您提供脚本,很高兴知道有一个 CLI 替代方案。

      2017 年 7 月 29 日 15:29

本文的评论已关闭。