AR年賀状をつくってみた。

いろいろ試行錯誤したので、自分でも忘れないように書いておきます。

環境は、
・Macbook Pro
・OSは、Mojave 10.14.6
・Blender2.82
です。

完成したのはこちら。

![ogp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/c23862c3-0c7a-9502-2dfb-4268996df4d6.png)

![ARnengajo_dousa2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/e2e84a92-1f94-212b-3873-08895ee02f03.gif)

タイトルは、AR年賀状「風」。
平面を検知すると、AR年賀状が出現。**凧揚げをしている人のアニメーションが動いているAR**です。

+ iOS Safari、Android Chromeで見る：
https://namikawasusumu.net/ar/
※iPhoneの方はSafariで、Androidの方はChromeで上記URLを開いてください。

+ Facebookアプリで見る：
https://www.facebook.com/fbcameraeffects/tryit/152838536348547/

+ Instagramアプリで見る：
https://www.instagram.com/ar/152838536348547/

今回は、iOS Safari、Android Chrome/Facebookアプリ/Instagramアプリで見られるようにしました。
3DアニメーションのARで、マルチプラットフォームでつくった例を探してもあまりなかったので、これから挑戦する人の参考になればと思います。

## 最初に

ARで最初の分岐点が、
**マーカー付きARか、マーカーレスARか。
アプリでやるか、Webでやるか。**
という話になることが多く、まずは、その話を。

マーカー付きARのマーカーというのは、
![marker2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/2d3873a9-abdc-c8ce-29b6-c52f538d59a4.png)
こんなやつですね。

これが紙の上についていて、それにスマホカメラをかざすと、ARが出現する、というものです。
マーカー付きARの進化形として、画像認識をして、その上にARが現れる、というものもあります。

一方、マーカーレスARというのは、平面や、壁、位置情報(ロケーションベース型ARと言われる)を検知して、ARが出現するものです。マーカーがいらないのは、手軽ですよね。今回は、**マーカーレスAR（平面検知）**を実装したいと考えました。

次に、
**アプリでやるか、Webでやるか。**

これは細分化すると、

**1. Web**・・・iPhoneのSafariやAndroidのChromeで動くようにする
**2. 独自アプリ**・・・ARが動くアプリを開発する。
**3. 既存アプリ**・・・既存アプリ上で動くようにする。

という分類になります。

さらに既存アプリには、
「styly」や「Adobe Aero」などの**AR/VR専用ビューワーアプリ**を使う
あるいは、**「Facebook」「Instagram」上のAR機能**を使う
という選択肢があります。

お手軽なのは、Webですが、FacebookやInstagramの利用も、SNSでのシェアに重点を置いているなら、有力な選択肢になると思います。

今回は、**WebAR**による実装を目指しました。（が、後述しますが、FacebookやInstagram上のAR機能による実装も行いました）

## 実装手段

今回の条件は、

+ **マーカーレスAR（平面検知）**
+ **WebAR**

です。あと、趣味でつくるものなので、お金もできるだけかからないほうがありがたい。

WebARの選択肢としては、

+ AR.js
+ 8th wall
+ model-viewer/iPhone Quick Look/Android Scene Viewer**

などがあります。

AR.jsは、Javascriptで書けるので、心惹かれたのですが、平面検知ができないので、今回は外しました。年賀状が、空中に浮いた感じになっちゃうのは、いやだなと・・・。AR.js、画像認識とかどんどん進化しているようなので、今後に期待です。

8th wallは、機能だけみると、めちゃくちゃ良さそう。でも、そこそこお高いんです。従量課金制なので、閲覧数が増えるほど、お金がかかります。仕事で使うなら有力な選択肢かもしれませんが、今回は趣味なので、外しました。
（22/01/02 11:49追記）
8th wallには、非営利プランもあります。とはいえ、基本利用料はかかりますが、選択肢のひとつだと思います。

+ **Quick Look**・・・usdzという独自フォーマット（ピクサーがつくったらしい）の、iPhone　Safari用の簡易ビューワープログラム。
+ **Scene Viewer**・・・Googleが開発したARCore搭載Androidのブラウザで、ARファイル（glTFなど）を開くことができる簡易ビューワープログラム。
+ **model-viewer**・・・iPhoneのSafariならQuick Lookを、ARCore搭載AndroidならScene Viewerと、自動で判別して開くハイブリッド的な簡易ビューワープログラム。

つまり、model-viewerを使えば、iPhoneにもAndroidにも対応できるということで、今回は、**model-viewerを使うことにしました。**

model viewerについては、こちらも参考にさせていただきました。
https://webar-lab.palanar.com/developer/model-viewer/

## 3Dアニメーションをつくる

3Dアニメーションをつくるには、ざっくり２段階あります。

＜STEP 1＞ 3Dの物体（オブジェクト）をつくる
＜STEP 2＞ 動き（アニメーション）をつける

僕はBlenderを使っているので、今回は、物体成型からアニメーションをつくるところまで、Blenderで行うことにしました。

![Blende1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/fd1d6aea-778d-535c-7df2-992d4dc89e59.png)

３Dモデルをつくったあと、ボーンを通して、アニメーションの動きをつけていきます。また、年賀状は、平面に、pngファイルをテクスチャとして貼りました。

注意点としては、

+ サーフェスは、プリンシプルBSDFにする。
+ 画像を貼りこむときは、ベースカラーのところで、画像を選択する。（シェーダーエディターでいじると、後で反映されないことがある）
+ 画像ファイルや、すべてのアセットの名前を英語表記にする。
+ UV展開の画像ファイルとのリンクはきちんと行う。
+ 動画やgifアニメは埋め込まない。（usdzが対応していない）
（22/01/02 11:49追記）
+ 裏面にも注意。Blenderからgltf→usdzへ変換していったとき、裏面の表示ができませんでした。両面表示したい場合は、同じものを同じ場所にコピペ、法線をひっくり返す、という技を使いました。

このへんであとあと苦しみました。
Blender単体で使っているときには、ちょっとおかしなところ（リンクの貼り方など）を大目に見てくれるんですが、大目に見てくれない感じです。

## ファイル出力＆変換

model-viewerのところで説明しましたが、model-viewerは、Quick LookとScene Viewerの兼用シーンビューワーです。なので、Quick Look用の**usdzファイル**と、Scene Viewer用の**glTFファイル**の両方が必要になります。

まず、Blender2.8は、glTFファイルの出力に対応しているので、できあがった3Dモデルとアニメーションを書き出します。

![blender2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/1719a7ca-90af-2448-87ca-284661903440.png)

glTFは、３種類あるのですが、この中のglTF Embedded（.gltf）を選択します。
その他の項目はこうしました。

![blender3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/4a4d31ac-3161-9cfb-114b-e4ccd7b4ea7a.png)

Blenderは、他の３Dアプリと軸が違っているらしく（知らなかった・・・）「＋Y」が上にチェックすることで変換しています。
ここまでで、glTFファイルは完成！

次に、usdzファイルをつくる必要あります。

glTFファイルから、usdzファイルへの変換は、「USD Python 0.64」をダウンロードして行いました。
（この記事を参考にさせていただきました。https://qiita.com/aa_debdeb/items/44d4788e6d89e71c2ff3）

```
./usdzconvert ~/sample.gltf ~/sample.usdz

```
で3Dモデルもアニメーションも合わせて変換できるのですが、なぜか、色が暗い！
いろいろ調べてみると、デフォルトだと、メタリックの反射がついてしまい、暗くなる、ということでした。

```
./usdzconvert ~/sample.gltf ~/sample.usdz -metallic 0

```
と、変換時に、「-metallic 0」をつけると、うまくいきます。（でも、それでも、ちょっと色味が心なしか暗い気が・・・。明るさを調整する方法を知っている方がいたら、教えてください）

これでついに、glTFファイルとusdzファイルがつくれました。

（22/01/02 11:49追記）
MacユーザーならReality Converterをインストールして使ったほうが手軽かもです。

## model-viewerのコーディング

コーディング、と書きましたが、かなり簡単です。
（簡単な代わりに、カスタマイズできる範囲は少ないですが）

model-viewerの公式リファレンスはこちら。https://modelviewer.dev/docs/index.html
この記事も参考にさせていただきました。https://www.jyuko49.com/entry/2020/07/24/135155

まず、骨組みとなるコードはこちら。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AR年賀状「風」</title>
  <!-- Import the component -->
<script
      type="module"
      src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"
></script>
<script
      nomodule
      src="https://unpkg.com/@google/model-viewer/dist/model-viewer-legacy.js"
></script>
</head>
<body>
    <model-viewer
      reveal="manual"
      src="./negajo.gltf"
      ios-src="./nengajo.usdz" 
      poster="./poster.png"
      style="width:360px;height:555px;" 
      auto-rotate
      camera-controls
      enviroment-image="./sora.jpg"
      exposure= 1 
      ar
      shadow-intensity= 1 
    >
    </model-viewer>
</body>
</html>
```

このhtmlファイルといっしょに、glTFファイルとusdzファイルも、同じサーバーの同じ階層にいれます。

```
src="./negajo.gltf"
```
で、glTFファイルの指定。

```
ios-src="./nengajo.usdz" 
```
で、usdzファイルの指定をしています。

あと、いろいろ設定できるのですが、ARモードのときは反映されない設定も多いんですよね。

```
      poster="./poster.png"
      style="width:360px;height:555px;" 
```
最初に表示する画面の画像と大きさを設定。

```
      enviroment-image="./sora.jpg"
```
環境画像を設定できます。喜んで設定したのですが、ARモードだと反映されないらしい。オブジェクトモード（背景が白になるモード）では反映されているようです。

```
      exposure= 1 
```
露光の設定。こちらも、ARモードだと反映されず、オブジェクトモードのみ。

```
      ar
```
これは、ARモードにするために、必須。

```
      shadow-intensity= 1 
```
影の設定。こちらも、ARモードだと反映されず、オブジェクトモードのみ。

となっています。

あとは、CSSでボタンとか整えて、完成！

完成した、model-viewerでのウェブサイトが、こちら。
https://namikawasusumu.net/ar/
※iPhoneの方はSafariで、Androidの方はChromeで上記URLを開いてください。

##　Facebook/Instagramアプリ内機能での実装

・・・とここまでで終わりにするはずだったのですが。

いざ、できあがった
https://namikawasusumu.net/ar/
をFacebookでシェアして、リンクを押してみると、Facebookアプリ内でブラウザが開き、model-viewerが動かない！という現象が。

model-viewerは、Facebookアプリ内ブラウザでは動かないんですね。
（ちなみに、Twitterアプリ内ブラウザでは動いたので、Facebookアプリ内ブラウザの独自の仕様のためと思われる）

また、LINEの場合、URLの末尾に「?openExternalBrowser=1」をつけておくと、そのURLをタップしたときに、LINE内ブラウザではなく、ちゃんとブラウザが開く仕様になっています。ありがたい・・・。

話を元に戻すと、Facebookでシェアするときには、Facebookのアプリ内で見られたほうが良さそう、ということもあり、Facebook、ついでにInstagramのアプリ内でのAR実装を行いました。

## Spark AR Studio

FacebookとInstagramにあるARフィルター開発ツールが、このSpark AR Studioです。

公式サイト（Mac用のアプリも、ここでダウンロードできます）
https://sparkar.facebook.com/ar-studio/

ARフィルタ開発ツールということで、顔を認識して、スタンプを出す、みたいなARフィルターのイメージが強いと思うのですが、他にもいろいろできます。かなり使いやすい。

![insta1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/86403deb-049d-2601-9ee3-e2957bff5d38.png)

平面検知、画像検知、フェイストラッキングなどに対応しています。あと、環境光も設定できますね。動画の埋め込みもできます。このあたりも、うれしいです。

![insta2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420008/c8a73411-48ec-aeb5-2a78-67def63b61df.png)

今回は、アニメーションは、Blenderでつくったものをそのまま持ってくるだけ。glTFも対応しているので、楽々・・・のはずが、ここで問題が！

今回のオブジェクトは、
人物・・・腕を引いたり、顔を上げたりのアニメーション
凧・・・上がったり下がったりのアニメーション
がついているのですが、１つのファイルでインポートすると、どちらかのアニメーションしか反映できませんでした（僕の使い方の問題かも、ですが）。

そこで、２つのファイルに分割して、Spark AR Studioで合体させることにしました。

また、容量制限があるので、気をつけましょう。

完成した後は、

**テストチェック**
自分のスマホのFacebookアプリやInstagramアプリでできます。
↓
**データをアップロード**
↓
**審査**
FacebookアプリとInstagramアプリに同時に申請できます。
↓
**本公開**
という流れになります。

審査にどれくらいかかるかは諸説あるのですが、僕の場合は、５時間ぐらいでした。（早っ！でも、１０日間ぐらいかかるときもあるらしいので、僕は運がよかったのかも）

できあがったのが、こちら。

+ Facebookアプリで見る：
https://www.facebook.com/fbcameraeffects/tryit/152838536348547/

+ Instagramアプリで見る：
https://www.instagram.com/ar/152838536348547/

#比較してみる

model-viewerとFacebook/Instagramアプリ（FacebookとInstagramは限りなく同じ。あたりまえですが）を比べてみます。
YouTube動画でみると、よりわかりやすいかと思います。

・model-viewer（iPhone Safariブラウザ）の動作検証
https://youtu.be/NZfcuBzyMjI

・Facebookアプリでの動作検証
https://youtu.be/ucgblEAou2s

フレームレートと平面検出が、iPhone Safariブラウザはとても優れています。地面に吸い付いている感じ。それと比べると、Facebookアプリのほうは、ややカタカタしている印象。

ただ、実際には、スマホの機種によっても違うと思います。

## まとめ

今回の年賀状の企画は、WebAR、model-viewerと相性がよかったようです。

逆に、「styly」「Adobe Aero」「Instagramアプリ」「Facebookアプリ」などの既存アプリではできる、あるいは、独自アプリ開発をすればできるけれど、model-viewerが苦手なこととしては、

+ タッチなどに応じる、インタラクティブな動作
+ 3Dモデルの一部に、動画やGIFアニメを埋め込む
+ 明るさなどの調整
（22/01/02 11:49追記）
+ 複数3Dモデルの利用
+ 画像マーカー、位置マーカー

です。

また、マルチプラットフォームで動かしたいなら、ひとまずglTFファイルでつくって、そこからusdzファイルにしたり、spark AR studioで調整したり、という流れが良さそうです。