BlenderとUnityとZapworksで作る 初めてのWebARアプリ開発
前回はBlenderとUnityとXcodeでARアプリを開発しました。スマホ端末にアプリインストールが必要なため、ブラウザ経由でARアプリを実行できたらと思い、今回はWebARアプリの開発にチャレンジしました。
※ この記事は、所属しているxRギルドのアドベントカレンダーに登録しています
はじめてのWebARアプリ
開発したアプリがこちらです。ARなので非現実感を出したくて、テーマとして「空に浮かぶ小島と幻想動物」を考えました。3DモデルはBlenderとSubstancePainterで制作しました。机やテーブルなど平面に「小島」を貼り付けたり、グリフォンを飛行させたりして眺めるデジタル模型です。制作期間は1週間でした (平日夜の2-3時間と土日)。
※ 下記のQRコードかURLからスマートフォンで実行できます。
1.1 WebARの実行環境をZapworksにしてみた
前回のARアプリ開発で利用したUnityのAR Foundationは、WebARに対応していない事がわかりました。最初は理解が難しかったのですが「AR Foundationは、AR関連のライブラリを提供しているが、WebGLによるモバイルアプリのサポートをしていない」という認識なのかと思いました。そこで、UnityのAR Foundation以外のライブラリを探すことと、WebARを実行できるサーバー環境を探しました。
調べる際の軸として「WebARアプリをUnityで開発したい」と「UnityでビルドしてWebARのプラットフォームにアップロードするだけにしたい」そして「年間コストを高くても2〜3万円以内に抑えたい」という点を重視しました。
選択肢として「8th Wall」とZappar社の「Zapworks」が挙がり、主にコスト面を比較した結果、Zapworksを選びました。理由は、仮にDeveloperアカウントで契約する場合は年間契約で65ドル、現在のドル円レート(1$=150円前後)であれば予算内の価格で収まる点。Unity向けのSDKが提供されていて、Unityでビルドしたzipファイルを管理画面からアップロードするだけでアプリケーションがWebに展開できる点が魅力的だったからです。
一方、ZapworksのUnity APIが提供するAR機能は、UnityのAR Foundationの豊富で強力なライブラリ群と比べると、ARに必要な要件を満たす機能が揃っているという印象でした。ドキュメントやサンプルもひととおり提供されていますが、決して充実しているわけではない印象でした。
なおトライアル期間は1週間です。この期間中はアップロード制限が50MBだったのでビジネスプランが適用されている様子でした。
1.2 ZapworksのAPIを活用したWebARの実装
BlenderとSubstancePainterで制作した下記の3DモデルをUnityにインポートして開発をしました。
Zapworksが提供しているUnity用のAPIがこちらになります。「Image Tracking、Face Tracking、Instant World Tracking」が利用できます。今回は平面検知をしたかったのでInstant World Trackingを利用しました。Unity AR Foundationの豊富なライブラリ群と比べると少し物足りなさを感じますが、APIは使いやすく実装も簡単なので、WebARで表現したかったことの要件は十分に満たしていました。
ZapworksのAPIは、込み入った設定がなくとても使いやすかったです。こちらのスライドを参考にセットアップしました。
例えば、Instant World Trackingで3Dオブジェクトを平面に着脱する際も、ボタンに下記のイベントを設定するだけで簡単に実現できました。この実装方法はこちらのTutorialに詳しく説明されています。
また、AR用のZappar CameraもUnity AR FoundationのXR Originと同じ感覚で利用することができました。開発の過程で、Zappar Cameraの位置情報をベースに、シーン内のオブジェクトを上下に浮遊するサンプルスクリプトを作ったのでGithubにアップしてみました。
また、Zapworksが用意しているサンプルやソースコードも公開されています。公開しているDocumentには書いてないので情報不足に感じますが、Githubに公開しているソースコードを入手して実行してみると、使いやすいリソースが見つけられました。
自分は、サンプルプロジェクトの影のシェーダーを活用して現実世界の平面に対して3Dオブジェクトが投影する影を表現しました。デフォルトでは影が濃いですが、UnityのDirectionLightのIntencityの値を0.4あたりにすると影が薄くなり、3Dオブジェクトと現実の融合感がして感動しました。
また、3Dオブジェクトを接地する際のポインタなどもサンプルに使いやすいアニメーションが梱包されているので、それを利用しました。
API DocumentにはAdvanced項目としてRealtime Reflectionsも提供されていました。アプリに設定してみましたが、金属的なマテリアルは使っていないので、今回に関してはあまり恩恵を感じられませんでした。
他に気になる機能として「Visual Positioning System(VPS)」というカメラ画像の解析による位置特定システムがあるようで、zapparの開発ブログで紹介されていました。こちらはWeb画面上で開発できる「Mattercraft」で実装しているようでした。現時点ではUnityのSDKには見当たりませんでした。
1.3 ビルドファイルの軽減
3Dモデルを平面に配置し、幻想動物の飛行モーションを実現し、簡単な操作用のUIを実装したあたりで、完成が見えてきました。しかし、UnityでBuildするとファイルサイズが40MBを超えるようになり、ビルドするだけで20分近くかかるようになりました。Zapworksの体験版はビジネスプランなので最大サイズは50MB。仮に契約するとしてDeveloperライセンスではアップロード上限は25MBなので、Buildファイルの軽減が必要になりました。
上記のサイトをヒントにUnityのEditor.logを調べたところ、3Dモデルのサイズが肥大化していたことがわかりました。原因はBlenderで使っているモディファイアだとすぐにわかりましたので、それを解決することで、最終的にBuildファイルを15MBに減らし、数分でビルドできるようになりました。
また、Buildファイルの軽減のため、SubstancePainterのテクスチャは最低サイズにしたり、不要なマテリアルはオフにしてテクスチャ画像を出力しないようにして軽減しました。
以上がZapworksを使ったWebARアプリ開発で体験したことです。そして以下はWebAR向けの3Dモデルを制作する上でのBlenderやSubstancePainterでの気づきやふりかえりです。
2.1 WebARを前提としたBlenderでの作業ふりかえり
「空に浮かぶ小島」ということで、情景を作る際にこちらの作品イメージを参考にしつつ、オリジナル要素を加えていきました。
今回の制作で最も学びになったのは「モディファイア適用時の頂点数の増加」でした。Blenderで3Dモデルを制作する際、モディファイアを利用することが多く、例えば地形を滑らかにしたりする際にサブディビジョンサーフェスを利用することがあります。一方、BlenderからUnityにFBXをエキスポートする際は、モディファイアを適用する必要があるのですが、モディファイアの設定によっては、適用した結果膨大な頂点数が発生します。
モデリングの際に、メッシュの数やメッシュ割には注意していたのですが、半ば手癖のように利用しているサブディビジョンサーフェスが、モディファイア適用によって膨大な頂点数を生成していることに気づいていませんでした。これに対して、Decimate(デシメート)モディファイアのUn-Subdivide(分割の復元)機能をつかって、表現が崩れない程度に分割を減らすことで、頂点数を大幅に減らす事ができました。
ただしこのデシメートの方法はその場しのぎの対策な気がして、本質的には「出力するデータのありかた」を策定した上でモデリングする必要を感じました。
自分の個人制作はこれまで映像制作がメインであり、Blenderで完結していたのでモディファイアを表現の1つとしかとらえていませんでした。しかし、今回の経験で、モディファイアはあくまでも中間的な処理であり、アウトプットを「画像としてレンダリングするのか」「メッシュ化してUnity用にFBXとして出力するか」によって、モディファイアをどう活用するかは違ってくると感じました。そこを考慮せず、つい手癖で「なめらかにしたいからサブディビジョンサーフェスをかける」となると、こういった問題に直面すると実感しました。
また、モディファイアに限らず、ベベルやスムースシェイドなどを適用すると、それ以前の状態にメッシュを戻せないので、例えばHoudiniのようにプロシージャルに3Dモデルを制作できると良いなと素朴に思いました。
これに関しては、BlenderのGeometryNodesでBevel NodeやSet Shade Smooth Nodeを設定し、完成してエキスポートする直前にインスタンスを実体化させるなどのプロシージャルなワークフローも模索してみたいと思いました。
2.2 UnityとBlenderのリグアニメーション互換性
UnityのAssetsにアニメーション付きの3Dモデルがあったので、グリフォンを動かしてみました。ゲームで使いやすくするためかLow Polyの3Dモデルで、単一のマテリアルに対して1枚の画像でテクスチャ表現をしていたので、表現したいイメージにあわせてメッシュを変更したり、マテリアルを再割り当てすることにしました。
また、リグアニメーションつきのUnityの3DモデルをFBXエキスポートして、Blenderにインポートした際、実行時にアニメーションが崩壊しました。原因はUnityとBlenderでウェイトペイントがズレていた事だったので、Blenderでウェイトペイントを塗り直しました。今回のアプリ開発で一番悩んだのは、UnityとBlenderのリグアニメーションの互換性についてでした。もっと効率的なデータの受け渡し方法があったのかもしれません。
2.3 Substance Painterのふりかえり
SubstancePainterは使い始めたばかりなので、テクスチャを作るだけで精一杯でした。SubstancePainterは一見すると、どんな質感でも着色できるように思えますが、実際にはきれいに作った3Dモデルにはうまく着色できる一方、メッシュ割やUVなどの品質が低い3Dモデルでは、いくらがんばってもきれいに塗れないことに気づき、自分のモデリングのクオリティの課題点を痛感しました。SubstancePainterのパフォーマンスやクオリティを左右するのは、BlenderなどDCCツールにおける3Dモデルのメッシュ割とUVが重要だと感じるほどでした。
また、SubstancePainter用の追加マテリアルやテクスチャをダウンロードできるSubstance 3D Assetsも必要と思い契約しましたが、それがあれば特殊な表現ができるわけでもなかったです。SubstancePainterは表現豊かなツールで、デフォルトでも十分機能を発揮できるし、多彩な表現も3Dモデルのクオリティ次第だと今回実感しました。
あと、SubstancePainter使っていて一番良いなと思ったのは、データの互換性です。BlenderにもShaderEditorで作ったシェーダーをテクスチャベイクする機能がありますが、1つ1つベイクする必要があり手間がかかります。SubstancePainterは様々なフォーマットにテクスチャを一括出力してくれるので、大変便利でした。
3.1 はじめてのWebARアプリで学んだこと
はじめてWebARアプリを作ってみて、一番良かったことは「3Dモデル制作から開始して、ゲームエンジンでの開発、プラットフォームへのビルドファイルのアップロードからパブリッシュし、実機で動作確認して遊んでみる」まで、一通りの制作工程を体験できたことです。特に、Blender, Unity, SubstancePainter, Zapworksと複数の要素をまたがることで、データの互換性や仕様のあり方をあらためて考えるきっかけになりました。
3.2 今後チャレンジしてみたいこと
無事に、トライアル期間の1週間で作りたかったWebARアプリが作れました。せっかくなので、ZapworksのDeveloperプランを年間契約しました。開発環境が充実してそうな8th WALLと最後まで悩みましたが、年額65ドル 日本円で1万円(11月末のドル円レート 1$ = 150円前後)だったのが決め手でした。
また、BabylonJSも少し試してみました。もともと「Unityで開発してビルドファイルをアップロードするだけにしたい」だったので今回はニーズに合わずでしたが、なにか別の機会に試してみたいと思いました。
今回のWebARアプリは眺めて遊ぶという目的でした。WebARはスマホがあれば実行できるので、もう少しビジネス的な課題解決を目的としたWebARアプリを作ってみたいと思いました。不特定多数の人が利用すると考えると、Zapworksのビジネスプランの年間コスト50万円に対するビュー制限数「12k views per year」は、ビジネス要件に応じてコストとビュー制限を検討する必要があると思いました。
WebARの実行環境に関してはホスティングサービスを使うとライセンス料が高いので、別の選択肢としてAWSのS3とCloudFrontを実行環境とすれば、コストをおさえつつビュー数の制限を緩和できるのではと思いました。
WebARは楽しいので、実行環境を含めて今後も模索していきたいと思います。