ぼくのかんがえたさいきょうのバーチャル美少女配信システム
この記事は Akatsuki Games Advent Calendar 2022 の 20 日目の記事です。 昨日は @yuji_ap さんの「UI Toolkitでステージエディタを作ってみた」でした。 今までの IMGUI でのエディタ拡張は全て C# のコードで書いていたのに対して、UI Toolkit は構造の定義は UXML USS で、見た目を定義は USS というのはどことなく Web ページの構成と似ていますね。
はじめに
アカツキゲームスではオフィス出社に加え在宅のハイブリッドワークの形で仕事をしています。 Zoom 会議がしばしばあるのですが、アカツキゲームスの一部メンバーはバーチャル美少女の姿で参加していたりします。去年の Akatsuki Advent Calendar 2021 にもバーチャル美少女でZoom参加する記事があったりします。
バーチャル美少女のZoom 参加するためのシステムを自作しているのですが、その遍歴とその概要を紹介しようと思います。 ぼくがつくったさいきょうのば〜ちゃるびしょうじょのはいしんしすてむです。
初代バーチャル美少女
構成
ざっくりとした概要は以下の感じです
顔トラッキング方法として ARKit を使ったりする方法がありますが、作った当時(2020年)動作する iPhone を持っていなかったので、 Web カメラがあれば動作できるように画像の顔検出で作りました。 Unity で OpenCV / Dlib を動かして顔トラッキングする方法もあるのですが、最初にPython で実装したのを使い続けてました。
画像処理で顔検出している関係上、 CPU リソースを使うので顔トラッキングをしていると PC が重くなるという問題があるので、別 PC でトラッキングを動かせるように UDP で Unity に送る方式にしました。
バーチャル美少女で Zoom 参加方法
バーチャル美少女で Zoom に参加するフローとしては
初代の諸問題
Zoom 参加方法を箇条書きにするとそこまでですが、普段自宅では顔トラッキングをすると PC が重くなるので別 PC で動かしていました。そのため、トラッキングを動かしている PCを に ssh を繋いで python スクリプトを動かしたり、Unity とキャプチャー用のソフトを立ち上げたりと Zoom 参加まで地味に準備が大変でした。
また、ウィンドウキャプチャーに CamTwist を使ってましたが、PC を M1 Mac に交換すると動作しなくなりました。
OBS だと問題なく動作するのでソフトを変えたり、
NDI に対応させてウィンドウキャプチャーをしなくて済む様にメンテをしました。ただ、ノリと勢いでコードを書いた部分が大半で、徐々にメンテが辛くなってきました。そのため、2代目バーチャル美少女システムとして1から作り直すことにしました。
2代目バーチャル美少女
1からバーチャル美少女システムを作り直すことにしたのですが、初代と同じ構成で作り直しても面白くないという理由で Unity を使わず Web アプリとして作り直しました。
概要
2代目のバーチャル美少女システムの概要は以下の感じです
- JavaScript の Mediapipe でトラッキング
- kalidokit で blendshape 化
- Phoenix LiveView でブラウザ間の通信
- 3D モデルの表示は three-vrm
トラッキングと 3D モデルに関する内容は JavaScript をつかっています。また、Web サーバに Elixir の Phoenix LiveView を使い、3D モデルをリアルタイムに動かす通信を行ってます。
ソースコードは GitHub で公開しています。また、以下のリンクで実際に動かしています
https://livevstream.naoyakohda.net/
実装
JavaScript
トラッキング、Blendshape 化、モデル表示周りは以下のライブラリを使ってます。
JavaScript の実装はそれぞれライブラリのサンプルプログラムを Phoenix LiveView で動作するように変更を加えた程度なので詳細の説明は省略します。動作する 3D モデルは VRM のみになります。FBX は Humanoid 周りの対応が大変なので対応してません。
Elixir
ブラウザ間の通信には Elixir の Phoenix LiveView と Phoenix PubSub で実装しています。
Phoenix LiveView はサーバーサイドレンダリングのフレームワークですが、今回はバーチャル美少女になるために使います。 LiveView は通常の HTTP の API サーバとは異なり、裏で WebSocket 若しくは Long Polling を使いサーバーとクライアント間のリアルタイム通信が可能になってます。
Phoenix LiveView は JavaScript を書かず Elixir のみで SPA風のページが作れる工夫がされています。とはいえ、バーチャル美少女になるための顔トラッキングやモデルを動かす様なことは流石に Elixir だけではできません。 そのため、LiveView では JavaScript の呼び出せる仕組みも用意してあります。
以下の様に phx-hook
で hook object 指定すると life-cycle callbacks が定義され、任意の JavaScript を実行することが可能になります。
<div phx-hook="hogehoge" />
また、callback では以下の様なものが用意されています。
el
: DOM要素の参照するpushEvent(event, payload, (reply, ref) => ...)
: サーバにイベントを送るhandleEvent(event, (payload) => ...)
: サーバが push したイベントを受け取りハンドリングする
フローとしては
- クライアントで顔トラッキング
pushEvent
で送られてきたトラッキング結果をイベントの params として送る- サーバ(Elixir) は
handle_event/3
でイベントハンドリング - 受け取った params(トラッキング結果) を
Phoenix.PubSub.broadcast/3
でクライアントに送る - クライアントは
handleEvent
でサーバからトラッキング結果を受け取りモデルを動かす
今回、pushEvent
でトラッキング結果をサーバに送り、handleEvent
でトラッキングした内容を受け取り、el
で追加した DOM でモデルを表示しています。
ブラウザ内で完結する場合はpushEvent
、handleEvent
でサーバ経由にする必要はないのですが、
複数のブラウザに対応させるためにサーバ経由でトラッキングデータのやり取りを行っています。また、PubSub の broadcast で送ってるので、ブラウザを表示している全ての端末でリアルタイムにモデルが動きます。
バーチャル美少女で Zoom 参加方法
バーチャル美少女で Zoom に参加するフローとしては
- 普段使うブラウザから Web ページにアクセス
- OBS で映像 Source を Web ブラウザにしてキャプチャー
- Zoom のカメラを仮想カメラに切り替え
初代より起動アプリが少なくなって楽になった 🎉
サーバをデプロイしていれば手元の PC に環境を作らなくてもブラウザを開けばバーチャル美少女になれる。🎉🎉 サーバも Docker 上で動くからデプロイも簡単。
そしてそして、URL を知っている人であれば Zoom に写ってるのとは別に好きな角度から見れるオマケ付き。
おわりに
以上、歴代バーチャル美少女のZoom 参加するためのシステムの紹介でした。
初代は Python と Unity でバーチャル美少女になっていましたが、2代目では Elixir と JavaScript でバーチャル美少女をリアルタイム配信できるようになりました。
LiveView を使ってバーチャル美少女配信は LiveView らしい使い方ではないですが、リアルタイム更新のためのクライアント間のハンドリングを特に意識しせずに、PubSub を使って配信できる LiveView はすごいですね。
今は3Dモデルを変えられませんが、自由にアップロードして選べるようにしたい… そして Elixir や LiveView の関して具体的な実装内容は書いてませんがいつか記事を書きたい…
リアルタイム配信なら WebSocket じゃなくて WebRTC だって? そんなこと言ってはいけない。
LiveView はバーチャル美少女なるために使うものでは無いって? そんなこと言ってはいけない。
わざわざ自作せずに既にある Web サービスを使えば良いって? そんなこと言ってはいけない。
明日の Akatsuki Games Advent Calendar 2022 は @kyooooooooma さんの 「UE5でMMDを踊らせるぞ」です。 MMD は UE で使うことを前提として作られてないのですが、それを UE5 でどういう風にしたら踊らせられるのかは楽しみですね。
最後に、アカツキゲームスでは一緒に働くエンジニアを募集しています。 カジュアル面談もやっていますので、気軽にご応募ください。