AR.js学习:基于Image Tracking的NFT URL设置问题

引言

最近在学习AR.js相关的知识,希望通过AR.js在web端实现AR(Augmented Reality)的应用。AR.js的网上教程较少,相对比较全的资料是官网的一个文档(AR.js文档,好像要FQ才能访问,目前没看到中文版本)。
熟悉AR.js的同学应该都知道,AR.js基于三种方式展示AR内容:

1)Image Tracking
2)Location Based AR
3)Marker Tracking

Marker Tracking是最常见的基于maker的AR显示方式,我今天要讲的是我学习使用Image Tracking的方式展示AR内容时,遇到的问题,以及解决方案。(这里就不详细介绍这三种的细节,大家可以到查看AR.js文档)

关键词:AR.js A-Frame Image Tracking nft url配置

Image Tracking简介

Image Tracking顾名思义,就是基于一张图片去展示AR内容,其实原理和基于Marker Tracking类似,都是根据图片的特性点识别图片并跟踪。AR.js集成了A-Frame和three.js两个框架,基于这两个框架都能实现Image Tracking。

图片要求

用于做Image Tracking的图片有一定要求,原则上图片越精细越好。推荐使用300dpi及以上的图片,72dpi的图片勉强可以,但是AR展示设备必须靠的很近,而且必须保持静止。

生成图片对应的Image Descriptors

AR.js官方提供了web工具,可以将图片转换成Image Descriptors,AR.js其实是根据生成的Image Descriptors做图片识别和跟踪定位的。
根据图片生成的Image Descriptors包含三个文件,分别为以.fset, .fset3, .iset为后缀名的文件。假设你生成的Image Descriptors文件名为:demo.fset, demo.fset3, demo.iset,那么你的Image Descriptors名字为demo(去除后缀名)。

官方Demo尝试

官方提供的基于A-Frame框架的Image Tracking例子,关键html代码如下:

蓝色线画出的分别是Image Descriptors文件所在URL路径(即nft url路径),和gltf格式3D模型的URL路径。Image Descriptors URL最后的trex为Image Descriptors的名字。
PS:测试运行官方demo非常顺利,只是有些慢,毕竟官方demo文件资源都是在国外服务器上。

部署自有web服务

部署官方demo到自有web服务器上,将以上蓝色划线的URL替换成自有的Image Descriptors路径和gltf格式的3D模型路径。

发现只替换gltf-model是可以的,但是替换掉nft的url之后,则demo运行失败,界面一直卡在

经过调试console的报错信息为:Error in loading marker on Worker 404。
确认是Image Descriptors文件加载失败,Image Descriptors文件URL访问失败导致。

问题定位

查看AR.js加载Image Descriptors文件源代码(aframe-ar-nft.js文件),发现Image Descriptors加载函数如下:

    var onLoad = function () {
        ar = new ARController(msg.pw, msg.ph, param);
        var cameraMatrix = ar.getCameraMatrix();

        // after the ARController is set up, we load the NFT Marker
        var regexM = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#()?&//=]*)/igm
        var reM = regexM.test(msg.marker);
        if (reM == true) {
            console.log('msg.marker=', msg.marker);
            nftMarkerUrl = msg.marker;
        } else if (reM == false) {
            console.log('basePath=', basePath);
            nftMarkerUrl = basePath + '/' + msg.marker;
        }
        console.log('nftMarkerUrl=', nftMarkerUrl);
        
        ar.loadNFTMarker(nftMarkerUrl, function (markerId) {
            ar.trackNFTMarkerId(markerId);
            postMessage({ type: 'endLoading' })
        }, function (err) {
            console.log('Error in loading marker on Worker', err)
        });

从源代码可以看出,如果我们指定nft的URL是以域名方式提供的,如官方demo的https://arjs-cors-proxy.herok...,则直接使用我们传入的URL;

否则,使用basePath + 我们传入的URL(msg.marker变量即为我们传入的URL)。
如果加载出错,则会使用console.log('Error in loading marker on Worker', err)打印出错信息。
调试程序发现,由于我部署的服务是localhost的:http://localhost:8088/test
,或者http://127.0.0.1:8088/test
非域名方式,所以走的是basePath + 我们传入的URL分支,打印出来的调试结果如下:

从打印结果看出,basepath值为http://127.0.0.1:8088而不是http://127.0.0.1:8088/test(test为我部署的web服务名称),导致拼接的ntf的URL路径错误。

问题解决方案

修改nft的URL如下图所示:

问题结论

AR.js(实际上是A-Frame)在处理nft的url和model url上存在差异,正确配置方式有如下两种:
1)html部署的web服务必须支持使用域名访问,且必须将ntf的url配置成Image Descriptors文件所在的完整的域名访问路径;
2)html部署的是本地web服务,采用127.0.0.1或者服务IP地址访问,则ntf和model的URL路径必须配置成相对路径,如上图所示。且nft的路径必须包含web服务名称,而modle的url路径则不包含web服务名称。

PS:感觉A-Frame这块处理的不是很合理,毕竟不是每个人一上来就有域名的服务器。在本地部署AR相关web应用(web服务只能用IP访问),而nft的url配置行为和model的url配置行为不一致,很容易导致错误。

model url配置更合理,支持绝对路径http://127.0.0.1:8088/test/trex/scene.gltf配置和相对路径trex/scene.gltf配置,无需指定web服务名称。

posted @ 2020-08-14 14:49  慕流  阅读(1859)  评论(2编辑  收藏  举报