みなさん初めまして!
2019年からGUNCY’Sでエンジニアをしている古荘です。
この記事では、先日まで携わっていたVR法人HIKKY様のWebARコンテンツ「ARTANA」で使われている技術について、jsartoolkit5の今年1月にアップデートされた内容を中心に少しだけご紹介します。
WebAR?
WebARとは、ブラウザ上で体験するARコンテンツです。対して、近年話題になった「Pokémon GO」などの個々のアプリ上で体験するARはネイティブARなどと呼ばれます。
ブラウザを使う一番のメリットとしては手軽さです。ネイティブARと比べ、アプリケーションごとにダウンロード・インストールする必要がなく、URLにアクセスするだけで体験できます。一方、デメリットとしては、ネイティブARほどの複雑な処理が難しいことや、WebAR関連の公開されているライブラリがネイティブARに比べて少ないことなどが挙げられます。
WebARにもいくつか種類があるのですが、携わった案件に適しているのはスマホで行うマーカー型のWebARでした。マーカーとは目印となる画像です。今回は、カメラなどを使ってブラウザに映した現実の映像にマーカーが映っていればその上に3Dモデルを重ねて表示させます。
著名なマーカー型のWebARライブラリ
マーカー型のWebARライブラリは、マーカー認識・追跡(以後認識と書いた場合認識・追跡を指します)ライブラリと3Dレンダリングライブラリなどの組み合わせで出来ています。なお、マーカーの「認識」は直前のフレームで検出できていなかったマーカーを検出することを指します。「追跡」は直前のフレームで検出できた場合に、その位置情報などを基に次のフレームでマーカーを検出することを指します。マーカー型のWebARライブラリで代表的なものは以下の2つです。
ar.js
2017年に公開されたオープンソースのライブラリで、以下の2つのライブラリが用いられています。
- jsartoolkit5 : マーカー認識
- three.js : 3Dレンダリングライブラリ
jsartoolkit5はartoolkitというネイティブのマーカー認識ライブラリの一部をJavaScriptでも扱えるようにしたものです。2019年に調べたとき、jsartoolkit5はどんなマーカーでも認識できるわけではなく、黒枠(または白枠)で囲まれたマーカーだけが認識ができました。黒枠を用いてマーカー認識を行う範囲を狭めているため、処理が軽いです。
8th wall Web
2018年ごろに公開された8th wall社の有料ライブラリです。独自のマーカー認識ライブラリと、以下の5つのうちいずれかの3Dレンダリングライブラリを組み合わせて使います。
- A-Frame
- Babylon.js
- three.js
- Amazon Sumerian
- PlayCanvas
こちらはar.jsと比べて枠なしのマーカーでも扱えます。SLAM(自己位置推定と環境地図作成)によるマーカーの位置の補正なども行える、非常に高機能なWebARです。
今回取った戦略
jsartoolkit5 + 自社製3Dレンダリングライブラリ
開発期間なども考慮の上、初めに3Dレンダリング部分は自社で開発しているWebGLエンジンを使うことを決め、それに合わせる形でマーカー認識としてjsartoolkit5を試すことに決めました。
まず、自社製のWebGLエンジンを選んだのは使い慣れているのが非常に大きい理由です。他人のライブラリだとカスタマイズがやりにくく、バグなどの対応は非常に大変です。
一方、マーカー認識ライブラリでjsartoolkit5を選んだのは、ar.jsというWebARのオープンソースの前例があるというのが決め手です。8thwallはソースコードが確認できず、開発の見通しが簡単に立てられなかったため(体験版を使おうにも自分の端末と相性が悪いのか登録ができませんでした…)、採用しませんでした。
また、jsartoolkit5を選んだ理由はもう1つあり、フォークされたブランチでとある開発が終了に近づいていた点です。次に説明するそれは、運よく自社製WebGLエンジンとjsartoolkit5のを組みあわせる部分の実装が終わるころに実装されました。
枠なしマーカーに対応したjsartoolkit5
2020年1月、WebAR界で大ニュースが。
Finally #NFT (Natural Feature Tracking) a #markerless technology for #AugmentedReality is in the master branch of #jsartoolkit5 #ArtoolkitX repository! This is a great step for the #opensource! Many thanks to all the people involved in this process! https://t.co/dU0IglV2VC
— Walter Perdan 🇺🇦 (@kalwalt) January 21, 2020
Walter Perdan(Kalwalt)さんらの貢献により枠なしのマーカーの認識(Natural Feature Tracking、NFTと呼ばれます)に対応するアップデートが行われました。ライブラリとしては、枠なし部分の使い方は枠ありとほぼ同じになっており使いやすい設計です。実装が簡単なこともあり、案件ではこちらの枠なしマーカー認識を用いました。
ただ、以下で説明するように枠ありと枠なしで大きく異なるところもあります。
枠なしマーカーの解析・注意点
jsartoolkitによるマーカーWebARでは、開発段階でマーカーの特徴を解析して、Webでの実行時には解析したデータを用います。解析と言っても、ユーザーはソフトを使うだけです。枠ありマーカーの場合はAR.js Marker TrainingというWebサイトで解析、結果をダウンロードできました。
枠なしのマーカーの場合、NFT-Marker-Creatorを用います。Web版もありますが、画像が大きい時に効率的に検出できないため、GitHub版をオススメします。GitHub版の使い方は以下の通りです。
- NFT-Marker-Creatorを "git clone"
- root で "npm install"
- マーカーとしたいpng or jpg画像を root 以下に置く(jpgを使う場合は後述の注を参照)
- root で "node app.js -i (画像のパス)" を実行
- 解析が終わるまで待つ(画像によっては数時間かかります)
試しに以下の画像を解析すると…
以下のように出力結果が出てきます。
注目すべきは赤線を引いたConfidence levelで、画像の認識のしやすさを表しています。最高値が5.0で、上の非常においしそうなラーメンの画像はマーカーとして最適なことがわかります。
一方、Confidence levelが1や0だとマーカーとしてうまく機能しません。枠なし対応といってもどんな画像でもマーカーとしてうまく機能するわけではなく、機械にとって都合の良い特徴が少ない画像はうまく機能しません。どんな画像が良いかについてはCreating good markersにまとめられています。
出力結果が表示されると、入力画像と同名のfset,fset3,isetのファイルが root/output 内に作成されています。この3つが解析結果を保存したファイルで、Web上でjsartoolkit5のAPIを用いて枠なしマーカーをロードする際に使います。
注)マーカーとしたい画像がjpgの場合は、以下のように画像の縦横とDPIを入力する必要があります。DPIは元画像のものでなくても問題ないようです。設定したDPIによってモデルの大きさが変わります。
iPhone 6sで60fpsを実現する
アップデートにより枠なしマーカーに対応したjsartoolkit5ですが、枠なしマーカー認識の計算コストは枠ありに比べて断然上がります。1月のアップデートではwebassembly(wasm)対応により実行速度が上がっていますが、それでも枠ありと同じ実装で60fpsを実現するのはスマホ(手持ちのiPhone 6s)では厳しい…。
ボトルネック
今回のマーカーWebARで特に時間のかかる処理は以下の2つです。
- (3Dモデルの)レンダリング
- マーカーの認識
マーカーを一度見つけた後は「追跡→レンダリング→追跡→(以降ループ)」というように処理が続きます。60fpsを実現するためには、1回の[追跡 → レンダリング] に掛けられる時間は長くても1000 / 60 ≒ 16.7(ms)です。
ここで、jsartoolkit5内のサンプルで使われているpinball markerの追跡にかかるパフォーマンスを見てみましょう。検証環境はintel core i7-7700HQのCPUを搭載したWindows 10のChromeです。
ARController.processで追跡が行われているのですが、おおよそ12ms以上かかっています。スマホよりもスペックの高いPC環境ですら16.7msの大半を埋めてしまうのは致命的です。
workerスレッドを用いた並列処理
追跡とレンダリングで処理を独立させられるので、複数スレッドによる並列処理が行いたい… そこで、workerの出番です。今回の場合は、メインスレッドが毎フレームカメラに映る画像のデータを別スレッドに送ることで、12msかかるマーカーの追跡を別スレッドに任せることができます。必要な画像データの用意にかかる時間は長くとも4ms程度(以下の画像のgetImagedata)で12msに比べると圧倒的に短く、60fpsを実現できます。
終わりに
jsartoolkit5も、新機能によって上のARTANAのデモのようにスマホブラウザで60fpsでの枠なしマーカーを用いたwebARが可能になりました。
ただ、この枠なしマーカー認識には以下のように改善の余地がまだまだあります。
- NFTマーカー1枚の認識ですら処理が重く、電力消費が激しい
- NFTマーカーを利用する準備の処理の時間が長い
- 表示位置の補正機能がない
処理の軽量化にはオリジナルの画像認識ライブラリの開発などが、位置の補正にはSLAMや最適なフィルターの導入などが考えられ、弊社では今後も開発を続けていきます。
「最近のマーカー認識の威力はまだまだこんなもんじゃないよ?俺が(私が)開発して見せてやるよ」という一緒に働きたい方などいらっしゃいましたら、是非お問い合わせからご連絡ください。
WebARのコンサルティングもお待ちしています!