前回のハンドトラッキングに引き続き、A-Frameのアップデートについてです。
A-Frame v1.1.0についてのブログを読んでみると、WebXR AR Moduleに対応と書かれています。
A-Frame 1.1.0 - AR, Quest 2 Support, hand tracking, compositor layers, immersive navigation – A-Frame
つまり、8th Wall WebやAR.jsなしでWebARができるようになったということですね。
まだドキュメントがあまりないのですが、試しに動かしてみたので紹介します。
webxrコンポーネントの使い方
A-FrameをARに対応させるためのコンポーネントがwebxr
になります。
https://aframe.io/docs/1.1.0/components/webxr.html
<a-scene>
にアタッチして使うコンポーネントで、Exampleに書かれている通りにHTMLを記述すれば作成済みのシーンがそのままARに対応します。
<a-scene webxr="requiredFeatures: hit-test,local-floor; optionalFeatures: dom-overlay,unbounded; overlayElement: #overlay;"></a-scene>
対応ブラウザについて
まず、Chrome for Androidで試してみます。
特に何もしなくてもARに対応しています。
A-FrameのWebAR対応、Androidだと普通にできてる。 pic.twitter.com/j8wwMxnvvj
— jyuko🐼 (@jyuko49) 2020年12月16日
次にiOS Safariで試します。
が、 ARモードに切り替えるボタンが表示されていません。
iPhoneだとSafariもChromeもARボタンが出なかった。
— jyuko🐼 (@jyuko49) 2020年12月16日
非対応なのか実装が足りないのかは調べる。 pic.twitter.com/D2dUlye4Xu
なぜ動かないのかは、WebXRへのブラウザ対応状況が関係ありそうです。
Can I useで確認してみると、Chrome for Android はWebXR Device APIを標準でサポートしていますが、iOS Safariはサポートしていません。そのため、iOSに対応させたい場合、現状ではA-Frame単体でのWebARは採用しにくいです。
iOSで動かしたい場合は、MozillaのWebXR Viewerを使うと、WebXR Device APIを利用できます。
動きますね。 pic.twitter.com/j489CyUFAg
— jyuko🐼 (@jyuko49) December 19, 2020
開発やテストには使えますし、インストールを促すフローにすればiOSも一応フォローはできますが、インプレッションは確実に落ちてしまうので、iOS Safariの対応が待たれます。
AR Hit Testの実装
ARでコンテンツの重ね合わせとカメラトラッキングができて、次にやることといえば平面(床)にオブジェクトを置くですね。
実現方法としては、AR空間へのHit Test(Ray Castともいう)を行って、平面と衝突する座標を取得する実装が一般的です。
WebXRにもHit Testを行う機能が用意されていて、A-Frameで利用することができます。
WebXR Hit Test Module
https://immersive-web.github.io/hit-test/
こちらを使うには、webxr
コンポーネントにrequiredFeatures: hit-test;
を記述する必要があります。先程のExampleを見返すと、既に有効になっています。
いよいよ実装・・・ですが、A-Frameのドキュメントには詳しい情報が書かれていません。
どこかにいい情報ないかなと探したところ、こちらの記事が大変参考になりました。
こちらに実装例もあります。
GitHub - stspanho/aframe-hit-test: A-Frame hit-testing example
超ざっくり説明すると、init()
に書かれた処理にて、ARモードを開始したときにイベント('sessionstart'
)が実行され、XRReferenceSpace
(XRSessionの座標系)とXRHitTestSource
(Hit Testに必要な資源・ハンドル)を取得しています。
毎フレーム実行されるtick()
にて、XRFrame.getHitTestResults()
でHit Testを実行して、空間との衝突があれば、XRHitTestResult.getPose()
でPoseを取得してpositionに反映みたいな感じです。
Hit Testを常に実行しているので、カメラを動かすと対象のオブジェクトも追従するような動きになります。
実際に試したものがこちらです。
動いてそうですね。 pic.twitter.com/knPqUru5SF
— jyuko🐼 (@jyuko49) 2020年12月18日
説明をぶっ飛ばしましたが、A-FrameではglTFモデルが読み込めて、VRMはだいたいglTFなので簡単に表示できます。Webで扱うので権利的に再配布OKのモデルを使った方がいいです。
ついでのついでに、A-FrameでglTFを扱うとマテリアルのテクスチャが黒っぽくなってしまうことがあります。というか、よくなります。
この現象については、A-FrameのFAQにも書かれていて、
document.querySelector('a-scene').renderer.Precision = 'mediump';
などの対処法があります。
他にも、three.jsで本件を議論しているIsuueが参考になります。
DOM Overlayの利用
ARで空間にオブジェクトが置けたら、次にやりたいのはアクションを起こしてARに作用するインタラクションですね。
A-Frameなので、JSのtouchイベントでエンティティのDOM操作を行えば・・・と思っていると、そうはいかないようです。
というのも、モバイルで没入型のXR(ARモードやVRモード)を有効にすると、touchイベントが取れないようでして、別の方法でイベントを発生させる必要があります。
そこでWebXR DOM Overlayです。
WebXR DOM Overlay
https://immersive-web.github.io/dom-overlays/
ARモードの画面上にUIを重ねて、clickイベントを発生させることでインタラクションを実行できます。
こちらの実装例も先程の記事から参照できます。
aframe/index.html at master · aframevr/aframe · GitHub
webxrコンポーネントのoptionalFeatures: dom-overlay;
で DOM Overlayが利用可能になります。
webxr="optionalFeatures: dom-overlay; overlayElement: #overlay"
overlayElement: #overlay
で重ねるDOM(HTML要素)を指定していて、
<div id="overlay"> <span id="greeting"> Hi, I'm the DOM Overlay </span> <button id="exit-ar">Exit AR</button> </div>
がOverlayするコンポーネントです。CSSでスタイルが定義されています。
さらに、ボタンを押したときの処理をA-Frameコンポーネントで定義しています。
<a-entity exit-ar-button="element: #exit-ar"></a-entity>
<script> AFRAME.registerComponent('exit-ar-button', { schema: { element: {type: 'selector'} }, init: function () { this.data.element.addEventListener('click', ev => { this.el.sceneEl.renderer.xr.getSession().end(); }); } }); </script>
A-FrameのEntity-Component-Systemが理解できていれば、難しくない処理です。
こちらを参考にして、押したらglTFのアニメーションを切り替えるボタンを作りました。A-Frame Extrasのanimation-mixerを使っています。
A-FrameでWebARからのglTFアニメーション切り替えまでできましたん pic.twitter.com/66qxeKYYkr
— jyuko🐼 (@jyuko49) 2020年12月19日
動画をよく見ないとわかりにくいかもしれないですが、画面の左下に"Change Animation"というラベルのボタンを表示していて、ボタンのタップでアニメーションが切り替わっているのがわかるでしょうか。
8th Wall Web、AR.jsとの使い分け
現状のA-Frameだと、Hit Testを用いたマーカーレスのARは作れますが、逆にマーカーを用いたARの実装が面倒です。
また、対応ブラウザで試したとおり、そのままだとiOS Safariで動きません。
上記が解決されるまで、AR.jsの出番はまだありそうです。
8th Wall Webに関しては、開発ツールとしての扱いやすさや曲面のイメージトラッキングなど独自の機能で有償である分の差別化を図ってきているので、A-FrameがiOSやイメージトラッキングに対応した後も利用シーンはありそうです。お財布と相談ですね。
まとめ
A-FrameだけでWebARができるようになりました。
iOS SafariはやくWebXR Device APIに対応してくれないかな。
ブラウザ/デバイス次第なのですが、将来的にはARとVRが切り替わるコンテンツができたら面白いなと思ってます。