じゅころぐAR

ARのブログ

8th Wall Webをthree.jsで動かす

何番煎じかわからないけど、試してみました。
一応、"Webエンジニア/ARがちょっとできるフレンズ"でやっているので。

8th Wallとは

8th Wall社のARプラットフォームで、8th Wall XR for Unity(Unity SDK)、8th Wall Web(Web SDK)が提供されています。

8th Wall | Augmented Reality

この記事では、8th Wall Webにフォーカスを当て、8th Wall XR for Unityにはちょっと触れる程度にします。

8th Wall XR for Unity

Unity開発者向けのSDKです。Uniry向けにはARKit、ARCoreのSDKがありますが、対応デバイスは一部に限られます。特にARCoreは対象ユーザがまだ少ない印象です。
8th Wall XR for Unityでは、ARKit/ARCoreに対応している場合は利用し、ARKit/ARCoreに対応していないデバイスでも8th Wall SLAMと呼ばれる独自のライブラリで機能を実現しているため、より多くのデバイスで実行ができます。
その代わり、ARKit/ARCoreと比べると、提供される機能は6-DoFトラッキング、HitTestなどの基本的なものになります。

8th Wall Web

WebGLでARを実現するJavaScriptSDKです。Webの利点として、アプリをDLせずにユーザをコンテンツに誘導できるところが大きな差異になります。
開発者視点では、ARコンテンツをA-Framethree.jsSumerianで作成することができるところもARKit/ARCoreと異なります。

対応デバイスについては、閲覧するブラウザに必要な技術要素がRequirementsに記述されています。
これらに対応したブラウザはCan I useなどでチェックできます。

WebGL - Can I use
getUserMedia/Stream API - Can I use
DeviceOrientation & DeviceMotion - Can I use
WebAssembly - Can I use

モーションセンサーについては、こちらのエントリが話題になってますね。
iOS 12.2でWebVRとWebARが半ば終わった件について - Qiita

余談(WebARとiOS Safari

Webの新技術はGoogleMozillaが先行してブラウザに実装し、AppleSafariにいつ実装するかで市場が動く傾向にあります。

WebGLiOS Safariで使えるようになったのはiOS8(2014年9月)で、MozillaがA-Frameを発表したのが約1年後の2015年12月。当時ARと全く無縁だったWebエンジニアの私がthree.jsを触りだしたのもこの時期からです。
Mozilla、WebVRコンテンツ開発フレームワーク「A-Frame」を発表 | OSDN Magazine

getUserMediaやWebAssemblyはもっと最近で、iOS11(2017年9月)から。 8th Wall Webが発表された時期を調べると、そこから1年後の2018年9月でした。
1つのアプリで複数対応 ARクロスプラットフォーム『8th Wall XR』 | MoguraVR News - VRの「いま」を掘りだすニュースメディア

・・・というように、Safariの機能実装から1年後くらいに3rd PartyのSDKやプラットフォームが登場する流れは感じてます。

で、次の重要なイベントはというとWebXR APISafari対応です。iOS13で発表されたらいいなと思いつつ、過去の感じからするとiOS14 or 15あたり(2020年9月-2021年9月)と予想しています。
WebXR API - Can I use
WebXR Device API

なお、余談の余談でARと直接関係ないですが、WebP(.webp、ウェッピー)もずっとSafariでの実装待ちです。こっちはiOS13で来てほしい!!
WebP - Can I use
WebP - Wikipedia

8th Wall Webを使う

前置きはこれくらいにして、実際に8th Wall Webを利用して評価してみました。

料金

まず気になるのは料金ですよね。
8th Wall - Pricing

Freeプラン

Web Developer向けにもFreeプランが用意されています。ただし、1,000 View/Monthの制約があり、ローカルでしか利用できません。

試しに使った感じだと、実機デバッグでトライ&エラーしないと動作が読めない部分があり、約3日の利用で150 Views近くに達していました。
個人利用でも注意しないと超えそうな範囲かなと思います。

f:id:jyuko49:20190422225452p:plain

Proプラン

$99/Monthの固定費 + Viewに応じたCPV Feesという料金体系になっています。

Freeプランと異なり、自身のサーバにホストできるので、$99/Monthの固定費はその分のコストと考えればよさそうです。CPV Feesの方はView(PV)にかかるコストで、ボリュームディスカウントになっています。

金額感を掴むために、Viewが一定量に達した場合の総コストを出してみました。

Monthly Views Total Costs
2,000 $99
10,000 $499
100,000 $2,749
1,000,000 $11,749

2,000PVまでならCPV Feesは無料で固定費の$99で使えますが、有料のレンジに入るとまあまあいいお値段です。
2019/4/22時点の為替レートだと、1万PV/月で約5.6万円/月、10万PV/月で約30万円/月ですかね。100万PV/月だと料金も100万円/月を超えます。

使い方

公式のチュートリアル通りに行えば、問題なく動きます。

Tutorialと順序は逆になりますが、先にWorkspaceでやることの一覧です。
8th WallのWebコンソールにログインして作業します。

  • Web Appの作成
    • App名を入れるだけ
  • APIキーの取得
    • Web App登録したら自動で発行されている
  • テストデバイスの登録
    • "Device Authorization"ボタン押して、表示されるQRコードをデバイスで読み取る

準備ができたら、Githubからサンプルプロジェクトをcloneしてローカルで動かします。

github.com

Macで実行する場合のコマンドは以下になります。
※Node.js、npmはインストール済み

# git clone https://github.com/8thwall/web.git
# cd web
# cd serve
# npm install
# cd ..
# ./serve/bin/serve -d examples/threejs/placeground/ -p 7777

実行すると、port:7777でローカルサーバが起動します。

f:id:jyuko49:20190422232054p:plain

QRコードも表示されるので、こちらからアクセスも可能。

f:id:jyuko49:20190422232200p:plain

上記に登録したデバイスでアクセスすると、公式のデモと同じサンプルアプリが開きます。

試作(three.js)

three.jsで何か作ってみます。

A-Frameでもよいのですが、three.js/examplesが充実しているので、A-Frameが必要な用途以外ではthree.jsをメインで使っています。

VRM

three.jsサンプルのTap to place(placeground)は、タップした位置にglTFモデルの木が生えます。
このモデルのパスはindex.js内で定義されています。

const modelFile = 'tree.glb'

VRMはglTFベースなので、モデルをVRMファイルに置き換えると普通に表示されます。

使ったVRMは、以前の記事にてクエリちゃんSDモデルのFBXファイルをUniVRMでエクスポートしたものです。
three.jsでWebVRを行うための基本的なところ - じゅころぐAR

MMD

three.jsでいつもやってるMMDのAR表示です。お借りするモデルによって利用規約もありますし、Freeプランはどっちみちローカルでしか使えないので、個人で遊ぶ用です。

MMDモデルはもぐ式りなをお借りしました。かわいい。
3d.nicovideo.jp

必要なthree.jsのライブラリはindex.htmlの<head>に追記で読み込めます。

<script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/libs/mmdparser.min.js"></script>
<script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/libs/ammo.js"></script>
<script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/TGALoader.js"></script>
<script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/MMDLoader.js"></script>
<script src="//cdn.rawgit.com/mrdoob/three.js/master/examples/js/effects/OutlineEffect.js"></script>
...

スクリプトもthree.jsと同じ感覚で書けるので、three.jsのexamplesを参考にして実装しています。詳細は割愛。
three.js/webgl_loader_mmd.html at master · mrdoob/three.js · GitHub

Image Targets

画像検知も試してみました。

マーカーとなる画像はWebコンソールのWorkSpaceから登録します。My Web ApplicationsでAppを選択すると、APIキーの下に"IMAGE TARGETS"ボタンがあります。

f:id:jyuko49:20190423003044p:plain

画像をドラッグ&ドロップでアップロードすると、NameMetadataを自由に編集できます。
設定した値は、後述するリスナにてdetailとして渡され、detail.namedetail.matadetaで取得できます。

f:id:jyuko49:20190423003613p:plain

画像を登録したらスクリプトの実装になります。

画像検知のイベントを受け取るには、XR.XrController.pipelineModule()のDispatched Eventsに対するリスナを登録すればよく、リスナはXR.addCameraPipelineModules()で定義できます。

サンプルに倣うと、placegroundScenePipelineModule()returnでリスナを登録して、XR.addCameraPipelineModules()に結果を渡す形になります。

  return {
    // Pipeline modules need a name. It can be whatever you want but must be unique within your app.
    name: 'placeground',
    listeners: [
      {event: 'reality.imagefound', process: onImageFound},
      {event: 'reality.imageupdated', process: onImageUpdated},
      {event: 'reality.imagelost', process: onImageLost},
    ],

試しに画像を検知したら、画像のnameをポップアップ表示する処理を書いてみます。

  const onImageFound = ({name, detail}) => {
    alert(detail.name)
  }

画像の検知と登録した情報の取得ができています。

あとは、onImageFoundでモデルを読み込んで、onImageUpdatedで追従、onImageLostでモデル削除の処理を書いてあげれば実現できます。

Tips

カメラモジュールのライフサイクル

8th Wall Webのthree.js実装では、CameraPipelineModuleのライフサイクルに対して、メソッドを定義することでARコンテンツが動作するので、この動きを理解してからは実装やデバッグが楽になりました。

onStart -> onCameraStatusChange (requesting -> hasStream -> hasVideo) -> onProcessGpu -> onProcessCpu -> onUpdate -> onRender

一例として、レンダリング時にeffectをかける処理は、onStartで開始したループ処理ではなく、onRenderに記述することで動作しました。

onRender: () => {
  effect.render(_scene, _camera)
}

まとめ

8th Wall Webの利点

  • Webブラウザで動作するため、アプリ不要
  • 幅広いデバイスでAR体験が提供できる
  • 比較的手軽に使える
  • three.js、A-Frameで開発ができる

対象デバイスが広く、WebサイトやQRコードからスムーズにARコンテンツに誘導できるため、WebARの特性を活かした製品になっていると思います。
個人的には、three.jsの資産やノウハウを活用できるメリットが結構大きいです。

8th Wall Webの課題

  • 大規模に使うと利用料の負担が大きい
  • アプリに比べて体験の質が低い

体験の質について、ARKit/ARCoreで開発していた感覚からするとラッキング精度は正直よくないです。少し動いただけでもコンテンツの位置がずれてしまうため、見せ方に工夫が必要になりそうなのと、ユーザが動き回るようなコンテンツはそもそも厳しい感じがします。
また、ARKit/ARCoreと比べて、そもそもの機能が少ないです。

どう活用していくか?

現時点でできるだけ多くのユーザにARサービスを提供したいとなると、有力な選択肢になり得ます。
ただ、決して気軽に使える料金ではないのと、提供したいユーザ体験の質に耐えうるかは、Freeプランでしっかり評価した方がいいと思います。

開発に必要なスキルはthree.jsやA-Frameに強く依存しつつ、8th Wall Web独自のAPIについても学習コストが多少発生します。先にthree.js、A-Frameを触ってからでないと独自の仕様に混乱するかもしれません。
逆に、three.js、A-Frameの経験者には使いやすいSDKです。

最後に将来性に関して、余談で少し触れたWebXR APIが標準化されてiOS Safariでも動作するようになると、Web SDKは役目を終える可能性が無きにしも非ずです。といっても1-2年は動きがないと思うので、この間にシェアを獲得できるかが分岐点になりそう。
製品に組み込む際には、将来的なSDKの置き換えも視野に入れておいた方が無難かと思います。