web ARで推しのライブのフラワースタンドを拡張した話

## はじめに
タイトルにもある通り、フラスタでAR演出をしてみました。

サーバのURLに飛んでARマーカーを読み取るとCGが重畳されるコンテンツです。
~~[ここから](https://fukakai3-fs-ar.sakura.ne.jp/)体験できます。~~
※無料サーバに移行しました：https://jocular-banoffee-80ae0c.netlify.app



完成品の動画は以下のようになってます。

https://twitter.com/lain_xr/status/1562427773255159818?s=20&t=szpkLokFFInFVuZ42mwEKg

これを実現するためのサーバ構築とAR部分のプログラミングを担当しました。

モデラーやイラストレーターなど非エンジニアの方でも手軽にweb ARを触ってほしいという思いからエンジニアからしたら簡単なことも含めて解説していこうと思います。逆にプログラマからしたら冗長に感じるかもしれませんがご容赦ください。

## 作るまでのいきさつ
まずなぜフラスタARを作ることになったのかを説明します。

まず初めに私の推しである[花譜(かふ)](https://kamitsubaki.jp/artist/kaf/)が**VTuber初の武道館公演**を行うことになりました。
公演の名前は**花譜3rd ONE-MAN LIVE「不可解参(狂)」** です。

本当に良かったので気になった人はアーカイブを是非ご覧ください。

https://twitter.com/kaf_info/status/1563360743067893760?s=20&t=f6ZJ9BOg3DmV48VDBnu37A

元々観測者（花譜が所属するKAMITUBAKI STUDIOのファンの総称）にはクリエイターが多いうえに、キャパたった1000人のLIQUIDROOMから始まった花譜の最初のライブ(行けたのはクラファン支援者なので人数は700人)から、今回は武道館に10倍の観測者が駆け付けます（ディスプレイを置く関係上武道館のキャパいっぱいまでは人が入れない）。
そんなこんなで多くのフラスタ企画が持ち上がりました。
私はその中の2つに参加しましたが、そのうちの1つが図らずも参加者約200人を擁するものすごい大きなフラスタ班でした。
すでにフラスタに飾るための装飾品を作るイラスト班と、3Dプリンタ班がいてびっくりしました（3Dプリンタ班ってなんだよ...なんで10人くらいもいるんだよ...）。

私も何かフラスタ関連で何か作りたい。しかし絵も描けないし、3Dプリンタもまともに扱えない。さらにライブのコンセプトに合わせて誰もやらないような狂ったことがしたい！と思っていました。
私の専門はxR(VR、AR,MRなど)で、xRコンテンツを開発できる人は少ないので他にやる人はいないと思いこれだと思いました。さすがに武道館に来た人にHMDをかぶせるわけにはいかないので、スマホで体験できるWeb ARを選択しました。
フラスタでAR表現をやってみたい旨を仲のいいフラスタ運営の1人に伝えたところ、その人がblender使いかつ、神椿公式のモデルが規約的にも使えることが分かり、実現できそうな手触りが得られたのでWeb ARをやることにしました。

## 制作フロー
以下の流れでフラスタARを完成させました。
カッコ内は担当者のイニシャルです。何も書いてない部分は筆者が担当しました。
大体2か月位の制作期間になりました。
実際はその間に院試などが挟まって忙しい時期もあったのでコアな実装期間は1~2週間くらいだと思います。
(今回制作にかかわったくれた人のほとんどが院試でしたｗ)

- プロトタイピング
- 制作会議＆要件定義（Fさん、Tさん）
- 先行事例の調査
- サーバ構築
- プログラミング
- モデルのアニメーション制作（Tさん）
- マーカー制作（Tさん）
- 最終調整
- 最終テスト（フラスタ参加者の方々）
※プログラミングと、アニメーションはほぼ同時進行でした。

### プロトタイピング
ここからは各フローの解説をしていきます。
AR(のみならずxRコンテンツ)は言葉で説明するよりまず体験してもらった方がいいので、こういうイメージのものを作りたいということを伝えるために、unityとSTYLYでデモ用のARコンテンツを作りました。STYLYはWeb ARではないですが、手軽に高品質なARコンテンツを作れるいいプラットフォームです。今回はSTYLYがメインではないのでプロトタイピング部分の技術解説は省きます。

https://youtube.com/shorts/Vt1ECc32rOc?feature=share

STYLYを使ったARコンテンツの制作経験はあったので、1時間くらいでデモは作れました。
モバイルバッテリーをフラスタに見立てて、直方体をその周りで飛ばすという暴挙にでましたが、まあプロトタイピングは最速でやりたいことのコアを実装するものなのでいいでしょう。
実際フラスタ参加者の方々にプロトタイピングを見せた時の反応は上々でこれで行けるという確信を得ました。

### 制作会議＆要件定義
筆者含め3人で具体的にどう作っていくのか会議をVRChatでしました。制作に必要なものは大きく、アニメーション付きモデル制作、プログラミング、サーバ構築の3点です。
アニメーション付きモデルは3人のうち一人がblender使いであった上に、フラスタの周りを飛び回る魚みたいなやつ(らぷらす)は公式が出していた（現在は入手不可）上に商用利用含めて利用可能だったためモデリングの手間は省けました。
プログラミングとサーバに関しては、筆者自身AR関係の知識はあるものの、Web ARを触るのが初めてだったのとサーバ周りの知識が乏しかったのでサーバ周りに詳しい人に聞いて、色々アドバイスをいただきました。
1人だと実現が難しいことでも共同制作なら実現可能になるのはいいですよね。（すり合わせは大変だけど）

現場に出たことがないうえに趣味でプログラムを書いてるので、ちゃんとした要件定義を分かっていないので簡単に確実に実装すべき項目を洗い出しました。

- 手軽に体験できること
- 数千人が来ることが予想されるので体験にかかる時間が短いこと
- QRコードは使えないこと
    - 一つの場所に人を滞留させないための武道館からの要請

これらの要件より、体験する人にアプリをインストールさせたり、マーカ周辺の特徴点を読み取らせたりする余裕はないと思い、事前にtwitterでマーカーとサーバのURLを共有し、マーカ方式によるARで行くことにしました。

https://twitter.com/kiske009/status/1562235700237709313?t=-tvhHsocZsknwh3Ztya1Hw&s=19

### 先行事例の調査
ここは実装に当たっては必須でないですが、大学で研究とやらをやらされているのと先人たちがどうやって実装しているかの確認のため行いました。
調べてみたところ先行事例はいくつか存在していて、[デレステ](https://togetter.com/li/1286571)や[にじさんじの委員長](https://twitter.com/arflowerstand/status/1203672861275148288?s=20&t=wPb7xVpTVgzdvhIPIOExEw)のライブなどでの事例がありました。

Web ARを使っているものがほとんどで、使っているプラットフォームは自前実装かLESSERのどちらかが多かったです。アニメーションはLive2Dやblenderで作られていました。
自前実装の場合はQRコードをマーカとして使っているものがほとんどでした。まあURLへ飛ぶのとARマーカとしての役割の2つを画像1枚でこなせるので非常に便利だからですね。今回武道館から要請が出なかったら筆者もQRコードをマーカにしようと考えていました。

### サーバ構築
今回は[さくらのレンタルサーバ](https://rs.sakura.ad.jp/?gclid=CjwKCAjwpKyYBhB7EiwAU2Hn2UVhs4kxrUVdsenHdOPPdHxBpSNRlv0byr91in4znhKYaqCyM4_FBBoCbqIQAvD_BwE)を借りました。
本当は自作サーバを立ててみたかったんですが、時間があまりないのと当日筆者も現地に行くため、保守ができないので見送りました。
レンタルサーバをさくらにしたのは、炎上したことはあるもの国産だから信頼できそうというシンプルな理由です。~~(サーバ何もﾜｶﾗﾝ)~~

サーバのサの字も知らなかったんですが意外と簡単でものの数時間でサーバを立てられました。

サーバ構築の手順としては**さくらのレンタルサーバのサイトで会員登録とレンタルの申し込みをする**→**FTPソフトをインストールする**→**サーバ内にファイルを入れたり更新したりする**というフローになります。

レンタルサーバはどれを使えばいいのかよくわからなかったのでとりあえずプレミアムプランにしました。結果的にサーバにあげたファイルサイズは数MBだったのでもう少し下のプランでもよかったかもしれません。
ちなみにサーバは最初の2週間は無料で試せます。

次に**FTPソフトのインスト―ル**についてです。
そもそもFTP(File Transfer Protocol)とは**ファイル転送プロトコル**のことで、プロトコルは取り決めのような意味なのでファイルをやり取りする際のルールみたいなものです。
ぶっちゃけFTPソフトを使うだけなら詳しい中身まで知る必要はないです。

無料で使えるFTPソフトはいくつかありますが、個人的なおすすめは**FileZilla**です。
お勧めする理由は手軽に利用できること、一度設定を済ませてしまえばワンクリックでサーバに接続できることです。また、いくつかのサイトではFFFTPがおすすめされていますが、FFFTPは**SFTP**という暗号化に対応したプロトコルを使えないのでセキュリティリスクが高いです。一方FileZillaはSFTPに対応しているので通信が暗号化されて第三者にファイルの内容が解読される可能性は低いです。

FileZillaの使い方や設定方法は書いてしまうと長くなってしまうため各自で調べてください。その際レンタルサーバの情報が必要になるのでコントロールパネルやレンタルサーバのプラットフォーマーから届いたメールを確認してください。
ただし、いくつかの箇所でつまったのでそれを共有します。

まずFileZillaでサーバ接続が確立されると以下のようにたくさんフォルダがでてきます。(左が自分のPCのファイル、右がサーバのファイル)
![Pcj4Gi4FD9bDYGq1661881092_1661881146.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517673/bd940226-e88a-c2e2-d087-7a3ceeb4618c.png)

最初、サーバに追加したいファイルをどのフォルダに入れればいいかわかりませんでしたが、**"www"** というファイル直下にファイルを追加していってください。

また、ここが一番はまった箇所ですが、**www直下にindex.htmlがないとForbbidenを返されるという罠があります。**
一応[この記事](https://help.sakura.ad.jp/rs/2214/?article_anchor=js-nav-6)によると設定を変えることで別のファイル名でも行けらしいですが特にこだわりがなければおとなしくindex.htmlを作りましょう。


また注意点としては、初歩的な話かつ当たり前ですが、ローカルファイルを更新してもFileZillaのファイルを差し替えなければサーバは更新されません。（~~これでファイル更新を忘れて何度か時間を溶かしました~~）

**プログラミング**
やっとプログラミングの章に入っていけます。（~~プログラミングはプログラミング以外の工程が存外に多い~~）
いきなりですが、まずはコードを載せます。
開発環境は**Visual Studio Code 1.70.2**です。

```php:index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>フラワースタンドAR</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover, shrink-to-fit=no" />
  <script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
  <script src="https://raw.githack.com/AR-js-org/AR.js/3.3.1/aframe/build/aframe-ar-nft.js"></script>
  <script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@v6.1.1/dist/aframe-extras.min.js"></script>

  <style>
    * {
      margin: 0; padding: 0;
    }

    body {
      overflow: hidden;
      cursor: none;
    }
  </style>

</head>
<body>
  <a-scene embedded arjs="debugUIEnabled: false" vr-mode-ui="enabled: false">
    <a-assets>
      <a-asset-item id="laplace" src="3Dモデルのパス"></a-asset-item>
    </a-assets>
    <a-marker type='pattern' url='マーカーのパス'>
      <a-entity gltf-model="#laplace" scale="4.5 4.5 4.5" rotation="0 -90 -270" animation-mixer></a-entity>
      <!-- x:親指 y:人差し指 z:中指 -->
    </a-marker>
    <a-entity camera></a-entity>
  </a-scene>
</body>
</html>
```

サーバの章でも言った通り、ファイル名はindex.htmlにしています。
本来は可読性を高めるために、cssとJavaScript(以下js)は別のファイルに記述すべきなんですが、そこまで長いコードではなかったのと[参考にしたサイト](https://blog.kimizuka.org/entry/2020/11/03/080000)がjsとcssとhtmlを一つのファイルにまとめていたのでこうしました。
普段web開発をするときはcssとjsは別のファイルに分けましょう。

軽くコードの解説をします。よくわからん！って人はコードのコピペをしてパスの差し替えとa-entityタグ内を調整してもARコンテンツが作れると思います。

まずコードはいくつかのブロックに分かれていて、styleタグで囲まれたとこがCSS(HTMLを装飾するコード)で、scriptで囲まれたところがjsのコードです。jsはサイトに動きをつけられる言語で現在作られているほとんどのWebサイトに使われています。
a-sceneタグ内でARの設定をしています。
今回はjsでARを扱うためのライブラリ（1から自分ですべて開発しなくて済むよう機能ごとにまとまったツールのようなもの）であるAR.jsとA-Frameを最初にscriptタグ内で読み込みます。

A-Frameの設定はa-sceneタグ内の間に記述していきます。
A-FrameはHTMLライクにARを手軽に扱えるライブラリで、Three.jsのラッパーです。
より細かい設定や高度なことがしたい場合はThree.jsを使う必要がありますが、今回はそこまで高度なことはしないため、A-Frameだけで済みました。

[A-Frame](https://aframe.io/docs/1.3.0/introduction/models.html)のドキュメントによると3dモデルの形式としは**obj**と**gltf**が扱えるようです。

どうやら"We recommend using GLTF"とgltfの使用が推奨されているっぽいですね。
そういうわけでアニメーション担当の方にgltfでの出力をお願いしました。

3dモデルの登録は**a-asset-item**タグでしていきます。id属性でモデルに任意の名前を付けられます。分かりやすい名前を付けましょう。
モデルのパスはsrc属性で登録します。index.htmlからの相対パスを登録してください。

次に**ARマーカ**を登録します。マーカ方式の場合type属性を**pattern**にしてください。
マーカのパスは3dモデルの登録と同じようにしてください。
ここで一点注意ですが、登録するマーカーはpngやjpgといった画像ファイルではなく**patt**方式です。詳しくはマーカ制作の章をご覧ください。

最後に表示する3Dモデルの調整を**a-entity**タグ内でしていきます。
先ほどa-asset-item内で命名したモデルをgltf-model属性で指定します。(gltf形式の場合)
モデルにアニメーションが付いている場合は**animetion-mixer**を忘れないようにしてください。
a-entity内で指定できるパラメータはたくさんあるので必要に応じて[A-Frameのドキュメント](https://aframe.io/docs/1.3.0/introduction/)に当たってください。
今回はscale属性でモデルの大きさを変え、rotation属性で向きを変えています。
blenderの座標系は鉛直上向き方向がz、奥行き方向がyとなっているのに対して、A-Frameは以下のようになっています。[(引用元)](https://kkblab.com/make/javascript/vr.html)（~~座標系を統一しなかった人類は愚か~~）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517673/e2ef4250-ba3e-1cf4-1b16-7f98208c196c.png)

あと、回転角に対して90°の倍数の回転しかしてないのに45°くらいモデルが傾いてしまうことがあるのですが、結局原因はわかりませんでした。なにか原因に心当たりがある方がいましたら教えてください。

ここまで書けたら忘れずにファイルをwww以下にアップロードしましょう。

### アニメーション制作
このパートは別の方が担当しました。
幸運にも3Dモデルは公式のものがあり、規約的にも使えたのでモデリングの手間が省けました。
モデラーの方はご自身のモデルが使えます。
モデリングめんどいって方は、[SketchUp](https://3dwarehouse.sketchup.com/)や[CGTrader](https://www.cgtrader.com/ja/free-3d-models)を覗いてみるとたくさん3Dモデルがあります。
素材を外部から持ってくる際は必ず利用規約を確認して遵守しましょう。

アニメーション担当の方に聞いたところ~~パス移動でアニメーションをつくったらしいです。~~(~~blenderなんもわからん~~)
訂正：パス移動するとgltfにアニメーションが同梱できなかったので、キーフレームを手打ちしたらしいです。お疲れ様です...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517673/445214af-34b3-97c5-4d98-a670db777998.png)

### マーカ制作
ARマーカは絵さえ用意できれば結構簡単に作れます。
おすすめはQRコードをマーカとして登録することですが、先に述べたようにQRコードは使えなかったのでARマーカ用のイラストを描き下ろしてもらいました。

ARマーカ用のイラストを描く際はいくつか注意点があります。
- 正方形であること
    - 長方形で作ると後述の変換サイトで強制的に正方形にされる
- 対称でないかつできるだけ複雑な絵柄であること
    - 対称であるとマーカを読み取る際に向きが一意に定まらないのと特徴点が少ないとマーカの認識精度が下がってしまう
    - 一応[このやり方](https://www.digital-transformation-real.com/blog/what-is-vuforia.html)でマーカの認識精度の評価をすることができます（必須ではない）


イラストが用意できたらARマーカに変換しましょう。
やり方は簡単で[こちらのサイト](https://jeromeetienne.github.io/AR.js/three.js/examples/marker-training/examples/generator.html)に画像をアップロードしてマーカと画像をダウンロードするだけです。
pattern ratioを変えることで黒い部分の割合を変更できますが、マーカを読み取る際はこの部分を基準にしているので黒い部分が細くなり過ぎないようにしましょう。またマーカを展示する際にも黒い部分に物が被らないようにしましょう。

プログラミングの章で言ったようにダウンロードしたpattファイルのパスを登録しましょう。
**ここまで来たらほとんどWeb ARコンテンツは完成です。**

## 最終調整＆テスト
あとはマーカーを設置して終了になります。
今回は当日にスタッフがフラスタそのものや装飾品を設置するということで実地テストができずいきなり本番を迎えドキドキしました。
当日の様子をシミレーションするため部屋でフラスタと同じ大きさの印を付けARの見え方を調整しました。
当日7000人もの人が武道館に来るため、体験してくれる人をその場にとどまらせないようにちょうど目線の高さにマーカーを設置するため、人の平均的な目線の高さである**155cm**の高さにマーカーを設置しました。また左右についてはちょうどフラスタの周りをらぷらすが飛ぶようにちょうど真ん中にしました。

一応前日にフラスタの参加者の方々にテストをしてもらいましたが特に不具合は見つかりませんでした。（サーバ側に不具合があった場合エンドユーザ側からはどうしようもないけど）

あとはサーバ障害に震えながら当日を待つだけですｗ

# 最後に
結果的に入場前は人が多すぎるのと入場のための流れができていたのでほとんどフラスタを見る時間はなく、しっかりフラスタを観れたのはライブが終わった後たった数十分でしたが合計で265人に386回ものアクセスをしていただけました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517673/9e9aa9b2-924d-32d2-bfd8-50f316f6340a.png)

やはりアプリのインストールの必要なくスマホさえあればだれでも体験できるWeb ARはいいなあと思いました。

次はロケーションベースARやGeospatialAPIを試してみたいです。

手順は多いが、Web ARはそこまで難しくはないので是非いろんな人に試していただきたいです。
そこかしこにマーカが貼ってあって色んなCGが飛び出す世界は面白そうです。
何か記事に関して質問や間違いなどがあればお気軽にDM(@lain_xr)やコメントを飛ばしてください。