PSF進捗まとめ #2

前回に引き続き作者による週間クリフハンガー #PROJECT_SFツイートのコメンタリーです。こういう「作者による解説」って作品を深く楽しむうえでいいですよね。


深夜の信号機

信号です。

VRChat界隈では、ワールドは「目に見える動き」がなくても案外自然に受け入れられるもので、実装されているとしてもパーティクルや水面シェーダー等の規則的な動きをする効果が典型的です。そこで、この場所では+αで「人の介在を感じさせる動き・人に影響を与える動き」「ただの背景ではなく、強制力のある動き」として明滅する信号機を作ってみました。

この信号はアニメーションではなくシェーダーで実装しており、高さとUVで歩行者用・車用のどの色かを識別して動かすという超アドホック実装となっています。また、「交差点が常に90度で交差する」という制約をかけることで、ヨー方向からどちらの道路に所属するかを計算して配置するだけでいい感じに信号として成立するようにしています1

コメントからは本当は3月下旬の春の気配がする深夜の住宅街が作りたい感(前回の記事参照)が滲み出ているような気がしますが、公式には真夏の夜の信号機です。

この動画ではルピさんがなんか「近づけば消えてしまいそうな、儚げな真夏の少女」的存在感を醸し出してますが、実際は単に自販機までジュースをパシってるだけです。いずれ一緒にギミックを試してもらったりとか動画でちょっとしゃべってもらったりもしようかと思っていますので、ではそのように。


おさかな

手がガラス突き破ってますが大丈夫ですか夏といえば水族館デートです(ほんまか?)。

これはボイドと呼ばれるアルゴリズムを実装して魚を1024匹出してみたものです。この記事を読んでくれている人はこれと同じものを当たり前のように実装できるか、あるいは何をやってるのか全く分からないかのどちらかだとは思うので技術的な説明は省きますが、ポイントとしては時間方向とおさかな方向のループの順序を適当に入れ替えることで1フレームあたり数十おさかなの処理だけで相互作用らしきものを表現しています。

普通の水族館の大水槽で見られる「ボイドっぽい魚群」を観察してみると、動画のものよりももっと(水槽と比較して)小さくはっきりとまとまっています。ただ、動画の場合は実装がシェーダーベースである関係上、魚群がはっきりと分かれるくらいまでクラスタ内の引力を大きくしてしまうと同期を全くしていないのがバレてしまいます。なので、この動画の時点では「通常の飼育環境ではありえない超密集飼育」っぽい展示にしています。あとパラメータ調整が面倒でこれ以上いじりたくない2

この動画の時点では「位置情報のメモリを直接テクスチャとして使ってみたらなんかきれいだった」という理由でになっていますが、あとあとLUTを使うなりして現実的な大水槽の展示に即した魚の種類の分布にします。未来の自分が。

ちなみに、それぞれのおさかなは左右に身を振りながら泳いでいるように見えますがこれは偶然で、前述のような近似計算を実装した結果たまたま発振しているという偶然の産物モーションです。

この動画ではファスさんがなんか「水族館で出会った、ミステリアスな雰囲気と狂気とをあわせもつ少女」的存在感を醸し出してますが、実際は単に「そのままだと絵が地味だから」という理由で水槽を眺めてもらってるだけです。いずれ一緒にギミックを試してもらったりとか動画でちょっとしゃべってもらったりもしようかと思っていますので、ではそのように。


田舎の家の「もと」

日本の夏を再現するためには、日本の住宅をいくらか配置する必要があります。かといって、まったく同じ構造の家のモデルを並べていくと「繰り返し感」が出てしまうので、いい感じに多様性のある家のモデルを数十軒作成する必要があります。

こういった街や建物のプロシージャル生成の先行例自体はたくさんあるのですが、

  • 従来は「上空から俯瞰するのに耐えうるモデルの生成」が目的であることが多いのに対してPSFでは「原寸大」のモデルを横から見ることがメイン
  • 完全に乱数ベースで単一のモデルを作ってしまうとギミックや演出を実装するときに扱いが厄介
  • そもそも実装に時間かけたくない

のでもっと簡単な方法を採用しました。

それは矩形の集まりに窓や扉を手で貼っつけていくという温かみのある手法です。Googleマップ等で住宅街を上から見るとわかりますが、たいていの日本の家は「道路に平行な面を持つ1〜4個程度の直方体の適当な和集合をとって上に1〜2個程度の屋根の和集合を乗っけたもの」に分類されます。なので、このルール通りに豆腐(1枚目のやや上側)と寄棟屋根(1枚目の左側)を組み合わせて壁に扉や窓を貼り付けると家っぽいものができます3。 テクスチャは後でなんとか自動化します4

このようなコンポーネントベースの方法でも自動化はできそうな気はしますが、「玄関は道路に面しているのが基本だが、防犯上や立地上の理由で路地を曲がった側面にある場合もある」「ベランダは南向きにある家が一般には好まれる」みたいなルールを書いていくのも大変そうなので手作業でやりました。

また、ただ家を作っただけだと味気ない(生活感がないと不気味に見える)ので装飾となる田舎にありそうなモデルもたくさん用意して配置します。私の一押しポイントは「ただ横に数個並べるだけで圧倒的『田舎感』が出る長方形のプランター(プラスチック・薄茶色)」です。


試験用ワールド

「作業する前に、作業部屋を作らない」とは私のとあるフレンドの言(げん)です。

今後ワールドの各コンポーネントの写真や動画を撮ってTwitter等に上げることによって承認要求を満たすことが予想されるのでささっと作成しました。住宅街のど真ん中でギミックの実演をしてても変かなと思ったので……。(とかいいつつ信号は普通にワールドに配置してるのを撮ってる)

このワールドでは私のワールドにしては珍しく(?)ノーマルマップが入っています。これは「まあ適当にパーリンノイズを貼っ付けておけばそれっぽくなるだろう」と思ってまあ適当に貼っ付けたもので、たぶんワールド本体もこういうノリで絵作りすることになると思います。


Player-replayer

どこまでも手間のかかることを……!5 6 7 8

アバターを指定した姿勢に追従させる方法はいくつかありますが、Unity本来のIK機能についてはUdonのOnAnimatorIKが呼び出されない(要調査)ため使用できず、Final IKのBiped IKについても細かいチューニングが大変だったり頭のロールが設定できない(要出典)ため、今回は「各ボーンの姿勢を愚直に記録・上書きする」という方法をとりました。

現在のUdonSharpではVRCPlayerApi.GetBone{Position,Rotation}(HumanBodyBones)でプレイヤーのボーン姿勢は取得できますが、HumanBodyBonesをいい感じに列挙したりすることができないらしいので、「『姿勢のコピーと追従するTransformの取得をベタ書きする実装』を自動で生成するスクリプト」を書いて対応しました。あとは適当な長さのバッファに突っ込んだり取り出したりするとリプレイが出来ます。注意点として、ボーン構成(長さや初期角度)が完全に一致したアバターでないと再生時に名古屋駅前みたいになっちゃうので、「任意のアバターの動作を再現するリプレイ装置」を作るためにはそれなりに工夫する必要があると思います。


その他のツイート

はい。

ちなみにルピさんはどんなときでも常にフルトラでわちゃわちゃしてて、ファスさんはこういう時(見栄え重視でない時)はだいたい3点トラッキングで来ます。


次回の記事くらいから本格的にギミック関係も紹介できればいいですね(言うだけはタダ)9