ViroReactでReact Native製のARアプリを作ってみる

この記事は [React Native アドベントカレンダー](https://qiita.com/advent-calendar/2020/react-native) の 20 日目の記事です。

[株式会社palan](https://palan.co.jp/)ではブラウザ上のARを実現するためのWebARが専門なのですが、[ViroReact](https://viromedia.com/viroreact)というライブラリでReact NativeでARアプリが開発できるということで、今回触ってみます。


## ViroReactとは
ViroReactはReact NativeでクロスプラットフォームのAR/VRアプリを開発することができる、Viro Media社のオープンソースのフレームワークです。
Viro MediaではReact NativeベースでARを開発することができる**ViroReact**と、AndroidのArCoreベースをよりシンプルに開発することができる**ViroCore**というフレームワークがあります。

公式サイトによると、以下のようなARを開発可能です。

- 現実世界での3Dトラッキング
- 水平・垂直の認識
- イメージトラッキング
- 物理的ベースレンダリングなど協力なレンダリング
- 煙や霧などオブジェクトへのアニメーションを付与可能

[ViroMedia](https://apps.apple.com/jp/app/viro-media/id1163100576)のアプリ内で動く手軽なARの開発も可能ですし、このようなスタンドアロンのアプリを開発することもできます。
試してみました。
![ezgif-7-c7cc2618901a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8762/ae4c0cb2-8256-aeeb-5721-9599b90aca6f.gif)


## Viro Media内でARを動かしてみる
Viro Mediaがリリースしているアプリ内でAR・VRを動かしてみます。
仕組みとしてはローカル上でViroMediaベースのアプリを立ち上げ、ngrokで発行されたURLを実機からViro Mediaアプリで入力することで、手軽に試せるようです。

早速インストールしてみましょう。
`yum install node`
`yum install watchman`
`npm install -g react-native-cli`

ここまでは良いとして、react-viro-cliをインストールしてみます。
`npm install -g react-viro-cli`

ここからReactViroのCLIが動かせます。

`react-viro init ViroSample --verbose`

`cd ViroSample` をした後に `yarn start` してみましょう。

するとngrokが動きURLが発行されるので、発行された `https://xxxxxx.ngrok.io` といったURLを[ViroMedia（iOS）](https://apps.apple.com/jp/app/viro-media/id1163100576)、[ViroMedia（Android）](https://play.google.com/store/apps/details?id=com.viromedia.viromedia&hl=ja&gl=US)で開き、URLを入力します。

ここで問題が！
私の手持ちのiPhoneXS、iOS14.3（開発者用）ではこのアプリがクラッシュして動きませんでした😢
他の方も上手くいかないという声もありますし、約1年アップデートされていないのでそこまでアクティブではないのかもしれません。

上手くいくとこういったサンプルが表示されるようです。
![4414726-IMG_2931.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8762/00819870-ae13-f93b-657c-deb773e349bd.png)

詳しくはこちらの方の記事などをご覧ください。
[webエンジニアがViroReactでAR/VRアプリ入門！](https://qiita.com/tommy96/items/bf7eb7c8363a1d896b05)


## スタンドアロンでARアプリを動かしてみる
テストアプリ上ではなく、スタンドアロンで動かしてみましょう。
Androidはこれらのキー設定を済ませておき、 `react-native run-android`を実行しましょう。

```
export ANDROID_HOME=/YOUR_PATH_TO/Android/sdk
export PATH=$ANDROID_HOME/platform-tools:$PATH
export PATH=$ANDROID_HOME/tools:$PATH
```
iOSはiosディレクトリで`pod install`し、`react-natvie run-ios` を実行します。

今回は簡単に3Dモデルを表示するデモを作ってみます。
こんな感じです。

```react
import React from 'react';
import {StyleSheet} from 'react-native';
import {
  ViroARScene,
  Viro3DObject,
} from 'react-viro';

const App: () => React$Node = () => {
  return (
    <>
     <ViroARScene>
        <Viro3DObject
          source={require('./res/spaceship.obj')}
          position={[0, 0, -1]}
          scale={[.2, .2, .2]}
          type="OBJ"
          dragType="FixedDistance"
        />
      </ViroARScene>
    </>
  );
};

export default App;
```

`ViroARScene` でARを制御してます。
豊富なPropsを有しており、トラッキングした際の挙動やオブジェクトのドラッグなどのイベントを定義することができます。
`Viro3DObject` はその名の通り、3Dオブジェクトを表示させることができます。
OBJやFBXを表示させることができるようです。
テクスチャを当てるときなどはこんな具合です。

```react
<Viro3DObject
    source={require("./res/spaceship.obj")}
    resources={[require('./res/spaceship.mtl'),
                require('./res/texture1.jpg'),
                require('./res/texture2.jpg'),
                 require('./res/texture3.jpg')]}
    highAccuracyEvents={true}
    position={[1, 3, -5]}
    scale={[2, 2, 2]}
    rotation={[45, 0, 0]}
    type="OBJ"
    transformBehaviors={["billboard"]}/>
```


そしてここでも問題が...！
私の手持ちのM1のMac Book Proではこのライブラリでrunできず。。。
M1はなかなかハマりどころ多いですね。
アドベントカレンダーに間に合わせる為に公開しますが、また解決次第更新します。

## 懸念点
昨年ViroReactはオープンソース化されました。
[Viro is going Open Source!](https://blog.viromedia.com/viro-is-going-open-source-be9da0b43328)

されましたが...以降ほとんどアップデートがされておらず、ライブラリがそんなにアクティブではなさそうです。
また、テストアプリであるViroMediaの更新も1年止まっており、そこまで将来性は無いのではと感じました。

[リリース状況](https://github.com/viromedia/viro/releases)
![スクリーンショット 2020-12-20 17.46.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8762/ebb04f13-aaad-52da-8730-e08e0fa79950.png)


iOSのARKit、AndroidのARCoreのアップデート、進化はすさまじいものがあります。
6DoFはもちろん、オクルージョン、ボディトラッキング、更にLiDARスキャンなど進化のスピードが早すぎるくらいです。
正直ViroReactはそのスピードについていけるのか怪しいと感じました。

## まとめ
React NativeでクロスプラットフォームのAR開発ができれば、より裾野は広がりそうです。
ですが、そもそもARKitとARCoreの差分を吸収し、クロスプラットフォーム化していくことは非常に労力のいることだと思います。
※ほぼネイティブレイヤーの機能ですし。

クロスプラットフォームであれば、Unityの[AR Foundation](https://unity.com/ja/unity/features/arfoundation)のほうがコミュニティ含め活発な為、iOSとAndroidと同時に開発していきたい際はそちらのほうが良いかもしれません。

[React Native Advent Calendar 2020](https://qiita.com/advent-calendar/2020/react-native)の21日目の記事は [@takagimeow](https://qiita.com/mtskhs)さんです!