React360とは?

堀川豊氏(以下、堀川):よろしくお願いします。「React360でVR」というタイトルで、お話させていただきたいと思います。

冒頭から申し訳ないんですが、「スリーハンドレッドシックスティ」って何回も言うのつらそうなので、今回の発表内では「Reactサンロクマル」と呼ぶのをお許しください(笑)。

本日の内容ですが、ReactVRとの差分とか、React360とはどんなもんなのかということを簡単に紹介させていただけたらと思います。

まず自己紹介しますと、私、堀川と申します。ピックアップ株式会社というDMMのグループ会社に所属しておりまして、この下のフロアで働いてます。職種としてはサーバーサイドエンジニアで、ふだんはGoでAPIを書いたり、WebのフロントエンドだとVue.jsで管理画面作ったりするのが仕事です。

今回のタイトルのReact360について説明しますと、こちらは3DとVRのUIフレームワークとなっておりまして、Webブラウザで動作する3D、VRアプリケーションの開発が可能となっております。

先ほどもお話が出たんですが、以前ReactVRというものがありまして、それが改名してReact360になった……ReactVRどこいった、って感じですが。

ReactVRとの関係

改名の詳しい経緯は公式のブログに記載されてますが、ざっくりと触れると、ReactVRにはWeb実装とOculus向けネイティブ実装があったそうなんですが、インターフェースが同じだけで中身はまったく別物だったんですね。紛らわしいので、Web版だけ別名で抜き出して、それがReact360になったという経緯らしいです。

このフレームワークを使用するメリットなんですが、Reactと同様の概念でUIの構築が可能というところが1つあると思います。Reactのユーザーインターフェース構築に関わる機能とかをそのまま活かせるのは、かなり大きなメリットかなと。

画面の構成要素をツリー状に組み立てていったり、コンポーネントという単位で切り出して、それを組み合わせてUIを組み立てていけるという概念そのものはそのままだということと、実績のあるReact開発の資産をそのまま利用できるのも大きいと思います。

テストのフレームワークだったり、ステートのマネジメントにRedux使ったりみたいな。既に実績のあるツールをそのまま使用してVRの開発ができるのは、かなり大きなメリットだと思います。

なので、上記の2つを見てみても、Reactの開発経験がある開発者は、けっこう低コストでVRコンテンツの開発ができるのではないかな、と思います。

続いてインストールとサンプル起動についてですが、npmで360のcliツールをインストールできるようになっています。このcliツールを利用してinitコマンドを叩くと、プロジェクトのひな形みたいなものを作ってくれます。

Reactの概念そのままでVRの開発ができる

プロジェクトを作成したあとにnpm startをするとWebサーバーが立ち上がりまして、ローカルホストの8081番にアプリケーションが立ち上がるようになっています。

実際に立ち上がったアプリケーションは(スライドを指して)こんな感じです。

これはサンプルなのですごいシンプルですが。3D空間内に2Dのパネルがポコンと置いてあって、その中にテキストで「Welcome to React 360」って書いてあるぐらいのアプリケーションですね。

このサンプルアプリケーションの構造を見ていきたいと思います。2つあるんですが(スライドを指して)1つ目、ここが実際のUIを構成するReactコンポーネントの部分ですね。このHello360というところが、先ほどのUIを構築している宣言の部分になります。

ここ自体は見慣れたJSXの形式で、宣言的にコンポーネントを組み合わせてUIを構築できるというかたちですね。ViewとかTextというのはReact360のほうで提供してくれているコンポーネントで、React Nativeとかで開発されてる方は見慣れているかなと思います。

1番下でAppRegistry.registerComponentというメソッドを実行してるんですが、ここでエントリーポイントとなるコンポーネントを登録しているというかたちですね。このへんもReact Nativeと一緒です。

アーキテクチャの内容

続いてサンプルコード2です。こちらは、React360のインスタンスを生成して、UIの描画メソッドを叩いている処理が書いてあります。プラスで、バックグラウンドのイメージとして360度画像のjpegを指定しています。

続いて、軽くアーキテクチャの話をさせていただきたいと思います。React360を立ち上げますと、Webブラウザの中にMain ThreadとExecutorという2つが立ち上がるようになっています。

Executorのほうから説明させていただきますと、こちらでReactアプリケーションの実行が行われるようになっております。ExecutorはWebWorkerとして実行されまして、メッセージパッシングを用いてMain Threadの360 Runtimesというやつとエントリーを行います。

Main Threadはブラウザのスレッドなんですが、こちらで3D周りの処理ですとか、インタラクションの管理とか、UIのレンダリング、Executorのやり取りなどを行っています。

サンプルコードを例に、処理の流れをざっくり説明していきます。client.jsからrenderToSurfaceを実行しますと、Main ThreadのRuntime内からExecutorにAppRegistryのrunApplicationを実行するようなメッセージが送信されます。メッセージを受け取ったExecutorは、Reactアプリケーションを起動します。起動したあとは、Main Threadのほうに実行してほしい処理をメッセージで通知するようになってます。

ReactVRからパフォーマンスの向上

例えばサンプルコード1では、TextコンポーネントとかViewコンポーネントとかを使ってたんですが、それぞれに対応するRCTビューとかRCTテキストの描画をMain Threadに依頼するために、メッセージの送信を行っています。そのメッセージを受け取ったRuntimeが、UIマネージャーっていうモジュールから指定のコンポーネントの描画を行うという仕組みになっています。

React360になって、Runtimeの部分が刷新されたそうなんですよね。公式のドキュメントとかにも書いてあるんですが。そこがReactVRと違うところらしいです。

Runtimeのざっくりとした構造ですが、Runtimeの中にはReactNativeContextとGuiSysという2つのオブジェクトがありまして、この2つが主要なオブジェクトになっています。

ReactNativeContextは、プロパティにネイティブモジュールっていうExecutorとやり取りするために必要なモジュール類とかを大量に保持してまして、それらがUIに必要な処理とかを実行しています。

GuiSysのほうはインタラクションの管理をしていて、ユーザーのインタラクションに応じて適切なイベントの発火を行ったりなどしています。

このRuntimeなんですが、ざっくりどんなことやってるかというと、Reactコンポーネントを3D要素に変換したり、ユーザーの入力イベントをReactコンポーネントにフィードバックしたり、React Nativeの処理を実行したり、Executorとメッセージのやり取りなどを行っています。

2Dオブジェクトの扱いが簡単

3D周りの処理は、実際にはThree.jsというライブラリが行っています。React Nativeとのやり取りは、先ほど出てきたReactNativeContextというオブジェクトを介して実行されるかたちです。

Executorは、先ほどから何回か説明させていただいていますが、Reactアプリケーションを実行するための機能ですね。WebWorkerとして実行されるようになっています。ブラウザのMain Threadとは別に実行されるようになっていますので、requestAnimationFrame(loop)を中断することなくコードの実行ができるようになっているところが大きなメリットで、パフォーマンスの向上にも貢献しているところかと思います。

続きまして、360で新しく追加された要素として、Surfaceというものがあります。こちらは3D空間内に2Dの要素を追加できる機能です。3Dオブジェクトの場合ですと、座標の指定とかはメートル単位とかでやるんですが、こちらはピクセル単位で指定が可能になっていますので、Webの開発者とかにはけっこう親和性が高いと思います。SurfaceはCylinderとFlatの2種類がありまして、用途に応じて使い分けていくようになっています。

ざっくりまとめですが、React360は、Reactの考え方とか資産を活用してVRの開発が可能になっています。そして、Runtimeが刷新されていまして、パフォーマンスが大きく向上しています。あとはSurfaceの登場によって、2Dのコンテンツなどが非常に扱いやすくなっている点が特徴かなと思っています。

私からは以上です、ご清聴ありがとうございました。

(会場拍手)