AR.js是一套运行在浏览器中的开源增强现实库,底层依赖WebRTC摄像头接口和WebGL渲染,配合A-Frame或Three.js等框架使用时,只需要引入一段CDN脚本,就能实现标记识别AR和基于地理位置的AR。相比需要安装原生APP的方案,它的部署成本几乎为零,用户扫码打开链接即可体验。本文将围绕CDN接入这一最常见的使用方式,讲清楚AR.js的能力边界、具体接入步骤以及常见问题的排查方法。

AR.js能做什么:两种核心模式的选择
AR.js最常用的有两种模式。第一种是标记追踪,也就是经典的图案识别,程序通过摄像头识别一张预先训练好的标记图,把3D模型固定在标记上方。这种模式定位稳定、计算量小,在低端手机上也能跑出接近60帧的流畅度,缺点是必须打印一张实体标记卡才能体验。第二种是地理位置AR,它借助GPS坐标和设备朝向传感器,在真实世界的某个经纬度位置上放置虚拟物体,适合做城市导览、景区打卡这类不需要实体标记的场景,但定位精度受手机GPS限制,误差通常在几米到十几米之间。
选择哪种模式,取决于你的业务场景。如果是产品展示、教育卡片、书籍配套内容这类需要精确贴合的场景,标记模式是首选;如果是线下活动、地图导览、虚拟签到墙,地理位置模式更合适。两种模式在代码层面互不干扰,也可以在同一个项目中并存。
需要说明的是,AR.js本身并不负责3D渲染,它是追踪层,真正画模型的是A-Frame或Three.js。所以通过CDN引入时,通常会看到两个script标签,一个加载渲染框架,一个加载AR.js构建产物,两者缺一不可。
通过CDN接入AR.js:从零跑通标记识别
最省事的接入方式是直接使用jsDelivr或unpkg提供的CDN地址。AR.js的构建产物按框架和用途分成了多个文件,标记模式配合A-Frame使用时,最常用的入口是aframe-ar.js。下面是一个可以直接保存为index.html并运行的最小示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<!-- 第一步:通过CDN引入A-Frame渲染框架 -->
<script src="https://cdn.jsdelivr.net/gh/aframe-io/aframe@1.3.0/dist/aframe-master.min.js"></script>
<!-- 第二步:通过CDN引入AR.js的A-Frame构建产物 -->
<script src="https://cdn.jsdelivr.net/gh/AR-js-org/AR.js@3.4.5/aframe/build/aframe-ar.js"></script>
<style>
body { margin: 0; overflow: hidden; }
</style>
</head>
<body>
<a-scene embedded arjs="sourceType: webcam; detectionMode: mono_and_matrix;">
<a-marker preset="hiro">
<a-box position="0 0.5 0" material="color: red;"></a-box>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>这段代码里有几个关键点。arjs属性中的sourceType设为webcam表示使用后置摄像头,detectionMode设为mono_and_matrix表示同时支持图案标记和条形码标记。a-marker的preset属性设为hiro,这是AR.js内置的一张默认标记图,你可以在官方文档中下载打印,用摄像头对准它,就能看到一个红色立方体悬浮在标记上方。
版本号是需要特别注意的地方。AR.js 3.x系列与A-Frame的兼容版本有对应关系,3.4.5版本建议搭配A-Frame 1.3.0或更早版本使用,如果你引入了最新的A-Frame 1.5.x,可能会遇到黑屏或模型不显示的问题。遇到这类情况,优先检查两个CDN地址的版本是否匹配,这是新手最常见的坑。
另外要强调HTTPS要求。浏览器的摄像头权限只在HTTPS环境下开放(localhost除外),所以如果你把页面部署在http协议的服务器上,getUserMedia调用会直接被拒绝。正式部署前,务必给域名配置SSL证书,或者使用GitHub Pages、Netlify这类自带HTTPS的静态托管平台。
地理位置AR的接入方式与注意事项
地理位置模式的CDN入口略有不同,它使用aframe-ar-theatre.js相关构建,核心实体是a-entity gps-new-camera和a-entity gps-entity-place。下面是一个最简示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<script src="https://cdn.jsdelivr.net/gh/aframe-io/aframe@1.3.0/dist/aframe-master.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.155.0/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/AR-js-org/AR.js@3.4.5/aframe/build/aframe-ar-nft.js"></script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false" renderer="antialias: true; alpha: true">
<a-entity gps-new-camera gps-camera-origin="latitude: 39.9042; longitude: 116.4074;">
</a-entity>
<a-entity gps-entity-place="latitude: 39.9052; longitude: 116.4084;">
<a-box scale="5 5 5" material="color: blue;"></a-box>
</a-entity>
</a-scene>
</body>
</html>gps-camera-origin指定观察者的初始坐标,gps-entity-place指定虚拟物体所在的经纬度,两者配合即可把蓝色方块钉在真实世界中。需要注意的是,移动端浏览器获取GPS需要用户授权定位权限,iOS的Safari对精确定位的触发时机比较挑剔,通常要在用户点击页面后才会给出高精度坐标,建议在页面上加一个开始按钮来触发定位流程。
精度问题是地理位置AR绕不开的话题。手机GPS的原始误差可能有十几米,如果需要更精准的贴合效果,可以配合AR.js的NFT模式使用,也就是通过自然特征识别真实场景中的图片或建筑立面。NFT模式的CDN入口是arjs-nft.js,它不依赖标记卡,而是识别任意图片,代价是性能开销更大,加载描述符文件也更耗时,适合对精度要求高但可以接受较长初始化时间的场景。
常见问题排查:黑屏、无识别、摄像头打不开
接入CDN后跑不起来,大概率是以下几类问题。第一类是黑屏,先打开浏览器控制台看有没有报错,最常见的报错原因是A-Frame与AR.js版本不匹配,或者CDN地址拼写错误导致脚本404。第二类是摄像头画面正常但模型不出现,这时候检查标记是否打印清晰,hiro标记必须保持原始比例不能拉伸,光照太暗也会导致识别率骤降。第三类是摄像头直接打不开,基本可以确认是HTTPS问题或者权限被拒绝,检查地址栏协议并在浏览器设置里确认摄像头权限状态。
还有一个容易被忽略的细节:a-scene的embedded属性。如果页面需要和其他HTML元素混排,必须加上embedded,否则A-Frame会以全屏模式渲染,把其他内容全部盖住。反过来,如果发现AR画面被压缩在页面一角,往往就是样式里给a-scene设置了固定的宽高,去掉尺寸限制改成全屏铺满即可。
最后说一下CDN选择。jsDelivr在国内的访问速度比较稳定,unpkg偶尔会出现加载缓慢的情况。如果你的用户主要在国内,也可以把aframe-ar.js下载到自己的服务器或对象存储上托管,文件体积只有几百KB,自己托管还能锁定版本,避免上游更新带来的兼容性问题。调试阶段多用桌面版Chrome的设备模拟,配合chrome://webrtc-internals面板观察摄像头流状态,能更快定位问题所在。