VRChatで個展を開く(その4・作品&技術解説)

ここでは展示品の意図や仕組みについて解説しています。
ほぼすべての作品についてネタバレを含みます。このワールドはPublic化を予定していますので、作品を100%楽しみたい方は実際に実際に会場で見るまでこの記事を読まないことをオススメします。

Element 0: Mismatching (Material)

全体的に、特殊なマテリアル(=シェーダー)を設定することで作品としての機能を実現しています。

マテリアルペン,5本入

VRChatのワールドにある普通のペンは黒・白・赤などそれ自身が意味を持たない単色であることがほとんどですが、この展示では以下のようなメタ的な意味を持つ色や模様を設定することで普通とはちょっと違うペンを実現しています。

  • Unity – New Material
  • Unity – Missing (Material)
  • Unity – Collider
  • Transparent(シェーダーはここ
  • Blender – Selected

他の一部作品にもついているリセットボタンについてはVRC_Scene Reset Positionを使用しました。

正しいはんだごては?

こういうミームを受けて作ったものです1
そばに置いてあるサーモグラフィーは、2つのカメラで普通の視界とPlayer・PlayerLocal・Mirror Reflectionレイヤーのみを対象とした視界を一度別々のRender Textureに描画し、これらを適当に加算することで表現しています。

優美展開

「折り紙の展開図」と「3DモデルのUV展開」が似ていることを踏まえて作った作品です。
メッシュの中心座標から適当な[0,1]の値を作り、各頂点座標を「オリジナルの座標」と「UV値」で補間することで手に持つと展開するようになっています。
三種類のモデル(鶴・風船・兜)はBlenderでQuadをKnifeで切ってから実際に「折る」ことで作りました。
ひとつ問題だったのは、折り紙では一つの部位に何枚もの紙が重なるため、両面を描画するようにすると容易にZ-fightする点です。
幸い鶴と風船は完成時は裏面が全く見えないので、上記の補間値が0.9以上の時に裏面を非表示とすることで対応しました(兜は裏面が見えるため頑張って頂点を調整しました)。

作品をつくる作品

美術館に置かれたメガネがいつのまにか作品になっていたという逸話から着想した作品です。
といってもVRChatでは普通の日用品が床に転がってるのは至極よくあることなので、「ボタンを押すと作品が変化する」「取っ手を持つと持ち運びができる」というインタラクティブな要素を加えました2

スタック・オーバー・苦労

VRChatで普遍的に行われている行為である「VRC_Pickupがついたオブジェクトを積み上げる遊び」に+αの意味をもたせた作品です3
“客寄せパンダ”とか”デパートやモールにあるキッズ用スペース”的な役割として作った作品です。左は「屋根を積むと自動で末広がりになる+重なりの数を自動計算するN重塔」、右は「重ねると自動で名前を付けてくれるハンバーガー」です。


左(N重塔)については各メッシュの原点座標から適当に計算しています。
右(ハンバーガー)についてはバンズの上部にカメラを付けておき、各パーツに専用レイヤーで加算ブレンドするQuadをつけておくことで重なったパーツが何であるかを計算しています。
(各QuadをRGBの各値を0b1111に分解したうちの1 bitのみに対応することで12個のパーツを個別に検出可能)
なんのパーツもない場合は「バンズ」にしたり肉が含まれてないと「〜サンド」にしたりと細かい調整もしています。
また、例のごとくConfigurable Jointでパーツがどこかに吹き飛んでいかないようにしています。

Step-by-Step by Step

足場のマークに立つと「その人だけ」または「その人以外だけ」(左奥だけ)になにかが見える作品です。
前者については「カメラ座標が一定範囲にあるとメッシュが表示されるシェーダー」で実現し、後者については「床下に固定したカメラ(Render Textuere出力)にPlayerかPlayerLocalの何かが写っていて、かつプレイヤーのカメラが一定範囲にないと表示されるシェーダー」で実現しています。
それぞれ見えるものは以下の通りです。

  • 右手前:大量のVRカメラが表示される
  • 右奥:同じ部屋の奥に櫻歌ミコちゃんが表示される4
  • 左手前:Ennichi Playgroundのパノラマが表示される
  • 左奥:二人組が足場に立つと本人たちには見えないハートのパーティクルが表示される(悪趣味)5

二つ目の走馬燈

光り物その一。
前処理として、私が過去に撮影した写真に以下の処理を行って色情報を抽出しテクスチャ化します。

  1. RGBそれぞれのヒストグラムを計算
  2. 写真全体の平均色を計算
  3. ヒストグラムを適当に正規化しテクスチャの1行(256ピクセル)として格納
  4. 平均色は各行の一番右のピクセルに格納6

次に「平面を画像の枚数分横に並べたメッシュ」を用意7し、シェーダーで色情報を描画しています。
この作品ではヒストグラムの「高さ」をfragment shaderで色として表現していますが、これはvertex shader側でポリゴンとして表現するためにはメッシュ全体のポリゴン数が多くなりすぎると判断したためです。

VTuber Particle

VTuberチャンネルの規模をGPUパーティクルとして表現したものです。
チャンネル登録者数はYouTube APIより取得し、サムネイル画像の色とチャンネル数を適当に正規化してRGBA形式でテクスチャに保持しています。
当初はチャンネル同士のおすすめチャンネルの関係も可視化しようと思いエッジ情報のテクスチャ作成までは行っていましたが、おすすめチャンネル機能はTwitter等と違い利用度合いがまちまち(知り合いだからといって必ず登録するものではない)ことでグラフが疎になりそうだったのでやめました。
ちなみに開催時の★の5チャンネルはです8

距離のリアル

今までの来場者との物理的距離を可視化する作品です。
原理としては、

  1. CGIを叩いた際のIPアドレスをMaxMind社の提供するDBであるGeoLite2を使用して経緯度に変換
  2. 経緯度をWebサーバ上の適当なDBに保存
  3. クライアントの経緯度とサーバに保存してある経緯度から相対的な距離と角度を算出
  4. 距離と角度をpng画像にプロットしてVRC_Panorama経由で表示

して実現しています。
第二回開催では、IPアドレスがDBに登録されていない場合9には日本経緯度原点を現在位置として使用するようにしています。

現実世界終末時計

名前の通り世界終末時計をもじった作品で、世界人口とVRChat人口の比を24時間に変換して表示する作品です10
世界人口に関しては調べた限り「現在の世界人口を返すAPI」を見つけることができなかったので、国連から報告されている予想人口推移をもとに計算しています。
VRChatのプレイ人数に関してはこのAPIからとっています。
表示は上記の「距離のリアル」や最初の部屋の時計と同じVRC_Panorama画像の一部として書き込んでいます。11

玉虫色の視点

一見すると「角度によって違った図形が見える作品」ですが、実はプレイヤーのIPアドレスによって全く異なった図形が見える作品です。
そのため、一人で見たり無言で鑑賞しているだけでは作品の「本質」が全くわからない作品となっています(Twitterを見る限り、後日写真を共有したときに初めて気づいた方もいたようで、ニヤニヤが止まりませんでした)。
作品名は「異なる視点(見る角度)によって違ったものが見える」と「異なる視点(プレイヤー)によって違ったものが見える」のダブルミーニングになっています。

VRChatにおいて、人によって見えるオブジェクトが異なる現象はごくありふれたもので、VRChatユーザも(ローカルミラー等のよく知られた形態の場合は)それを普通に事だと認識しています。
(これに関してはカンナさんxclocheさんの記事でも触れられています)
そこで、この作品ではこの現象を作品として表現するとともに、気づいたときのインパクトを大きくするためにわざと単体では面白みにかける「見る方向によって見え方が違う物体」12でブラフを張る形で表現しました。

実装としては、外部のWebサーバのCGIを使って「IPアドレスから適当にハッシュ値をとって色に変換した画像」をVRC_Panoramaで表示し、カメラでVRC_PanoramaからRender Textureに変換してからシェーダで採取して表示するメッシュを決定しています。
壁に写っているスポットライトも実はUnityのLightではなく単なるテクスチャで、IPによってUV座標を変えているだけです。

ちなみに、VRカメラのエフェクトを使うと全てのメッシュが見えてしまうため、「シェーダーでclip(-1)をかけたBox」を置いておくことで対策しています。

これはあなたの作品です

VR環境だけで使用できるカメラのとあるエフェクトを使うことで説明文と作品本体が見えるようになる作品です。
説明文については、Illustratorとかでsvgを書き出し、Blenderでfbxに変換しています。
なお、対象としているエフェクトは法線ベクトルのノルムによって色の濃さが変わる?ようなので、説明文モデルをUnity上で垂直方向にスケールすることで読みやすくしています。

ハイパースマートスピーカー

「もしも任意の判定問題(答えがYesかNoかのいずれかである問題)を解くことのできる集積回路(IC)があったら」という仮定のもとでいろいろ作った作品です。技術的な要素は特にありません。
試作品として置かれているモデルに関しては実際に電子部品の選定と回路設計をした上でモデルを作成しているほか、机に置いてあるデータシートも電子工作したことある人から見るとあるあるなネタになっています。
会場で流されている製品紹介動画はなんか作りたかったので作りました。

VRC_WebPanel

完全にメタ的なネタです。技術的な要素は特にありません(あってほしかった)。
本来展示される予定だった「ボイド・ボイド・キューブ」というのは、「岡本勝彦氏が作成した『ボイドキューブ』(ルービックキューブの非外周部の7キューブを取り除いた作品、実際に動く)を更に改良して角の8個以外を除いたルービックキューブ」と銘打った作品の予定でした。
原理的にはWebPanelを使った普通のルービックキューブを実装するめどは立っていて、これの一部を非表示にすることでボイド・ボイド・キューブとして展示する予定だったのですが、あまりにも突然のご不幸で、まだ信じられない気持ちでございます。
心からお悔やみ申し上げます。

1%の本質

技術的にはStep-by-Step by Stepの作品とほぼ同様ですが、説明文を読もうと近づくとSteamVR起動直後の真っ白な空間が表示される作品です13
レンダーキューを可能な限り大きくしてアバターの表示も消えるようになっているので、「あなたが見ていた個展はすべて仮想である」というエモ感をぶつけることを目的としています。
TwoLeafさんの情報をお借りして以下のような表示をしています。

  • VIVEの場合はLighthouseが斜め前後に表示される
  • Oculusの場合はトラッキング用カメラが前方に表示される14
  • デスクトップ環境の場合は代わりに説明文を囲むウィンドウが表示される

これに加えて、VRの場合は対応するデバイスのSteamVRステータスウィンドウも表示されます。

最後の演出

「ミュージアムショップを出たらその展示会の内容は終わりである」「ミュージアム(美術館)の構造は変化しない」という常識を逆手に取った演出です。
最初の部屋に望遠鏡が壁に向かって置いてあるのも一種の伏線を意図したものです。
ちなみに、床に出現するカスミソウには「夢心地」という花言葉があります15

第二回開催時の演出

第二回の開催時にはいくつかの追加要素を入れました。必ずしも技術的な解説ではないですが、もう時効だと思いますしこのワールドは別に謎解きワールドではないので書いちゃいます。

  • アイコン:入場時のエントランスにある私のアイコンの背景は透明ですが、会場を1周すると背景が紺色に変わります。第一回では最初から紺色だったのですが、フィオさんの配信動画中で「一周すると背景色が変わる」という説明をされてしまったので急遽実装しました16
  • 時計:壁に手を突っ込むと持てるようにしました。これはおきゅたんbotさんの配信の打ち合わせの際に「おきゅたんは時間を忘れて遊んじゃうのでタイムキーピングしたい」という要望を某同行者の方から受けて実装しました。
  • けん玉:会場を1周するとエントランスのごく一部の空間で一時的に私がけん玉をしている姿が見えます17。これは私が10分間くらい虚無に向かって延々とけん玉してる動画を予め撮影しておいて表示していました。ちなみに、この演出は低確率でしか発生しないのですが、理由は私にも不明です(VRChatでの動画再生関係はバグが多発するので別に不思議ではないですが)。また、初めてワールドに来た方が見てしまうと月の演出と被って情報量が多すぎるので、IPアドレスがDBに記録されている人(=ワールドに入るのが2回目以降の人)のみ表示するようにPanoramaとシェーダで調整しています。
  • 20個目の展示作品:二週目で会場にどこかに青りんごが現れるので、それを別のある場所に持っていくことで20個目の展示が現れます。りんごは初期状態では透明ですが、VRカメラのあるエフェクトを使うと普通に見えてしまう可能性があるため、メッシュ自体を床下に表示しておき、これをvertex shaderで上にシフトすることで「肉眼では見えるけどVRカメラ(vertex shaderを無視する)には表示されない」オブジェクトを実現しています。
  • イワシ:どこかにイワシがあります。ちっちゃいです。

VRChatで個展を開く(その3・運営と来場者の記録その2)

「1%の仮想」第二回開催も無事(?)終了しました。

この記事ではこの第二回開催分を合わせた統計データをまとめておきます。

全般的な解析結果は前の記事で。

 

来場方法の変更について

第二回では以下の3つの方法のいずれかで来場できるようにしていました。

  1. 私にJoinする
  2. このブログ上のウェブポータルからJoinする
  3. 会場内のフレンドにJoinする

第一回では1.の方法で私が人力インスタンスビーコンとなって会場間を駆けずり回っていたわけですが、単純に体力が持たないのと一部作品についてサーバエラー時の例外処理を実装したので私が直接管理しないインスタンスとして2.を用意しました。

2.については坪倉さんのツール等で生成したPublic1インスタンスへのジャンプURLをウェブ上に公開しておけば機能します。今回はVRC_Panoramaで表示する用のVRCAPIを使ったインスタンス一覧画像(前回の記事参照)にusemapでジャンプURLを上乗せしていました。

来場者の分布(「距離のリアル」改)

GeoLite2を使用して来場者の位置を可視化しました2

日本が点だらけなのは当たり前ですが、アメリカとかヨーロッパからも結構アクセスがありました。一方で(プレイ)人口が多そうな中国はそこまで点が多いわけではありませんでした3

日本列島はこんな感じです4

国別の人数はこんな感じです。この結果は個人的には結構衝撃的で、「日本語以外では一切広報活動を行っていないイベントにもかかわらず来場者の1/3が非日本語圏」でした。VRChatでイベントを行う際はやはりワールド内に英語で一文でもイベントの趣旨を説明しておいたほうがいいと思います……

ちなみに「1%の仮想」では「説明文は日本語でしか書いてないからすまんやで」みたいな言い訳は一応書いておきました。

来場者の推移

1日目(上)、2日目(下)の来場者の推移です。色付きの部分はFriends+のインスタンス(私からJoinできる)、灰色の部分はウェブポータルインスタンス(y23586.netからのみJoinできる)です。

この結果を見ると、インスタンスへのURLをネットに貼り付けておく手法でも案外受け入れられるようです。特に数百人単位の人がウェブポータル経由で入場しているということは「スタッフの乱発的なフレンド承認作業が数百人分減る」ということなので、イベンターの方々にも是非検討してもらいたいと思います5