仮想世界のつながり:VRChatにおけるソーシャルネットワークの可視化

この記事はVRChat Advent Calender 2018の19日目です。昨日の記事はReflexさん(@reflex1124)の「Reflex Shader 2.0の基本的な作りについて」でした。

Summary

In this short article, “How People Live in Virtuality: Visualizing The Social Network of VRChat,” I briefly analyze “how people live in VRChat” by using VRChat API. This includes the fact that a typical VRChat user has no connection with most (99.4%) of the community. And its results imply that in order to grow the Virtual community it is essential to sustain 1) an open and mobile environment, and/or 2) a conservative and creative environment.

注意

この記事ではVRChatユーザーの動向についてのデータを扱っています。このようなデータを評価・議論することに対して不快感を抱かれる方は閲覧されないことをおすすめします1 2。また、いろいろとセンシティブな情報を含むので、事実を歪めない範囲でわざと情報を隠したりブラフを入れたりしています。

導入

VRChatでは日々いろんなひとがいろんな場所で「暮らして」います。一方で、VRChatのシステムの関係上、1ユーザーの直接のフレンド以外の動向はほぼ完全に隠匿されるため、コミュニティがどのように成り立っているかを把握することは簡単ではありません。そこで私は考えました。

「1%の仮想」でフレンドが増えた私なら、APIを駆使してコミュニティの全体像が読み解けるのでは?

……ということで、この記事では私が取得した情報をもとにちょっとしたデータ解析をしてみます3。先に言っておくと、フレンドの皆さんごめんなさい。

背景

VRChatにおける「ワールド」の概念4は、私なりの解釈では以下の2つの尺度で分類できます。

  • 公開 or 非公開:ワールドへのJoin(入場)がどの程度開かれているか。基本的にVRChatではフレンド関係(他者からの信任)によってワールドに入れるかが決定しますが、後述するように例外もあります。
  • 自然発生的 or 計画的:ワールドの成り立ちが意図されたものかどうか。イベントとして開かれるワールドは「計画的」に、逆にPublicが普通のワールドは「自然発生的」とします。

これを私の知っている範囲で公開されている情報をもとにプロットしてみると以下の図のようになります。1%の仮想を除き単発のイベントに関しては表示していません(数が多いため)。

どこか間違っている箇所があればTwitterとかVRChatとかでお気軽にご指摘ください。また、この図は「右/左/上/下に行くほど良い」ということを意味するものではありません

「インスタンス作成計画」とは単にインスタンス作成のために事前に打ち合わせやセットアップが必要なことを指します。逆に「インスタンス管理者」はワールドIDを知っている人であれば誰でもなることができます。
以下、簡単な説明です。

  • Japan Shrine, Fantasy Shukai jou, Japan Townは定番中の定番ワールドで、なぜか(トロール等の存在があるにもかかわらず)伝統的にPublicのインスタンスが開かれます。1619Hz:IIも同様ですが、こちらは「初心者の交流」という目的がワールドに設定されているため、少し右側に配置しています。
  • 1%の仮想は以下の入場方法をとっているため、図のような配置となっています。
    • 第一回:私か会場内フレンドへのJoin(私へのフレンド申請は順次許可してました)
    • 第二回:私か会場内フレンドへのJoin+専用ページ(公開)からのJoin
    • Public:Public化されているため誰でもインスタンスを作成できる
  • バーチャル集会場Club.DelicはTwitter等からは入場方法が見当たらなかったため、公式ページやTwitterが存在するSilent ClubKemono Clubよりも下に配置しました。
  • GHOST CLUBは「オーナーに日記を書く必要がある」「皿を回す必要がある」ため最も右下に配置しました。

また、これらのワールドの「インスタンス」の意味することはそれぞれの色によって全く異なります。青色は基本的にPublic化されたワールドで、必要に応じてインスタンスが作成される(または既存の適当なインスタンスがプールされる)ため、「インスタンスID」に特に意味はありません。一方で、黄色や赤色の場合は、特定の用途のためにインスタンスを作成し、かつ集団の大部分が長時間滞在することが多いため、「特定のインスタンスに入る」ことが大きな意味を持ちます5。言い換えると、図の左ほど「ワールド本体を楽しむためのもの」、右ほど「人との交流やイベントを楽しむためのもの」といえます。

問題は、一番左上の分類「以外」の領域です。というのも、これ以外の領域はフレンドがいないと内情(誰がどの時間帯にいるか)を知ることができないため、フレンド数が多い人でないと解析自体ができないためです。なので、それを以下で見てみます。

評価方法

直近数ヶ月のフレンドの滞在しているインスタンスIDおよびそのインスタンスにいるメンバーを断続的に取得しました。取得手法や定量的な詳細についてはこの記事では非公開としますが、別に非合法的なアレではないですし、ググれば出てきます6

評価:隣接行列

まずは隣接行列です。これは一言で説明すると「VRChatユーザーを縦と横に並べて、つながりのある2人の交点に点を打ったもの」です。ここでは仮に「5時間以上同じインスタンスにいたことのある人は『つながりがある』」と定義しています7

VRChatユーザーの隣接行列。もうこの時点で記事の結論が出ている


図です。縦横にVRChatユーザー1673人8が並んでいて、白色のマスが「つながり」を表します。例えば、100番目の人と200番目の人につながりがあるかどうかは「左下から上に100ピクセル、右に200ピクセル進んだところが白色かどうか」で判断できます。ここではigraphのinfomapでクラスタリングしてインデックスを入れ替えており、クラスタの構成人数が多いほど左下に来るように配置してます。各小行列(白色が正方形の形になっているところ)はクラスタ(仲良しなグループ)を表します。

この図を見ると、明らかに「普通のVRChatユーザーはクラスタ外の人とはほとんど交流しない」ことがわかります(繰り返しになりますが、図の大部分を占める黒い箇所は「つながりがない」ことを意味しています)。また、黒色の部分の中に短い縦線や横線がありますが、これは「メインに所属しているクラスタの他に別のクラスタにも繋がりがある人」を表しています。

フレンド

次に、この図の私のフレンドのみを赤色で着色してみます。

私のフレンド(赤色)。私は真ん中の小さな赤いところにいます

この図で特徴的なのは3番目に大きいクラスタにフレンドがほとんどいない点です。この図において最大のクラスタ(最も左下)はファンタジー集会場とバーチャル集会場によくいる人のクラスタで、2番目はとあるクラスタ(クラスタの方針を考慮して以下🍤とします)ですが、私の正直な感想として3番目はどんなクラスタなのかはほとんど知りません。この例からもVRChatの交流が非常に疎であると言えると思います9

イベント系クラスタ

イベント系クラスタ(7箇所あります)

イベントを定期的に開いていてかつTwitter等で宣伝している(と私が勝手に判断している)クラスタを着色するとこのようになります。どこがどれかについてはプライバシーとかもありますので伏せます。興味深いのはイベントの規模とクラスタのサイズが必ずしも一致しない点で、複数インスタンスが並列して開かれるイベント(の主催者がいるクラスタ)でも構成人数が10人程度のところもあります。この理由としては、開催インスタンスが多すぎると逆に流動性が高く大きなクラスタが形成されづらいものと思われます。

 🍤

最後に、2番目に大きいクラスタについて軽く触れます。ここで唐突に隣接行列の「つながりの多さが上位95%の人」を着色すると次のようになります。

「つながりの多さが上位95%の人」を着色した図

この図より、明らかに🍤クラスタが特異である(クラスタ内部での交流が極めて盛んである)ことがわかります。理由としては、このクラスタでは継続的にクリエイティブでエモエモな「なにか」を行える環境が整っているため、リピーターが非常に多いことが考えられます。

評価:グラフ

“VRChatter Particles”(エッジの色の濃さは一緒にいる時間を反映)

景気づけにグラフにしてみるとこのような感じになります。少し大きめの丸が私です。

その他の情報

その他の豆知識をずらずら並べると以下のようになります。

  • 日本人コミュニティで最も大きい(と思われる)クラスタはファンタジー+バーチャル集会場勢であり、規模は60人程度と推定される
  • 🍤はクラスタ内部での交流時間が極めて長く特異
  • 30人程度で強連結(全員が全員と仲良し)で滞在時間が超長いクラスタが存在する10
  • 普通のクラスタの構成人数は平均11人程度、中央値7人程度
  • 普通のVRChatterが「長い時間をともにする」フレンドは多くても6人程度。一方で30人以上と深い交流を持つ人も5%程度存在する
  • 上記の隣接行列の非ゼロ要素は全体の0.6%である(すなわち、平均的なVRChatユーザーは仮想世界の99.4%とつながっていない

感想

集会場と🍤はクラスタの方針が間逆であるにもかかわらず1〜2を争う巨大なクラスタになっていることは非常に興味深いです。つまり、仮想世界のコミュニティを大きくするには「流動的でオープンな環境をつくる」か「保守的でクリエイティブな環境をつくる」の両方の手法が有効であると言えます11
一方で、「だれもが瞬時につながることができる」といわれる仮想世界で平均的なクラスタの人数が10人程度であることも特筆すべきかと思います。やはりこの理由としては「PCスペックの仕様上、1インスタンスに入れる人数が30人程度が限界」というのが根本的な理由としてありそうです。前にも書きましたが、VRChat運営においてはインスタンス間の情報伝達をもうちょっとうまくやってほしいなと思います12

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を無視する)には表示されない」オブジェクトを実現しています。
  • イワシ:どこかにイワシがあります。ちっちゃいです。