使用Awe.js在浏览器中增强现实

增强现实是一个整洁的概念。 我们以周围的世界为视角,并以图像,文字,声音和视频作为补充。 科技公司开始通过诸如Meta GlassesMicrosoft HoloLensMagic Leap之类的设备探索AR的可能性。 这些非常令人兴奋的AR头戴设备尚未完全面向消费者发布,因此可能要过一段时间才能让每个家庭都拥有一副。 但是,还有另一种方法可以使用移动浏览器将世界介绍给增强现实,而他们可能更容易使用这些东西。

我以前在SitePoint上有关使用Google Cardboard和Three.js将VR放到Web以及使用JavaScript和Google Cardboard过滤现实的文章中介绍了使用JavaScript和Three.js进行现实创建和操纵的其他方式。 在本文中,我将向您展示如何使用名为awe.js的JavaScript库在移动网络上创建增强现实体验。 我们将创建一个在纸笔顶部打开的3D控制板。 我们可以将其连接起来,以执行通过JavaScript HTTP请求可以启用的几乎所有操作,因此我将其设置为使用IFTTT更改LIFX灯泡的颜色。

您需要什么

对于此演示,当前需要使用Google Chrome移动版。 它可能也可以在Firefox for Mobile上运行,但是当我在HTC One M9上尝试点击事件时,我发现点击事件并未触发。 它也可以在某些台式机浏览器上运行(Chrome和Opera在我的Mac上运行得很好),但绝对不是与带有触摸事件的智能手机相同的体验。 在平板电脑上,它可能很整洁。

您还需要一个IFTTT帐户,以及如何使用在HTTP请求上触发的规则来设置Maker Channel的知识。 如果您是IFTTT的新手,那么我们之前已经阅读了有关使用IFTTT将LIFX灯泡连接到IoT的文章中的基础知识。 对于Maker频道的新手,我们还将IoT和Node.js连接到IFTTT中进行了介绍

最后,您需要在纸上打印标记。 我们将使用的标记是这一标记:

标记号64

编码

如果您想直接阅读代码并进行尝试,可以在GitHub找到它们

Awe.js

Awe.js是一个JavaScript库,它使用Three.js,您设备的相机和一些非常聪明的技术在浏览器中创建增强现实。 您可以在awe.js GitHub存储库上下载该库和一些示例。 它提供了四种不同的AR体验,每种都在仓库中带有自己的示例:

  • geo_ar –允许您将对象放置在设定的指南针点上。
  • grift_ar –与Oculus Rift兼容。
  • leap_ar –与Leap Motion控制器集成。
  • marker_ar –允许您创建位于增强现实标记上的体验。 这是我们将在此演示中使用的那个。

我们的增强现实演示代码

我们的演示代码长于300行,但其中很多是针对相似对象的重复代码。 我建议从演示的GitHub存储库下载演示代码,并按照此处提供的说明进行操作。 一旦了解了所有工作原理,请尝试修改并构建自己的东西。

一切都在我们windowload事件中开始。 我们包括的第一件事是一个变量,用于跟踪我们的AR控制面板(在这里我简称为“菜单”)是否打开。 最初,它是关闭的。

window.addEventListener('load', function() {
    var menu_open = false;
    
    // Our code continues here
  });

然后,我们开始使用awe.js库。 我们所做的一切都在window.awe.init()函数中定义。 我们从AR场景的一些全局设置开始。

window.awe.init({
    device_type: awe.AUTO_DETECT_DEVICE_TYPE,
    settings: {
      container_id: 'container',
      fps: 30,
      default_camera_position: { x:0, y:0, z:0 },
      default_lights: [{
        id: 'point_light',
        type: 'point',
        color: 0xFFFFFF
      }]
    },
  • device_type –所有示例都将其设置为awe.AUTO_DETECT_DEVICE_TYPE ,要求它自动检测设备。 到目前为止,我还没有看到需要对此进行更改。
  • settings -我们实际上可能希望在此处实时更改的设置。 这些包括:
    • container_id –我们将在内部生成整个元素的ID。
    • fps –我们期望的每秒帧数(可选)。
    • default_camera_position –我们要从中查看场景的默认摄像机位置(我们从(0,0,0)开始)。
    • default_lights –我们可以为场景设置一系列不同的Three.js光源,为每个光源指定一个ID,定义光源的类型和颜色。 我们的演示中只有一个白色Three.js PointLight。 光源类型有很多选项可用,它们与Three.js光源的不同类型相对应- 'area''directional''hemisphere''point''spot'

设置好之后,我们便定义了awe.js初始化后的操作。 一切都包裹在awe.util.require()函数中,该函数定义在加载我们需要的其他JavaScript文件之前所需的浏览器功能。 请小心,仅定义演示所需的浏览器功能,因为如果使用其他一些GitHub示例中列出的功能错误地定义了AR应用程序,则可以不必要地阻止AR应用程序在某些浏览器中运行。 例如,为了使元素基于罗盘点定位,您需要使用'gyro'功能。 在大多数台式机浏览器上都无法使用。 在本演示中我们不需要它,因此我们将其排除在外。

ready: function() {
    awe.util.require([
      {
        capabilities: ['gum','webgl'],

定义的文件引入了awe.js的特定功能-lib lib/awe-standard-dependencies.jslib/awe-standard.jslib/awe-standard-window_resized.js都很常见,它们定义了标准位以及awe.js和处理窗口大小调整的片段。 我们的演示使用标记,这需要标记下面列出的其他两个文件。

files: [ 
    ['lib/awe-standard-dependencies.js', 'lib/awe-standard.js'],
    'lib/awe-standard-window_resized.js',
    'lib/awe-standard-object_clicked.js',
    'lib/awe-jsartoolkit-dependencies.js',
    'lib/awe.marker_ar.js'
  ],

成功加载所有这些文件后,我们将运行适当命名的success() awe.js函数。 准备开始显示元素时将始终运行的第一个功能是设置awe.js场景。

success: function() {
    window.awe.setup_scene();

awe.js中的所有元素都位于“兴趣点”(POI)中。 这些是场景中的特定点,通过可将对象放置在其中的坐标进行标记。 您可以在awe.js以及元素本身中移动POI。 我们创建一个POI,将其放置在看到特定纸笔的任何地方。 要创建POI,我们使用awe.pois.add()的awe.js函数。

我已经给它指定了一个'marker'的ID,但是只要您在代码中对该POI的其他引用中始终保持一致,就可以随意命名。 我们将其初始位置设置为(0,0,10000),这会将其稍微移开一定距离,直到可以使用为止。 我们还将其设置为不可见,直到发现标记。

awe.pois.add({id: 'marker', position: {x: 0, y: 0, z: 10000}, visible: false});

我们添加到POI中的元素在awe.js中称为“投影”。 我们添加到场景中的第一个投影被称为'wormhole' ,因为这是一个扁平的黑色正方形,菜单项将在其中消失。 就像POI的ID一样,只要您将其与代码中对它的其他引用保持一致,就可以为您自己命名任何东西。 我们使用awe.projections.add()函数将其添加到POI中。

awe.projections.add({ 
    id: 'wormhole',
    geometry: {shape: 'plane', height: 400, width: 400},
    position: {x: 0, y: 0, z: 0},
    rotation: {x: 90, z: 45},
    material: {
      type: 'phong',
      color: 0x000000
    }
  }, {poi_id: 'marker'});

我们可以添加为投影的对象有很多选择,因此我将更详细地说明它们。 请注意–此处用于定位和旋转的所有x,y和z值均与其POI有关。 该POI在最后由其ID定义为{poi_id: 'marker'}

  • geometry -这是指投影的Three.js几何选项。 每种几何类型所需的选项都与awe.js中提供的选项匹配。 例如, Three.js中的SphereGeometry将在awe.js中表示为{shape: 'sphere', radius: 10} 。 对于使用最新的Three.js的用户(在awe.js的当前可用版本中), BoxGeometry仍要使用CubeGeometry。 因此,要创建盒子,我们使用格式{shape: 'cube', x: 20, y: 30, z: 5} (尽管名称,它不必是“ cube”)。
  • position –您可以相对于项目的POI调整项目的x,y和z轴。
  • rotation –您可以相对于其POI通过其x,y和z轴旋转该项目。 我将虫孔在其x轴上旋转90度,以使其在桌子上平放,并在其z轴上旋转45度,因为我认为它看起来更自然(它并不总是与标记完全对齐,因此它在对角线上的效果不那么明显)。
  • material –这定义了投影的Three.js材质。 我一直坚持使用'phong'MeshPhongMaterial中的MeshPhongMaterial),但是看起来像'lambert''shader''sprite''sprite_canvas'也可以作为选项使用。 我们还可以将其颜色定义为十六进制。
  • texture –演示中未使用此texture ,但为了完整起见,我希望将其包含在本文中。 要定义纹理,您可以包括texture: {path: 'yourtexturefilename.png'}

在演示中,我向场景中添加了七个不同的盒子/立方体,每个盒子/立方体高30像素,并在y轴上放置低31像素,以便它最初被虫洞隐藏。 它们的宽度略有不同,使它们看起来有点像灯泡。

我通过它们的x和z坐标将它们从虫洞的中心稍微移回了一点,但是老实说,如果-5使您感到烦扰,对于这些变量,将它们保留为0也可能很好。 我已经将它在y轴上旋转了45度,以便它在虫洞顶部以一个不错的角度面对。

awe.projections.add({
    id: 'ar_button_one',
    geometry: {shape: 'cube', x: 60, y: 30, z: 5},
    rotation: {y: 45},
    position: {x: -5, y: -31, z: -5},
    material: {
      type: 'phong',
      color: 0xFF0000
    }
  }, {poi_id: 'marker'});

每个'ar_button_{NUMBER}'的ID为'ar_button_{NUMBER}' ,其中数字是菜单按钮从下到上的索引。 我们将在对IFTTT的HTTP调用中使用此ID,因此保持这些一致性和准确性非常重要!

定义投影后,我们定义了AR拼图中一个相当重要的部分-标记检测事件。 我们将其添加为传递给函数awe.events.add()的数组。

awe.events.add([
    // Our events here
  ]);

我们只有一个awe.js事件,所以这里只有一个事件。 该事件定义了一个我们可以调用的ID。 我称它为'ar_tracking_marker' 。 我们定义了适用的设备类型。 到目前为止,在所有awe.js示例的仓库中这似乎都是相同的,因此我将其保留为PC和Android设置为1时的样子。

id: 'ar_tracking_marker',
  device_types: {
    pc: 1,
    android: 1
  },

然后,我们使用register()unregister()函数来添加和删除正在监视标记的事件侦听器。

register: function(handler) {
    window.addEventListener('ar_tracking_marker', handler, false);
  },
  unregister: function(handler) {
    window.removeEventListener('ar_tracking_marker', handler, false);
  },

然后,我们定义事件处理程序,一旦发现标记,该事件处理程序将运行。 我们会寻找“ 64”标记,并且仅在找到它时才运行响应。

handler: function(event) {
    if (event.detail) {
      if (event.detail['64']) {
        // Our response!
      }

在寻找标记的回应中,我们希望将我们称为'marker' POI与我们的物理纸质标记一起移动到现场,并使它可见。 我们使用event.detail['64'].transform将其转换为与物理标记对齐。

awe.pois.update({
    data: {
      visible: true,
      position: {x: 0, y: 0, z: 0},
      matrix: event.detail['64'].transform
    },
    where: {
      id: 'marker'
    }
  });

我们还将'wormhole'投影设置为可见。

awe.projections.update({
    data: {
      visible: true
    },
    where: {
      id: 'wormhole'
    }
  });

如果没有看到标记,但是菜单处于打开状态,则将其设置为保持打开状态,但隐藏虫洞。 这样做的主要原因是,随着光线的变化,标记可能变得难以辨认。 我们不想陷入无路可退的特定颜色!

else if (menu_open) {
    awe.projections.update({
      data: {
        visible: false
      },
      where: {
        id: 'wormhole'
      }
    });
  }

如果没有标记,并且菜单没有打开,则整个POI将被隐藏,等待我们查看。

else {
    awe.pois.update({
      data: {
        visible: false
      },
      where: {
        id: 'marker'
      }
    });
  }

最后,我们告诉awe.js更新场景。

awe.scene_needs_rendering = 1;

我们将要设置的实际功能的最后一部分是单击事件。 所有这些都在object_clicked事件内。

window.addEventListener('object_clicked', function(e) {
    // Our click events
  });

我们的click事件包含在e.detail.projection_id中单击的投影的ID。 我们使用switch语句来确定如何对点击做出反应。 单击虫洞可打开和关闭虚拟菜单,而单击虚拟菜单按钮将触发我们的浅色。 我们使用switch语句,因为每个按钮将运行相同的响应代码。

switch (e.detail.projection_id) {
    case 'wormhole':
      // Clicks to open and close our menu
    break;
    case 'ar_button_one':
    case 'ar_button_two':
    case 'ar_button_three':
    case 'ar_button_four':
    case 'ar_button_five':
    case 'ar_button_six':
    case 'ar_button_seven':
      // Clicks on our virtual menu buttons
    break;
  }

我们的蠕虫menu_open单击事件根据menu_open是true还是false来打开和关闭菜单。 如果为假,则使用awe.js awe.projections.update()函数对y轴上的每个按钮进行动画处理一秒钟。 这将其移出虫洞。 每个投影移动之间的唯一区别是每个对象在y轴上移动了多少。

if (!menu_open) {
    awe.projections.update({
      data: {
        animation: {
          duration: 1
        },
        position: {y: 35}
      },
      where: {id: 'ar_button_one'}
    });

否则,如果菜单已打开,则我们将它们全部移回蠕虫孔下的初始位置并从视图中隐藏。

else {
    awe.projections.update({
      data: {
        animation: {
          duration: 1
        },
        position: {y: -31}
      },
      where: {id: 'ar_button_one'}
    });

在if else语句之后,我们将menu_open切换为与之相反的位置,以便我们跟踪其位置。

menu_open = !menu_open;

在按钮单击事件中,我们向IFTTT发出HTTP请求,其中包括按钮的ID作为事件名称以及访问IFTTT服务的密钥。 我们实际上并没有使用返回的数据,而是将其记录到控制台以进行调试,但否则,实际结果来自IFTTT对HTTP调用的反应。

...
  case 'ar_button_seven':
    var request = new XMLHttpRequest();
    request.open('GET', 'http://maker.ifttt.com/trigger/'+e.detail.projection_id+'/with/key/yourkeyshouldbehere', true);

    request.onload = function() {
      if (request.status >= 200 && request.status < 400) {
        var data = JSON.parse(request.responseText);
        console.log(data);
      }
    };

    request.send();
  break;

毕竟,如果由于不兼容等原因导致awe.js无法加载,我们可以加载另一个脚本来显示错误消息。

{
    capabilities: [],
    success: function() { 
      document.body.innerHTML = '<p>Try this demo in the latest version of Chrome or Firefox on a PC or Android device</p>';
    }
  }

现在是HTTPS时间

截至2015年末的更新-我将跳回本文以添加一些相当重要的信息-Chrome现在要求使用相机的网页必须通过HTTPS进行投放。 因此,在尝试运行此服务之前,您需要找到一种通过HTTPS运行服务的方法。 到目前为止,我使用的一种测试方法是ngrok,它可以为您的本地主机提供HTTPS隧道。 我们在SitePoint的“ 从任何地方访问本地主机”中都有指南,可以帮助您入门。

演示在行动

如果我们在谷歌浏览器移动版上运行此代码并将其指向我们的标记,则会出现一个虫洞。

我们的AR虫洞出现了

如果我们单击虫洞,则菜单按钮应设置为正确的位置。

我们的虫洞打开并可见

如果我们单击菜单项之一…

在我们的AR菜单上选择红色

它应该改变我们LIFX灯的颜色!

我们的灯变成红色

结论

这是您使用awe.js在浏览器中开始使用增强现实时需要知道的一切。 就像当今科技界的许多发展一样,它具有巨大的潜力! awe.js团队一直在致力于插件的开发,很快就会有一个更新甚至功能更全的版本! 也可以设置一个Three.js立体效果以用于Google Cardboard,并将其与awe.js的某些功能结合起来,以构建AR耳机体验。 我认为一篇文章可能要花很多钱,所以请留意未来一篇文章!

如果您使用此代码尝试一些AR魔术或将其进一步研究,在注释中留下说明或在Twitter( @thatpatrickguy )上与我联系,我很乐意将其签出!

From: https://www.sitepoint.com/augmented-reality-in-the-browser-with-awe-js/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值