あずまの日記

日々のVRChatの暮らし

リムライトで携帯画面覗き見防止フィルムを再現できる

 こういう感じ。見る方向が斜めであればあるほど、設定した色や画像になっていく。

 GIFが再生できない環境向け: 左がまっすぐ前から見たとき、右が斜めから見たとき。

 リムライトの設定例はこういう感じ。適用するものの大きさなどに応じて調節は必要かも? 画像の文字起こしとして全部書くけど、主に「色/マスク」「範囲」「ぼかし」「リムライトの細さ」が調整ポイントです。

設定名
色/マスク 好きな画像
透明度 1
メインカラーの強度 0
ライトの明るさを反映 0
影部分で無効化 0
裏面で無効化 ON
透明度を適用 ON
合成モード 通常
ライト方向の影響度 0
範囲 0.45
ぼかし 0.4
ノーマルマップ強度 1
リムライトの細さ 0.5
VR時の視差の強さ 1

 lilToonのリムライトには画像を設定できる。リムライトの範囲をとても広くして、画像を設定することで、これを実現している。リムライトなので、なめらかに切り替わっていくのが、それっぽい感じを出していて面白い。特にVRChat上で見ると、画面の角度を変えると自然にフェードしてかなりそれっぽい。
 見方によっては、斜めにすると絵柄が変わるブロマイド的でもある(フレンドはそういう使い方をしてくれた)。

 自分でこういうのできないかなと言い出してから実現までもっていけたのが初めてで、やはりこういうことができると楽しい。

・・・

 ちなみにここに行き着くまでに色々試したので、何がどううまくいかなかったかメモしておくと……
 素朴な案として、手前にフィルムの画像を貼った別のオブジェクトを置く案があった。Boundsで見えるオブジェクトが切り替わるとか、ステンシルで斜めから見たときだけフィルムのオブジェクトが見える、という実現方法で、後者は試した。ただこういう感じだと、瞬間的にフィルムの画像100%になってしまって、覗き見防止フィルムのような見えるものがだんだん変わるというのはできなかった(たぶん)。
 なのでやはりシェーダでやるのがいいだろうとなって、最初はMatCapやNormalMapでできないか試していたけど、見ている方向(物から見たカメラの角度)によって表示を変えるということができないのでだめだった((光に対する)物の角度しか設定できない)。距離フェードは距離だけで角度は関係ないし、視差マップはずれるだけでやりたい動きにならなかった。最終的に、「見ている方向(物から見たカメラの角度)によって表示を変える」から考えて、リムライト、となった。

 それでいうとリムライトも、円形の範囲で濃さが変わるような動きで、完全ではない。範囲をできるだけ広くしつつ、いい感じにフェードしていくような設定値になんとなく合わせている。広い平面に適用しようとしたら、結構難しいかもしれない。

Get Backのスタジオのワールドでビートルズやりたい

 楽器弾けるわけじゃないけどビートルズの写真撮るのやりたい。今のところGet Backのときの感じのサヴィル・ロウのスタジオとか屋上とかのワールドはなさそうなのでなんとかして作りたい。

www.disneyplus.com

2022年末にVRCSDKのunitypackageファイルでの配布が終わるので、アバターやワールドのUnityプロジェクトなどはVRChat Creator Companion(VCC)で新しい形式に対応したプロジェクトに移行するとよさそう

hello.vrchat.com

三行

  • VRCSDKのunitypackageファイルでの配布は2022年末に終わるので、今後もVRCSDKを更新していくなら、VRChat Package Manager (VPM)形式というのに対応したUnityプロジェクトにしておく必要がありそう
  • 記事で紹介されている手段は2つで、VRChat Creator Companion (VCC)を使って移行するか、自分でUnity HubからUnityを起動してテンプレートパッケージをインポートするか
  • 既存のプロジェクトを移行するにはVCCが楽そう
    • この辺詳しくないので教わりたい

既存のプロジェクトをVCCで移行する

 公式のドキュメントはここ→ Migrating Projects | VRChat Creator Companion

 VRChat Creator Companion (VCC)という、VRChat用のUnityプロジェクトを管理するためのソフトウェアが公式で登場した。同時に、VRChat Package Manager (VPM)という新しいパッケージ管理形式も登場している。順序としては、「VRCSDKをVPMに統一したいので、VCCというツールを用意しました。移行してね & 新規作成もテンプレートがあるから使ってね」というように読める。

 VCC自体のインストールは、 https://vrchat.com/home/download からできる。「Creator Companion」というのがそれ。
 VCCでは、「Projects」>「Add」からプロジェクトを追加できる。既存のプロジェクトを移行するなら、

  • 「Projects」>「Add」からプロジェクトを追加して、
  • 追加したものをクリックして、
  • 「Make Backup」でバックアップを取る
    • 「Backing up (プロジェクト名)」と出るのでしばらく待つと完了して、「Show Me」を押すとエクスプローラが開いてバックアップファイルを確かめられる(zipファイルができているはず)

  • バックアップできたら、「Migrate」で移行する
    • もとのプロジェクトは残しつつコピーとして移行するなら「Migrate a copy」、もとのプロジェクトを上書きしていいなら「Migrate in place I HAVE A BACKUP」。

 成功したら「Open Project」が押せるようになっていて、押すとUnityが開くはず(失敗するとどうなるのかまだ見れてない)。普段の使い方としては、今までのUnity Hubの代わりに、プロジェクトを選んで起動するソフトウェアというイメージ。

 ちなみにMigrateボタンを使わずに手動で移行しようとすると、既存のプロジェクトから必要なものをエクスポートして、テンプレートプロジェクトにインポートする、みたいな手順を踏むことになりそう?だけど、この辺は詳しくないので教わりたい。

VRChat Package Manager (VPM)

 VPMとは、VCCで使われるパッケージ形式のこと (Packages | VRChat Creator Companion)。今までもアバターや衣装などをUnityにインポートしてAssetsに現れたものを使って……とやっていたわけだけど、VPM形式に沿うことで、VCC上で「何をインポートしたか」「バージョンがいくつか」などを管理できるようになる。あとは、「事前にこのシェーダーをインポートしてください」みたいなものもVPM形式では「依存パッケージ」として表せて、VCCが必要なものをインポートしてくれるようになる、と書かれていそう。

新規にプロジェクトをつくる

 アバターのプロジェクトについては、mio3ioさんのドキュメント(https://avatar.mio3io.com/#/setup_vcc)などに詳しい。ワールドのプロジェクトでも、「Project」の「New」から「World」を選んで名前をつければ、テンプレートからプロジェクトがつくられる。ちなみにUdonSharp (U#)が必要な場合は、「UdonSharp」を選ぶとUdonSharp(がワールドのテンプレートに追加された)テンプレートからつくられるので便利。

 少し長めに帰省することにしたところ、少し長めにVRChatに行けないことに気づいてだいぶ寂しい思いをしている。Quest2だけでも持ってきたら単体&無言でログインできたのかも、今度はそうしてみたい。

任意の場所を常に向くカメラ

 VRChat 公式のカメラには Look at me モードがあって、常に自分の顔?を向いてくれるようになる。これを、任意の点を向けるようにしたい。

できたもの

 VirtualLens2 を使って、レンズが常に白い Cube を向くようにした。写真の向き (縦にしたり斜めにしたり) は、持っているカメラの向きで変えられるようにしてある。
 あとは白い Cube (とカメラ本体) がカメラ上で見えないようにしたいのだけど、 UI Layer に変えても写ってしまって困ってる……(どうしたらいいのか??)

詳しく

 ツイートしていたら教えてもらったので、その通り VirtualLens2 と Aim Constraint でやってみることにした。

booth.pm
docs.unity3d.com

 Aim Constraint は、指定したものを向くための Component で、単純にアバターの顔を指定すれば Look at me 相当のことができる。今回は、それを任意の場所にしたいので、ワールド固定した Object を向くようにする。なので作戦としては、ワールド固定を習得してから、 Aim Constraint を習得する二段階。

ワールド固定

 見たのはこのあたり。後半に仕組みも書かれていて面白かった。 Position Constraint でアバターと逆の移動をさせることでその場に置き去りにする、という手法で、ものすごいなるほど感がある。 Rotation Constraint は単に無効化するために負数を指定するというのも面白い。

note.com

 今回は、ワールド固定する白い Cube は (手ではなく) カメラのレンズの前にくっつけるということにしたので、↑の記事での手順のうち、手に持たせる代わりにカメラのレンズに入れた。この後やる Aim Constraint で指定するので、 Aim Constraint をつける Object の子には入れないように気をつける (子に入れてしまうと、 Aim Constraint で向く→ Cube の位置も変わる→向く……という無限ループになって高速に回転してしまう)。

Aim Constraint

 上でやったワールド固定できる Cube を向くように、カメラのレンズに Aim Constraint を追加する。 Unity の様子はこういう感じ。

 しかし Aim Constraint を指定すると、 (Z軸が Cube を向いてくれるのはいいとして) レンズの向き (Z軸回転) が必ず初期位置から 90度ずれてしまって困った。色々試すと、 Up Vector という設定を変えると挙動が変わることがわかった。これは本当に理解が難しかった…… (Unity のドキュメントには「アップ軸を指定」とか「上方向を指定」とか書かれていてよくわからない (英語でも「specify the up axis」とか「to specify the upward direction」とかなので翻訳のせいではなさそう))。

Aim Constraint の Up Vector

 Up Vector というのは、「Aim Constraint で向く際にどこを常に上とするか」という設定である、と言えそう。

 まず Aim Constraint というのは、「指定した Object に向かって、 (Transform を基準とした) あるベクトルを向ける Component」である。今回はカメラのレンズの真正面が Z軸そのものだったので、 (0, 0, 1) というベクトルを指定した。例えばカメラの斜め上のほうを何かに向けたいときは、 (1, 2, 3) みたいなベクトルも指定できるということになる。
 ここで、そのベクトルを向けた後の状態を考えると、そのベクトルを軸にいくら回転してもよいことがわかる。例えば今回の場合、 Z軸回転をどれだけやっても、 Z軸が Cube に向いているというのは変わりがない。なので向きが一意にならない (多分)。
 Up Vector を使うと、その向きを一意に決めることができる。例えばレンズの Y軸 (0, 1, 0) を Up Vector にして、 World Up Type を Scene Up にすると、レンズ Y軸が Scene の上 (Scene の Y軸) に常に向く。公式カメラの Auto level (常に水平になるモード) と同じような動きになる。デフォルトは Scene Up なので、上で書いていた「レンズの向き (Z軸回転) が必ず初期位置から 90度ずれてしまって困った」というのはこれだった。

 ドキュメントにはこういう表がある。

Up Vector このゲームオブジェクトのアップ軸を指定します。例えば、ゲームオブジェクトが常に正の Y 軸が上を指すように指定するには、X、Y、Z 軸にそれぞれ 0、1、0 の__Up Vector__ を入力します。
World Up Type 上方向の軸を指定します。エイムコンストレイントは、このベクトルを使用してゲームオブジェクトのアップ軸をこの上方向に整列させます。
Scene Up シーンの Y 軸。
Object Up World Up Object が参照するゲームオブジェクトの Y 軸。
Object Up Rotation World Up Object が参照するゲームオブジェクトの World Up Vector によって指定される軸。
Vector ワールドアップベクトル。
None ワールドアップベクトルを使用しません。
World Up Vector World Up Type で Object Up Rotation と Vector の選択時に使用するベクトルを指定します。
World Up Object World Up Type で Object Up と Object Up Rotation の選択時に使用するゲームオブジェクトを指定します。
https://docs.unity3d.com/ja/2019.4/Manual/class-AimConstraint.html

 今回は、レンズの Y軸をカメラの Y軸に合わせたかったので、 Object Up を使うことにした。小さな Cube をもうひとつ足し、カメラの Y軸側にちょっとだけずらしておいたものを、 World Up Object に指定する。 Up Vector を Y軸にすることで、小さな Cube に常にレンズの Y軸が向くので、カメラを縦にしたり横にしたりするとそのように画面が変わるようになった (一番上の動画でもわかる)。

 ちなみに None にしたときにどういう挙動になっているのかはよくわからなかった。回転が一意に定まらないはずだけど、大体決まった場所で決まった向きになっているので、何かの基準にフォールバックしているような気もする。
 あと World Up Type の Vector に今気づいた。これを使うと、レンズの Y軸を常に Scene の X軸に向けて必ず縦の写真を撮れるようにする、みたいなことができそう。

3DF Zephyrで八ツ橋をフォトグラメトリしてVRChatで出現させる練習

 フォトグラメトリをやってみたくて、ゆくゆくは京都の観光名所とかをやってみたいけど、ひとまず初めの一歩として、机の上に偶然八ツ橋があったので撮った。

撮った写真

 できあがったのがこれ。

 フォトグラメトリでちょっとググって見たところ、よくおすすめされてるのは 3DF Zephyr だったので、今回はまずそれを使ってみることにした。 www.3dflow.net

 手順はこのあたりを見て、写真からテクスチャ付きメッシュを生成して obj ファイルに出力した (mtl ファイルと jpg ファイルx2 も一緒に出力されて、それらをまとめて Unity の Asset に入れることで使うことができた)。

 無料版だと材料の写真は 50枚までしか入力できなくて、精度が心配だったけど、少なくとも手元の八ツ橋はかなり良い感じになった。景色とかになるとスケールが大きくなって、相対的に荒くなると思うけど、例えば銀閣寺のあの建物 (銀閣) だけを撮ってフォトグラメトリ、とかならなんとかなりそうな気がする。ところで建物とかはどうしても日向と日陰ができるはずで、写真からテクスチャをつくる以上そこは諦めるしかないのかな…… (テクスチャの日陰の部分を後から明るくするとかはできそうだけど)。
 ちなみにアバターから八ツ橋を出せるように仕込むと、 24万ポリゴンあるからアバターランクは Very Poor 、みたいなことを VRCSDK に言われてしまう *1 ので、ポリゴン数を削減するような処理をしないといけないはず。どうやるのか気になる。

*1:上のツイートは 2万ポリゴン見間違えてた

azuma14.hatenablog.com

 その後調べてやったり教えてもらったりしてわかったことは増えてきた。

  • アバターに服着せたり靴履かせたりするときにボーンの移植が必要な理由がよくわからない
    • 追従させるためっぽいけど、もの(メッシュ?この辺の用語もふわふわしてる)との結びつきがどこで設定されてるのか?
  • Blender でメッシュとボーンを対応づけているっぽい?
    • メッシュがポリゴン(三角形の面)でできた立体で、 Unity 上での位置の基準としてボーンを結びつけていそう
      • 腕みたいな場所によって違う動きをするところに袖を追従させるために入れていそう
      • なので Blender で設定したボーンを移植する必要がある
        • 服のメッシュは元からあるアバターのボーンとは結びつけてないし、 Unity 上でそういうことをしなさそう (できないのかどうかはわかってない)
  • sit 時の姿勢を変えたい
    • 足を揃えたい
  • アニメーションを Booth とかで販売/配布している方がいそう
    • VRCSDK によってアバターの設定として Sit 時の動きを設定することができて、 Controller を設定する
      • そこの座ったときの State に、好きな動きの Animation を設定しておけばよい、ということっぽい
  • DynamicBone とか Cloth とかで長いスカートがたまにめちゃくちゃになるのは仕方ない(というかコライダーの設定の難易度が高い)として、 reset avatar したときにちゃんと戻るようにしたい
    • 何も工夫しないと? reset avatar 後にちょっと上からスポーンするせいでどうしてもスカートがめちゃくちゃになりがち
    • 最初の数秒は Cloth オフにするとか、 ExpressionMenu で Cloth のオンオフできるようにするとか……?
  • これはやっている人がいそうだったので、そうやったらできそう (まだやってない)
  • ワールドの遠景をつくりたい
    • 壁ではなくて景色の場合に消失点? 地平線? をどうするものなのか
  • そこそこつくってあとはテクスチャとか、部屋から出ないなら全部テクスチャとか、ということらしい?
    • まだ具体的にどうしたらよいかはあんまりわかってない
  • 衣装ごとにアバターを変えているけど、アバター間でアニメーションとかが乖離しつつあるので揃えたい
    • 素朴にコピペでなんとかするしかないのかな……
  • これは未だに難しいなと思ってる
    • どうしたらいいのか……
    • 人に聞いたらやはり基底のアバターみたいなのをつくっておいてそこからつくる、みたいな感じでやっていっているようだった
    • prefab にして後から設定値を持っていく技もあるらしい