VTuberを支援する技術

# 注意
マッハ新書という面白い試みが最近されています。
「取りあえずリリース」はアウトプットに時間をかけがちな私には挑戦してみる価値のある手法でした。
上記試みを参考に、12時間以内にリリースを目標に構想していた記事を書き上げました。

# 概要

VTuberが盛り上がってきていますね。
なりたい職業ランキングにYoutuberやゲームプログラマーが上がることを考えるとVTuber関連のエンジニアになりたい人も出てくるのではないでしょうか。
そこで、私の知っている技術を紹介します。

# センサー

## トラッカー

手法は色々あれど、目的はリアルでの座標の変化を観測することです。

### 画像解析によるトラッキング(単眼カメラ)

特徴点、簡単に言えば色が急激に変わる箇所を観測することで姿勢を求めることができます。
中でも背景に埋没しない特徴的な色のオブジェクトは高精度なトラッキングを維持できるのでトラッカーと呼ばれることがあります。

利点

* カメラがあれば利用できるという汎用性
* 表情トラッキング、アイトラッキング等の未来の技術を利用できる
* 実質的にトラッカーである特徴点が他の手法の10倍程度確保できる
* モーションモデルの負担がない

欠点

* カメラから隠れる位置のトラッキングが不可能
* 他の手法と比べると重い
* トラッカーが平面情報(x, y)しか持たない

まだまだ発展途中の技術なので断定はできませんが、カメラ1つでの姿勢推定は現在では不可能と感じます。

### 画像解析によるトラッキング(2カメラ以上)

2以上のカメラを利用して画像データから立体の姿勢を特定する技術はStructure from Motion(SfM)と呼ばれています。

ステレオカメラを利用すると比較的簡単にできるとはいえ、基本的に大げさ過ぎて使いどころが難しいです。
トラッカーの装着が不可能かつセンサーの精度が期待できないスポーツの観戦などのバーチャル化を実現しようと思ったらこの手法しかないと思います。

### 深度センサーによるトラッキング

実質的に単眼カメラと完全に同期させて利用します。
なので、画像解析手法のオプションとして考えると良いと思います。
デメリットがない割にメリットが大きいので頻繁に使われる手法です。

利点

* 画像解析手法と比べて深度情報(z)が追加されているため3D空間上をトラッキングできる

欠点

* 深度センサが必要となり、深度センサの有効範囲という制約が増える

### 走査線によるトラッキング

残念ながら位置センサというモノは存在しません。
GPSは衛星やアクセスポイントの情報を用いて位置を算出しています。
私たちが位置を得るためには相対的な何かが必要です。

HTC ViveのLighthouseがこの方式のはずです。

利点

* 広い空間を高精度でトラッキングできる
* トラッキングできない死角がほとんどない

欠点

* 設定、機材、設営の全部が面倒
* モーションモデルの負担が大きい

## Head Mounted Display(HMD)

HMDは様々なセンサーを利用して違和感の少ない姿勢を算出しています。

### ジャイロ(角速度)センサー

これなしにはHMDは成立しない程の恩恵を与えてくれるセンサーです。
初期姿勢からのジャイロセンサー計測値を元とした推定姿勢の精度はかなり高く基準点がなければ気付かない程です。
顔の動きと画面の連動が少しでも遅れると強烈な違和感に繋がるVRでは必須ではないかと思います。

### 加速度センサー

思ったよりも速度を与えないと識別できなくて扱いにやや困るセンサーです。
しかし、重力加速度は安定して計測できるので現実の下方向を取得できるのは優秀です。

### 磁気センサー

理想的には絶対的な方角が分かり便利そうですが、現実的にはノイズが多く使うのは難しいです。
上手にノイズを取り除けるのなら補正に使えそうに思います。

## キャリブレーション

VR業界では２種類の意味で使われるので注意が必要です。

### センサー固有の癖を特定するための作業としてのキャリブレーション

センサーは物理的なモノなので工場で量産したとしても１つとして同じものはありません。
なので、メーカーが設定する誤差をその製品を使う限り許容する必要があります。
そこで登場するのがキャリブレーションです。
製品に一定の癖が強く出る物理的なテストを課すことで癖を正常値に補正するデータを取得します。

具体的な例を出しましょう。
悲しいことに絶対に違いが出てしまうハードウェア、人間のキャリブレーションが分かりやすいでしょう。
何らかの媒体に身長のデータを取得して入力します。これがキャリブレーションデータになります。
そのデータにアクセスできれば3D空間のアバターと身長をマッピングすることができるので、身長の違いを誤魔化して動作させることができます。

### 一次記憶データの削除としてのキャリブレーション

ジャイロセンサーは精度が高く誤差が少ないとはいえ少量の誤差は出てしまいます。
それが蓄積すると正面を向いているはずなのに90度真横を見ているなんてことになります。
ジャイロセンサーによる計算値は加速度なので全て足し合わせることで現在の角度を求めています。
その一次的な計算結果である角度を一度初期状態に戻すこともキャリブレーションと言ったりします。
他にもセンタリング、リフレッシュ等とも表記することがあります。

# 補正

処理の早い順に並べると
ソフトウェアエミュレート > 有線上のセンサ > 無線上のセンサ > ネットワーク同期
という感じになるので、遅くなればなるほど上手に誤魔化してやる必要があります。

## フィルター

センサーの値は当然アナログ値なのでノイズが乗ってきます。
スパイクのような明らかに観測できるノイズの場合は簡単にフィルタリングできますが、センサー固有の癖を取り除くことは困難です。
そこでフィルターを通した観測値を利用することで比較的安定した値を利用することができます。

有名な所だとSavitzky–Golay filter等があります。

## 等速直線運動予測

力が加わっていない物質は等速直線運動をするのもそうなんですが、私の経験則的な意見ですが人の動きは等速直線運動になりやすいです。
試しに適当に腕を振ったり回したりしてみてください。
同じ速度で動作していませんか？

私と同じことを思ったかは分かりませんがセンサーの観測範囲から消えてしまったものは消える直前の速度で直進し続けると仮定して動作させることで少しの時間誤魔化すことができます。誤魔化している間にセンサー値が再び取得できたならユーザに不快感を与えずに済むでしょう。

同様のことがネットワーク同期でも行えます。
というかネットワークの同期は200ms毎しか同期が取れない場合とかもあるので誤魔化さないと酷いことになります。

## 実測値と予測値の合成

上記と似たような話に実測値と予測値の合成があります。
待ちに待った実測値を取得した瞬間に上書きしようとした時に予測値と大きく異なる場合ワープすることになります。
一緒に話していた友人が突然ワープすることは大きな不快感へと繋がります。
そこで、実測値と予測値を徐々に合成することでユーザの違和感を減らす手法があります。

実際の座標と違う位置に描画される方が不自然だと感じる人もいるかもしれません。
大丈夫です。本当の座標を知っているのは本人だけだし、誰のカメラにも映ってなかったとしたら実際の座標とズレていることを誰も観測できません。

# 3D

ライティング等の全ての3Dにおいて必要な知識は省略しています。

## Inverse Kinematics(IK)

いきなり逆運動学の話をしても何の逆なんだってなるので、よくある解説に従って順運動学(Forward kinematics : FK)から話します。
肩を90度、肘を90度曲げた時に手の座標の位置を計算して求めることを順方向と考えた際に、
手の座標から肩の角度と肘の角度を求める研究を逆運動学(IK)と言ったりします。

手のトラッカーを体に近づけた場合に肘のトラッカーなしに肘を曲げてもらうには、手の座標から肩や肘の角度を求める必要があるということですね。

FKは順番に計算してやれば一意の値が算出できるので話は簡単でした。
しかし、目標座標から姿勢を求める問題は非常に難しく下記のような手法を使わなければならない場合があります。

### メタヒューリスティック的手法

IKのような組み合わせ問題に対して有効と言われているのがメタヒューリスティック的手法です。
特徴としては良い結果が得られそうな組み合わせパターンの保持、解空間の底からの脱出等をそなえています。

以下の様な手法があります。

* Neural Network
* 遺伝的アルゴリズム(Genetic Algorithm)

## ブレンドシェイプ/モーフ

表情やリップシンクの為の口の形等の表現に使われます。
大雑把に言うとブレンド率によって移動する頂点群です。

# 音声

ボイスチェンジャーについてはハード・ソフト両方の知識が追い付いていないので触れません。

## Speech To Text(STT)/Text To Speech(TTS)

最近ではディープラーニングのお陰で人工音声入出力が良好な成果を出しています。
GoogleやIBM等の企業が個人でも使える人工音声入出力サービスを提供しているので、それを利用することで別人の声でしゃべることができます。

私が実際に利用したことのあるWatsonのSTT/TTSを基準とした記述ですが他のサービスでも似たような状態なのではないかと思います。

基本的にはWeb APIを経由するので多くの環境で動作させる事が可能です。
しかし、マイク入力と音声ストリームの取り扱い方が環境によって違うのでそこをSDKでカバーし、カバーしきれない部分を自分でなんとかするという形になるかと思います。

STTでは固有名詞や専門用語は誤認率が高く、カスタムモデルという自分用の学習モデルを利用する必要がありました。
発音とテキストのペアのリストを与えて学習させることで誤認率は下がります。

## リップシンク

音声ストリームから口の形が判別できる箇所とその時間を抜き出し、口の形を変形させるモーフのブレンド率にそのタイムラインを合成する技術です。
音声ストリームさえあれば、リアルタイムマイク、音声ファイル、人工音声等々で利用できます。
音声から判別できる口の形は多いが、全部のモーフを作成する手間を考えると絞った方が良いと考える人が多そうに感じます。

# 設営

HTC ViveのLighthouseは現状赤外線を用いている様で太陽光に簡単に邪魔されてしまいます。
屋外での利用は現状では難しいです。
また、1つの機器でも故障すると目的の動作を得れない場合が多いので各装置の予備を常に確保しておかないと悲惨なことになる可能性があります。
また、Lighthouse同士でも干渉し合うので理想的には1セット毎に部屋で隔離した方が安定します。
反射率の高い板があるだけで正常に機能しなかったりと結構繊細なので安定稼働させている環境とできる限り同じ環境で利用することが望ましいです。

# できなかったこと

配信プロトコルや動画形式にも触れたかったのですが、まだまだ知識が追い付いておらずそれなりにまともなことが言えるようになるまでに時間がかかりそうなので、この記事では触れません。一番大事かもしれない箇所ですが。