Programming in VRChat

VRChat でのプログラミングについて調べたことの書き溜め

ワールドにカメラを置き、撮す映像を写す面を作る

要するに VRChat 内にカメラとその表示モニターを作る方法。 これは基本的には VRChat は関係せず一般的な Unity の機能の範囲で実現可能な内容ですが、 多くの人が作りたくなるモノであるように思うので記事にしてみます。

レシピ

  1. ランタイムに書き換えられるテクスチャである RenderTexture アセットを作成する
    • (操作:Unity メニュー > Assets >Create >Render Texture)
  2. シーンに Camera を作り位置など調整する。
    • (操作:Hierachy タブ > Create > Camera あるいは GameObject > Camera)
  3. Camera のインスペクタで Target Texture に、ステップ1で作った RenderTexture を指定する。
    • これでカメラの出力先が画面ではなくテクスチャになる
  4. 同じく Camera のインスペクタの Culling MaskPlayerLocal, UI, UiMenu のチェックを外す
  5. このテクスチャを表示するモノを作る。(やり方はいくつかあるがここでは手順が少ない方法を紹介)
    1. シーンに Quad を作り位置など調整
      • (操作:Hierachy > Create > 3D Object > Quad)
    2. シーンに表示されている Quad に、ステップ1で作った RenderTexture をドロップする。
      • Quad の面の向きに注意。裏側から操作するとその後ろへドロップされてしまう
      • これで Quad の見た目がカメラの映しているものに変わる
    3. Quad の Material コンポーネント (表示名はステップ1で作った RenderTexture と同じになる)の設定中 Shader の選択を、Unlit > Texture にする。

f:id:naqtn:20180224225454p:plain f:id:naqtn:20180224225516p:plain

補足・解説・拡張ヒント

  • RenderTexture のデフォルトの画素数は 256x256 になっている。
    • このため表示を大きくすると粗さが目立つかもしれない。
    • RenderTexture のインスペクタ中 Size でこの値は変えられる。
  • カメラは新規にシーンを作った時に元から置かれている Main Camera ではなく新規に作成すること。
    • Main Camera を使うと Unity の編集画面では動作するが VRChat からロードすると黒い表示になる
    • (元からあるカメラは MainCamera タグが付いていて、特定の目的に使われるようだ。参考:Camera.main
  • カメラと RenderTexture を使うとそれだけ描画時間を余分に消費する。画素数の大きいテクスチャを何枚も使うとフレームレートが低下するはずなので、注意して設置する必要がある。
  • カメラの動作を止めればその時のテクスチャの内容は残る。写真的な演出になる。
    • (これをファイルとして書き出せれば素敵なのだけど…)
  • カメラを VRC_Pickup を付加したオブジェクトの子として構成すれば、カメラはつかんで移動できる。表示物についても同様。
  • 上記レシピではカメラと表示物をひとつづつ作ったが、間をRenderTextureがつないでいるだけであり、これらが一対一である必要はない。
  • Culling MaskPlayerLocal を外したのは、プレイヤーの体の表示のちらつきを防ぐため。
    • 仕様は不明だが経験的に見つけた良さげな設定なので、何か間違っているかもしれない。将来の版では不適切になる可能性もある。
    • PlayerLocal は、そのクライアントを操作しているプレイヤー自身(のアバター)が該当する。これを無効化してもプレイヤーの表示は別のレイヤー MirrorReflection によって行われる。はっきりしないのだが、この二つが同時に有効になっているとプレイヤーの体の少しずれた描画が二度行われてちらつきを生じているようだ。
    • (なお逆に PlayerLocal を残して MirrorReflection を無効化すると、 アバターの構造に依存するようだが、頭だけが描画されなくなる(ぎゃぁぁ)。多分これが普段描画されている自分。自分の通常の視界において自分の頭が邪魔にならないようになっているのだろう。ちらつきの発生は(完全にあてずっぽうの推測だが)VRのための両眼のカメラの位置とライティングの具合でズレが見えてしまうように思える。ライト設定によっては気にならないこともあるようだ)
    • TODO この設定では自分自身のアバターが出すパーティクルが映らないとの話もあり。要確認。
  • Unlit/Texture はライティングを考慮せずに(un-lighting の略?)テクスチャを単純に描画するシェーダー。デフォルトのままでは表示結果が暗かったりといったことがあるので、簡単に解消する方法としてこれを選択した。
  • 表示物の別の構成方法 (UI の機構を使う方法):
    1. Canvas をシーンに配置する。(Hierarchy > Create > UI > Canvas
    2. インスペクタで、この Canvs の Render Mode を World Space に変更する
    3. Width, Height, Scale や位置角度を調節する(マニュアル:World Space UI の作成 参照)
    4. この Canvas の子に、テクスチャを直接描画する部品 RawImage を追加する
    5. この RawImage の Texture に、作成した RenderTexture を設定する

参考