Imaginantia

思ったことを書きます

良さのレイヤー

「良い体験」という言葉があります。いいゲーム。いいワールド。良さという概念は実在します (どれくらい良いかは具体的に判断可能である) が、根本的に「良さのレイヤー」が違うことがある、という話を書きます。

端的に言えば、楽しいゲーム・綺麗なワールドは「良い」んですが、それだけでは新たな体験は得られない (=「良い」とは言えない)、という話です。

1.

所謂シンプルな「良さ」、という面ではゲームなら「操作が楽しい」「エフェクトが気持ち良い」「スコアが貰えて嬉しい」、ワールドなら「綺麗」「過ごしやすい」「いろんな物がある」というような成分があると思います。

それは確かに「良い」んですが、それによって「高品質な体験」が得られるとは限りません。むしろ場合によっては「ありきたりすぎて面白くない」まであります。

ゲーム作り初めてみたいな人がやろうとする領域がこの辺りだと思います。何故なら、こういうところから始めるしかないから。

だけど、そういう部分だけ追求したところで「先」には進めません。

2.

先にあるのはゲームなら「戦略性がある」「段々うまくなれる」「驚きがある」、ワールドなら「世界観がある」「面白いものが見られる」「ギミックがある」みたいな領域だと思います。

つまりさっきよりも少し外側の世界です。小さい良さを積み重ねて作り上げることができる「良さ」の観念です。

これは「努力」の領域じゃなくて「考える」ことで良くしていくものです。つまり色々見て「目を良くしていく」ことで段々わかっていくものだと思います。

なにかつくりたいもののベースが既にあり、それを段々改善していくことで「良く」していくフェーズです。

3.

次にあるのが「コンセプトが存在すること」です。「何をさせたいのか」「何のために作ったのか」「何故こうはしなかったのか」に適切に答えられるような作品。

これは作る前の話。もっと考える領域。

コンセプトがしっかり立っている作品は、もう 1. や 2. のような「小さな良さ」はそこまで出来に関係ありません。コンセプトが在る時点で「良くなっている」のです。

とはいえ、これができる人間は「小さな良さ」もちゃんと立てることができます。これは即ち、コンセプトがちゃんとしていると思っていても、小さな良さがちゃんと存在していないのなら、それはコンセプトが出来ていないということです。

例えば「歯車が動力伝達によく使われている世界のワールド」を考えるなら、その時点で噛み合わない歯車は作れないのです。

「何度も戦うことで強くなっていけるゲーム」にするなら、状況把握がしずらいUIにはできないのです。

コンセプトは実現することに意味があります。もとい、実現されていない要素はコンセプトではないのです。

「うまくコンセプトを実現できなかった」という状況は発生しないのです。

ゲームを名乗るなら、ゲームになっていなければならないのです。

4.

さて、その上にやっとあるのが「新規性」という良さです。みたことないものはよいもの。

とはいえ勿論いたずらに新しいものを作ってもしょうがないです (存在しないものなんていくらでもあるんですから)。その新たなものを作ることに価値がある、という状況が大事です。

例えば Portal は「パズルとFPSを組み合わせた」という新しさがありましたが、そんなことよりも「ポータルによって今まで体験したことのない物理法則とその応用を学習できる」ことのほうが圧倒的に大事です。

ここからわかるように例えば「組み合わせること」による新しさは「興味深い新規性」ではありません。組み合わせることによって発生/派生した新たな概念が大事なのです。

ちなみに「今までに無いゲームシステム」みたいなのは、ここには入りません。それは「何がしたいか」ではなく「何をするか」です。そこではなく「そのシステムによってどんな効果が期待できるか」が大事なのです。

Amebient は「雨が金属を弾いて音が出る」という (VRChat的には) 新しいシステムがあるわけですが、そんなことよりも「みんなで自由に雨で演奏できる」方が大事なわけです。

まぁ作り手にとっては、そういう「コンセプトをどう実現するかの具体的アイディア」はありがたいものであり、「良い」ものだとも思いますが。

この辺になってくると枯れた媒体 (「絵」とか) にはなかなか難しい領域になってきますね。

5.

そして、次にあると思っているのが「概念の提示」です。

そのゲームをプレイすることで、そのワールドに行くことで、「今まで視えなかった概念を認識できるようになる」こと。

本当に新しい作品というのは、体験しはじめたときには理解できないはずなのです。だけど、体験を通して概念が自分の中に生えて、もはや当たり前にまでなる。それが「体験」の持つ素晴らしい能力です。

The Witness のような。

そこまではいかなくても、まぁ。

個人的には What Remains of Edith Finch が好きです。これは「体験という概念」を体験を通して教えてくれる。

ワールドだと…あるだろうか。CUE [Archive] とかそれになってたらいいなとは思いますけどね。小さな「音楽演出手法の1つの提示」です。

PROJECT: SUMMER FLARE も類する感じがありますね。「物語体験手法の1つの提示」だと言えます。

とは言え「体験して頭がぐちゃぐちゃになるほどの作品」はまだ見たことがない気がしますね。そのうち出てくると良いな。

海外系のデカいワールドだとどうにも「大衆向け的ゲームの文法」を引用している感じがあり、こういう「インディーゲームの持つ異常な鋭さ」みたいな成分をあまり見ないんですよね。

面白いワールド、良いワールドはいくらでもあると思うんですが、「(VRChatにある) 見なければならないほどの作品」はやっぱりまだまだ少ない感じがあります。

この辺になると媒体はもはやあまり関係なくなって来たりするんですよね。Inscryption とかね。

終わり

私はそういう「新たな概念を提示してくれるような良いワールド」を求めています。作りたいです。

そしてまぁ、わかると思うんですがそういう領域の作品って「数ある作品」と存在のレイヤーが違うんですよね。戦っている場所が違う…いえ、もはや「戦っていない」のですが。

ジャンルを絞ってどうとか、綺麗なレンダリングを目指してどうとか、面白いストーリーでどうとかじゃないんです。もっと上なのです。

努力が報われたりするようなものではない。技術でどうにかなるものでもない。もっと根幹にある領域。

「本当に面白いもの」というのはそういうところにあると思っています。

 

とは言え、勿論この話は「普通に良いゲーム・ワールド」を否定するものではありません。むしろそれがあってこそ、です。

ただ「良い」と言ったときにどの領域の話をしているのかは、意識的であっても良いのかもしれません。

作品の褒め方、という話でもありますね。コンセプトが立ってないワールドでも、世界観を褒めることはできるのです。褒めることと批判することは同じですね。共に「どこに境界があるかを示す行為」です。

Z-Fightだって本当にどうでもいいことなんです。コンセプトがちゃんと実現できていればもうそれで良い。それにその領域に居る人間なら、Z-Fightを指摘されるのは嬉しいことだと思いますから。

良くない部分を指摘されて気が滅入るのは、自分自身の作品を信頼できていないからです。

責任を取る覚悟は大事です。

みんなでがんばりましょうね。

 

ちなみに、今回書いた5つの階層はなんとなく書いたらそうなっただけで、何かはっきりした基準があるものではありません。(これをはっきりさせることに意味はありません)

私はそういうのに名前を付けたりする行為が嫌いです。自分で考えることに価値がある。

各々がいろんな体験をして、たくさん考えていくしかないと思います。

おわり。

日記 220901

久しぶりに日記を書きます。

最近いろいろがあって大変です。いろいろというのは本当にいろいろで、良いことも悪いことも。

生活面はたいへんのんびりといい感じなんですが (睡眠時間はなんとも言えませんが)、作業が。いろいろな。

ふつうに頑張らなきゃいけないやつ、やればできる気がするのにやってないやつ、期限とか無いから放置すればいいのにやってるやつ、空き時間がなくてできてないやつ、勢いでやるって言ったのでやるしかないやつなど、様々です。

8月終わりに整理ができていたらいいなと思っていたんですがなんかむしろ増えつつあります。これは時期が重なっているというやつです。

やっとあたまぐるぐる (仕様を決めないと不安でそれ以外何も手が着かない現象) が落ち着いてきた (仕様が決まった) ので3番目のやつ (Twitterに上げてるアレ) を放置して本来やるべきことをやってい…るつもりです。

が、ちょっと負債が多すぎた感じでしんどみです。自由が永遠に来ない。

なんか予定 (?) ではまた新たな何かに手を出そうとかしていた気もするんですがとりあえず余地がなさそう。ぶっちゃけおしごとがたいへんです。

9月には全ての整理がおわったらいいなあ。最近作り始めたアレもさっさと終えないとだし、5月頃2月頃に作り始めていたアレもどうにか世に出したいです。新たなワールド案も出てきてしまったんですがこれは来年に回します。

やらなきゃいけないことも多いですが、やりたいことも多いのでその点はいいところです。多すぎてメインが死んでるのは良くないですが。

しんどみの根幹になっているのは2つくらいなので、それがどうにかなれば実質自由だと思います。

もうちょっと走ります。いえ、走らなきゃいけないです。どうにか。

おわり。

浴衣2022

いちおう解説を書きます。

まずコレは「アバターを透過させる下地」「糸っぽいメッシュ」の2つから成り立っています。それぞれ作り方が全然違うというか、まず無関係なものです。

下地

お分かりの通りステンシルです。大昔に「輪郭線だけ」はやったことがあったんですが、アバターと共存させるのが微妙に大変でした。

大まかな仕組みは次の通り:

  • RenderQueue は 1200 くらいを使ってます (つまり他全ての描画より先に描画処理を行います)
  • 浴衣をとりあえず描画 (Depthだけ・色は描画しない)、このときにステンシルに書き込み
  • 浴衣のアウトラインを描画 (ついでにステンシルを 0 にする)
  • ステンシルを初期化しつつアバターを描画 (浴衣に被ってる部分は Depth によって正しく遮蔽される) (コレもついでにステンシルを 0 にする)
  • 最後に浴衣をもう一度描画、ステンシルを 0 にしつつ、この時に ZTest Always にして SV_POSITION の z を強制的に 0 (reversed Z における far clip) にすることで Depth も初期化
  • あとは普通にシーンを描画するだけ

これでわかる人には説明が終わっているとは思いますが、折角なのでもうちょっと解説をします。

StencilとDepth

おおよそ箇条書きで書きます。

  • レンダリング時には「色」「深度」「ステンシル」という3種類のデータを内部的に保持している
    • 「観えている映像」(最終レンダリング結果として現れるもの) は色のみ
    • それぞれ機能が違う (描画命令レベルで違う) が、結局「各ピクセル毎に格納されているデータ」があることに変わりはない
      • それぞれ Color Buffer, Depth Buffer, Stencil Buffer と呼ぶ
        • Buffer っていうのは格納場所みたいな意味で使われている
    • これらは中に入れることができる値も違う
      • Color Buffer は「4つの小数 (RGBAのこと)」
      • Depth Buffer は「0から1までの小数1つ」
      • Stencil Buffer は「0から255までの整数1つ」

こんな感じ。(DepthとStencilの色付けには特に意味はない)

  • 色はまぁ当然、視界を映すためのデータ
  • 深度は物体の前後関係を正しく処理する為のデータ
  • ステンシルはポリゴンによる範囲選択によってポリゴンを消したりする為のデータ
    • 「現在の Stencil Buffer を参照してテストを行い」「シェーダ設定に基づいて書き込みを行う」ようになっています
    • 何もしなければ一切使われません

というわけで、まず輪郭だけが出るシェーダを考えてみます。

  • 膨らんだ部分から元の部分を消せばよい!
  • まずオリジナルの領域をステンシルでマークする
    • ステンシルの書き込みをします (Ref 17Pass Replace ってやれば「実際に描画を行う時、Stencil Buffer の値を 17 に更新する」という命令になる)
    • 背景の色を残しておきたいので ShaderLab で ColorMask 0 を指定します (Blend入れるよりも (無駄な処理をしないので) 良いと思う)
  • 膨らんだモデルを描画する時にステンシルに被ってたら消す
    • Ref 17 にして、Comp NotEqual ってやれば「Stencil Buffer の値が 17 じゃないときにテストを通る」ようになります

できました。ちなみにこの2段階の処理はシェーダで2Pass書いてもいいですが、実際に GameObject・Material・シェーダを2個分用意して、異なる RenderQueue で実行させるのでも大丈夫です (複数オブジェクト使うときにはこの方が良さそう)

1個目

2個目

膨らんだモデルはまぁその辺のToonShaderで作れると思います。今回の私の浴衣はlilToonです。

本題

ではメインの話に戻りますが、まずVRChatのアバターとして持っていくことを考えると考えなきゃいけないことがいくつかでてきます。

  • どんな順番で世界・他のアバターが描画されるかわからない
    • 先程の例は単体ではそれっぽく動くが、他のオブジェクトの位置関係によっては破綻する
    • 特に、深度を何も弄ってないので「輪郭線だけにみえるが、中身が (深度的には) 実在する」感じになってる
      • つまり手を突っ込むと消失するように見えるということ
      • ついでに言うと服のRenderQueueが高い (半透明など) 人はこのオブジェクト越しだと服が消える
    • RenderQueue を高くしても半透明系と仲が悪くなるだけ
    • ZWrite On をやめれば深度は出なくなりますが、自分自身との遮蔽計算がぐちゃぐちゃになる (見るに堪えない感じになる)
    • 深度は正確にしておくとりあえずめっちゃ早めに処理しておく必要があるということ
  • 他にもステンシル使っている人がいるかもしれない
    • 競合しないタイミングで描画を実行処理が終わったらステンシル値を元に戻す

ぶっちゃけステンシルの大変さの9割は「如何に破綻を少なくするか」だと思います。

まぁ今回に関しては最終的には「RenderQueueをめちゃ低めにして」「深度をちゃんと出す」だけです。

ちなみに先述の「ステンシルに応じて消す」のはできるはできるんですが、あまりにも消えすぎて勿体ないので「普通に前後関係で消させる」「最後に、下地が残ってたら全部貫通させる」ようにしています。

左: ステンシルで消すと「画面上の領域」として全部消してしまう、右: 深度で消すなら細かい輪郭線がちゃんと残る

というわけで:

  • (1回目) 最初のステンシル書き込みはそのまま
  • (2回目) 輪郭線を描画するときに、ステンシルに 0 を書き込む (Pass Zero を指定する)
    • 下地じゃない部分のステンシルを全てリセットしていきます
  • この間にアバターをもちもち描画する (上と同様にステンシルに 0 を書き込む)
    • これは「浴衣より手前にアバターが来た時に、不可視となった領域のステンシルをリセットする」ため
  • (3回目) ステンシルが所定の値になっている場合、ステンシルに 0 を書き込みつつ (リセットしつつ) 深度に 0 を書き込む
    • 尚この時 Depth Test を切る (遮蔽物があっても描画させる)
      • どうせステンシルが所定の値になっているのは可視な領域だけなので大丈夫
    • この 0 というのは「一番遠い値」を指していて、つまり「そこには何もなかったフリをさせる」ということです
    • そうするとその後でも上書きして描画できるようになる

深度に 0 を書き込むのは、vertex shader の出力 SV_POSITION の z の値を直接弄ることで行っています。

v2f vert (appdata v) {
    v2f o;
    o.vertex = UnityObjectToClipPos(v.vertex);       
#if UNITY_REVERSED_Z
    o.vertex.z = 0;
#else
    o.vertex.z = 1;
#endif
    return o;
}

まとめると:

  • (1回目, Queue = 1205) Stencil { Ref 17 Pass Replace } ColorMask 0
  • (2回目, Queue = 1206)
    • オリジナル領域 Stencil { Comp Never } (消すだけ)
    • 輪郭線 Stencil { Pass Zero }
  • アバター描画 (Queue = 1207, 1208) Stencil { Pass Zero }
  • (3回目, Queue = 1210)Stencil { Ref 17 Comp Equal Pass Zero } ZTest Always ColorMask 0
    • (vertex.z を far clip へ飛ばす)

以上です。ちなみに実際の Ref の値は違いますがまぁ。(Ref 80ReadMask 240 WriteMask 240 を使ってます)

ここまでやれば後は何をやっても大丈夫 (深度が適切なので破綻することはない) です。

糸メッシュ

なんかいい感じに模様入れようと思って作りました。Houdini製です。

  • Blender に浴衣メッシュを持っていって余計な情報 (weight系) を全て削除
  • それを Houdini に持っていって糸メッシュを生やす
  • それを Blender に持っていって Transfer Mesh Data で weight を乗せる
  • Project From View で適当に UV を乗せる
  • Unity に持っていって着せるだけ

面白いのはメッシュ生成くらいで、他は全部やるだけです。

メッシュ生成も上のツイートがほぼ全てを説明していますが、まぁちょっとだけ書きます。

やってることは:

  • ある点を始点、適当な向きを移動方向として
  • 次を繰り返す
    • 現在の移動方向に向かってちょっと進む
    • 現在の点に最も近いメッシュ上の点を算出、そこへ移動
    • 移動方向を「現在居る面」に射影
    • 現在の点に頂点を追加、前回の点と結ぶ

こうすると「メッシュに沿ってまっすぐ進む曲線」がつくれます。

ちゃんと書くと:

// Attribute Wrangle, Run Over は Detail (only once)
// 1番目の入力に浴衣メッシュが突っ込んであります
vector firstPos = ...;
vector firstTangent = ...;
vector cp = firstPos;
vector tangent = firstTangent;
int c = addpoint(0, cp);
for(int i=0;i<100;i++) {
  cp += tangent * 0.01; // ちょっと進む
  int prim;
  vector uv;
  xyzdist(1, cp, prim, uv, 1); // 最近点を計算
  cp = primuv(1, "P", prim, uv);
  vector cn = primuv(1, "N", prim, uv);
  tangent = normalize(tangent - dot(tangent, cn) * cn); // 面に射影
  int p = addpoint(0, cp); // 頂点を追加
  addprim(0, "polyline", c, p); // 結ぶ
  c = p;
}

実際には、加えて「毎ステップ、進行方向を法線を軸にちょっと回す」処理が入ってます。(matrix m = ident(); rotate(m, 0.0155, cn); tangent *= m;) この回転角度がガチャ成分になっていて。

左から順に 0.0101, 0.015, 0.0155

いい感じの値を見つけるのに苦労しました。初期位置もちょっとずらすとめちゃくちゃ変わります。まぁこれくらいならガチャしてもいいと思います。

ちなみに左右の下駄にもそれぞれ線を別で引いてます。

最後にPolyWireに突っ込んで終わりです。便利やね。

というわけで糸メッシュができました。13万ポリくらいあります。多いけど描画範囲狭いしまぁ大丈夫でしょ。

おわり

まぁわかればシンプル。糸生成器は実は omochi museum で使ったもの (導線を引くために) だったので作業量は多くなかったです。

元々は他にもやりたいことがあった (浴衣を通すとなんか輪郭線で出来た海みたいなのが広がってるとか) んですが、無理であることに気づいてやめました。

なにかの参考になれば幸いです。

 

あ、大事なことなんですが、複数人が同じようにステンシルを使うと影響しあってしまうので何が起きるかわかりません

例えば私のアバターはもしも RenderQueue 1206 でステンシルを全消しするシェーダがあったとすると貫通部分がぐちゃぐちゃになります。

運用には気をつけてね

 


追記: Unityにおける深度は実は2種類あります。1つはさっき言ったもの。もう1つは、「シェーダで取得できる _CameraDepthTexture」です。これは似て異なるものです。

カメラのbokehの実装などに使われるこの Depth Texture は「他全ての描画を行う前に ShadowCaster パスを使って生成された Depth Buffer をテクスチャにしたもの」です。

つまり「描画途中の Depth Buffer が参照できる」わけではありません。(それは GPU の仕組み的に難しいと思います)

で、ShadowCaster パスは Render Queue の影響を受けない。そして複数の ShadowCaster パスを Shader に記述しても1つしか認識されない

つまり色々と先程ステンシルで頑張って組んだ仕組みは ShadowCaster 上では動きません。つまり、あの浴衣は正しくボケてくれません

なんか方法あるのかしら。しらない。

まぁ。複雑な描画を完璧にやるのはむずかしいなというところです。

イメージ時代の終わり

「AI」が楽しく創作をしている今日この頃、それによっていろいろな反応が出ているのを見る現在です。

いろいろ思ったことをとりとめなく書きます。

なお、この文章に出てくるAIという単語は、最近話題のアレに類するものを指しています。

創造性

よく言うのが「AIが作った作品には意思が無い」というものですが、果たして人間に意思はあるのでしょうか。

即ち全ての情報は観測されなければ実在しない故に、その「意思」を測る (存在を確かめる) には成果として表れなければならない、という結論に至るのではないかと。

私は「観察者が好きに補完して想像してね」スタイルの作品が好きではないので、この「意思の明示化」には概ね賛成する立場ですが、同時にこれは多くの既存の作品を潰す方向性だとも思います。

そんなにも絵の意図が実在するものでしょうか?

逆に、AIの生成した絵には意図はないと誰もが言えるものでしょうか?

全ての立場に関してニュートラルであるという立場であるためには、基本的には前情報を多く持っていてはいけません。今回のケースにおいては「作者が人間かAIかという情報」は、ニュートラルな立場に於いては知ってはいけないものです。

その状況で「この絵は意思があるかないか」を以て「評価」することは、現在とても危険なのではないか、という考えは一般的認識だと私は思っています。

当然偏った立場の人間が宣うのはまぁ自由ですが、私はそうありたくないので、このニュートラルな立場を取ります。

 

ところで面白いこと (良いとも悪いとも言ってません) を言ってるらしい文書があったのでちょっと見ました。

元々昔から (1961?) "Creativity" をどう扱うかについてのモデルとして "Rhode's 4-P model" というものがあるらしいのですね。"Product" (最終出力), "Person" (作成者), "Process" (過程), "Press" (環境) の4つ。

こいつは最初から「テキストベースの画像生成システムからHuman creativityをどう識別するか」という視点で文章を書いていて、例えば「生成画像は完璧とはいえないものの時間の問題なので、ProductそのものではHuman creativityを測れないだろう」「良いpromptを書く能力は評価に値する」「コミュニティも大事」みたいな感じのことを書いてます。要は「最終出力以外の部分においては、Creativityが存在する」という主張。

…まぁそうね。そうだと思う。

で、見ての通り、これは「画像生成システムを利用した絵の話」なので、一般的な創作物の話ではないです。あのツイートはミスリーディングじゃないかな。

 

さて、ところで一般的に「最終成果物ではなくそれ以外で評価する」というのはさほど認められる立場ではないと思っています。(この文章は上の論文の姿勢を否定してないですよ。)

だって作品は"それ"じゃないですか。それを「作品」と呼んでいるではないですか。

所謂「芸術」という領域はずっとこの「異常な評価軸」をやってきたのだと思っていますし、それでも続いてこれたのだと思いますが。

多くの人間がSNSを通して「評価」という行為に慣れている現在、もうちょっと状況は変わっていくような気がしています。

「良い絵だ」という建前としての評価が剥がれていくような。それこそNFTはもはや建前がなくなった世界だと思いますが。

 

「最終成果物では人間とAIの区別ができなくなる」という前提において、それではどうすればいいのか、という方向性は大きく2つだと思います。

1つは「諦める」。AIは確かに人工知能と名乗るに値する程度に賢くなった。はい。それでいいんじゃないでしょうか。私はこっちのほうが潔くて好きです。

わざわざHuman creativityを見出そうとするよりも、シンプルに「AIの吐いた絵も良いものである」という評価が素直であり、そして多くの人の直観ではないかと思います。

もう1つは、言及された通りに「意思・過程・環境を作品に含める」ことです。それは「説明文あっての作品にする」ということです。

私はこれを「自ら敗北を選ぶ行為」だと思っているので、あまり好きではないです。何故ならわざわざ説明文なんて書かなくても良い絵はたくさんあるのですから。

自らを敢えて「AIと区別しようとする」行為はほぼエゴだと思うのでまぁ勝手ですが、それによって作品が残念になるのは寂しいです。

ちなみにNFTは全部コレだと思います。

内挿の広大さ

これは唯の問題提起ですが。

「AIができるのは内挿だけ」、という言明をよく見ます。何かと何かを組み合わせるのは得意だけど、新たな何かは生み出せない。

ただ、ところで、「創作というのは昔から作られてきたいろいろなものを組み合わせていくこと」という言明もよくみます、よね。

そこで考えるのは。「確かにAIは内挿しかできないとは言うが、もしもそれでみんなが満足するのならそれで十分なのではないか?」と。

例えば組み合わせるだけでもびっくりするようなものが生まれていることはまぁ見ての通りですし。

何よりも「一切知らないもの」は私達も「理解できない」ものになります。それは結局求めているものではきっとない。

人類はそこそこ歴史があるようなので、まぁ内挿によって作り出せる範囲もそこそこ広いはずです。

「あの感じ」と一言で言えるものはそんなに数多くないのかもしれませんが、でもちゃんと言葉にすれば作れるものが殆どではないでしょうか。

だから、その「内挿しかできない」という観点にはあまり意味はない気がするのです。

まぁ、この話には「内挿を行う空間自体から外れた領域にあるもの」が抜けてますが。外挿をするとかではなく、もっと空間そのものを変える方向が、まだ残っている領域です。

次の話もそれです。

イメージと構造

いいですね。いいですが、見ての通り、この絵はスチームパンクの絵として見ると破綻しかありません。

そのケーブルは何が通ってるんでしょう。そのパイプは。いえむしろそれは本当にパイプでしょうか?

世界観を組み立てる基礎となるものが「法則」ですが、現段階に於いてはAI生成の絵は特に「法則」に従う素振りがありません。

つまり延々とそれっぽさだけを吐き続けています。そしてその精度に関しては人間の能力を越えています。

この「それっぽさ」はそれはそれで評価されるべきものだと思いますが、それによってある種の「人の創造性」が否定されることになります。

「それっぽいだけの模倣作品」というジャンルはもはやAIで十分生み出せうる可能性があるわけです。

それは例えば、「歯車の意味合いを考えずに雑に配置したようなデザイン」を「AIでも作れそう」という観点で否定できうるということです。

 

人間の知性というのはいろんな領域から成り立ってると思いますが、そのうち「発想」と「印象」についてはその独自性を脅かされていると言えるのかなと思います。

そうすると残る領域が「構造」と「表現」です。

何故そこにそれがあるのか、どうやってそうなったのか、どうしてそう描いたのか、そうすると何が起きるのか。明確な法則を以て表現を行う為の「構造」に関する考察。

そしてその印象を何で描くか、どう描くか、描いたものをどう観測させるか。絵に限らない表現形態の模索。

どうせそのうちAIに奪われると思いますが、とりあえずまだ安泰らしいです。

私はそういうものに則った創作物が好きです。だからこれを推します。

 

ところでVRChatワールドの多くは、まぁ、「印象」で出来ていると思います。つまり奪われうる余地があるということです。

ただの「綺麗なテクスチャ」を描く能力はもう代替可能になってしまいました。それっぽいデザインを起こす能力も。

残るのは「何故その風景を作るか」という意思と、その結果として生まれる「空間そのものに備わる一貫した法則」です。

それっぽい世界はもうぽちぽちで作れるわけなので、それっぽいだけではない世界、即ち「それ」が「それ」である根拠を伴った世界が、「気軽に作れない領域」として残るわけです。

個人的にはさっさと気軽に生えてほしいんですが (みんなそう思ってるのでは?)、まぁ、とりあえず「そういうちゃんとした世界」がこれから明確な価値を持つようになったらいいな、と思っています (これはずっと言ってます)。

ちなみに別に根拠を論理的に明示せよという話ではありません。私はただ「自らの意思による一貫した行動」というものが良いものであると思っているというだけです。

それはもちろん、「ただ見たかったから作った」「ただこの印象が欲しかった」ことによる行動を全面的に称賛します。

否定したいのは、「こういう場所にはだいたいこういうものがあるだろうから」「とりあえずやってみたらそうなったから」「みんなそうやってるから」「誰かが言ったから」という曖昧な動機です。

 

これまでの話を整理すると、「AIはそれっぽいものを作ることはできる」「人ができる大事なことは、そのそれっぽさを本物にすること」「そしてその選択に責任を持つこと」ということです。

アルゴリズムとAI

昔はアルゴリズムという語がそこそこ流行っていたと認識していましたが、最近の様子を見ると大凡忘れ去られているような雰囲気があります。

アルゴリズムというのは「一連の手続きに則った情報処理」であり、まぁ最近の某AI群もみんなそれです。が、この2つの語は観点が異なります。

「AI」というのは知性を示す語ですが、ここでの「知性」は「知のあるように振る舞うこと」だと思います。対照的に、「アルゴリズム」の示す内容は「知の振る舞いとは何で出来ているか」です。つまり外側からみたものと、内側からみたもの。

で、「外側からみたもの」には信頼を置くことができない (検証不能である) ことより、厳格な結果を求められるシステムよりは今回のような曖昧な世界に適合しやすい。

「内側からみたもの」はその明確な処理内容から、何らかの定まった結果を生み出す過程として利用しやすい。

何の話かというと。

度々「人工知能でこんな処理が楽になるように」とか言う人がいますが、概ね求めているものは後者に基づいたシステムであろうと思う、という話です。

まぁなんかこう。知性っていろいろあるよね、ということが一般の人間には難しいのかもしれません。何故なら人は「人」という1つの存在であるから。

でもそういう話にちゃんと指摘するような人が居たのはちょっとうれしくなりました。他人事ですが。

 

ちなみに実は「必ず求められた行動を実行できるか」という観点においてはこの2種は大差ありません。どっちもできません。

AIは言わずもがな「何をするかわからないから」ですが、アルゴリズムは「決められたことしかできない」「定められた行動が本当に求められたものかどうかは誰も保証しない」からです。

いつだってfail-safeが一番です。本当に。そういうことができるのもまた人間なのかもしれません。今のところ。

余談: 主張と反論と

よくtwitter等で誰かが「主張」を掲げ、それが拡散し、誰かから「反論」を頂く、という構造を観測するわけですが、なんか私はどっちも負けた気になるのでどっちもしないようにしています。

完全に何も言わないのが一番なんですが、なんかどうしても言いたくなって (つまり敗北した結果として) こういう文章を書いたりしています。そういうモチベーションで文章を書いています。

まともなことをこんなところで言ったところで意味なんて無いし、まともじゃないことを否定したってまた意味も無いです。大事なのはそういう主張群を読んで自分で解釈して取り込むことだと思います。

ただ自らの判断の精度を上げることだけに価値があります。

 

私は「どうしてそうなっちゃうんだろう」というような発言が好きではなく、その疑問に至った時点で理由をちゃんと仮説に基づいて提示しようとすべきだと考えます。

私は「もうこれしかない」などのような発言を見ると、本当にそれは正しいのか、「これ」以外が存在しないと言える根拠は実在するのか検証しようとします。

文献の要約を記すような発言はそれがちゃんと要約になっているのか確認すべきだし、文献を引用したような文章に含まれる単語が本当に文献にあるのか確認すべきです。

結局なんでこういうことをしなきゃいけないかというとみんなちゃんと文章を書いてないからです。私もそうだろうし。

信用できるのは自分の中にある何かだけです。

だからきっとこうやって文章を出力することは、それそのものにはきっと意味は無いのです。

だけど書いちゃう、っていうのは、ただの自分の弱さです。

おわりに

私は現在のムーブメントを楽しく眺めている立場です。いろいろと面白いことになっているのは事実だし、私の好む「構造の伴った世界」が相対的に評価されるようになると感じているからです。

それはそれとしてしょうもない発言をする人間が多くてさみしいですが。悪い癖よね、界隈の。いや人類の。

またまたすぐ新しい波が来ると思うので、それを楽しみにしています。

そうやって「イメージだけで評価をする時代」がだんだんと終わっていくのを眺めていこうとおもいます。

少なくとも人類は良い方向に向かっていると思っています。

おわり。

Cubes 解説

  • 日本語を丁寧に書くの面倒なので箇条書きスタイルでいきます
    • もうこれからそれでいいのでは?
      • ぶっちゃけ読みやすいと思うんすけど
        • この記事が読みにくいのはもう内容的にしょうがない

もくじ

  • Graphilia改造について
  • 描画について

Graphilia改造について

行ったこと

  • ノード10個の追加
    • Input系: Cube Coord, AudioLink (Bass/Low-Mid/High-Mid/Treble), Last Cube Z
    • Output系: Cube Z, Light, Back Light
    • 計算系: Hash
  • メニューへの追加 (私はメニューの追加はしてないです)
  • ノードの実装

実装 (全ノード共通部分)

ノード追加したければ他のノードがやってることをそのままその通りやれば良い (それはそう)

  • Scripts/GraphiliaNode.cs
    • 定数 (private const int) を追加 (予めメニューを想定して番号を割り当て)
    • UpdateImpl 関数内 nodeDirty 分岐内
      • まず各ノードタイプに合わせて入出力に関する値を設定
        • 入力数 (numInputConnectors) / 出力数 (numOutputConnectors)
        • 即値入力 (スライダー化) の許可 (allowImmediateValues)
          • 不要な場合は省略可っぽい
        • 入力名 (inputNames) / 出力名 (outputNames)
      • 次に各ノードタイプに合わせてに関する値を設定
        • 入力型 (inputTypes) を使って出力型 (outputTypes) を計算
          • n次元ベクトルは n=1 のとき "Scalar", そうでないとき $"Vec{n}"
    • GetNodeName 関数で各ノードの名前を設定
      • これがノード板に表示される名前になる
  • Scripts/GraphiliaMenu.cs
    • GraphiliaNode.cs と同様に private const int の定数を追加
      • 当然数値は GraphiliaNode.cs と一致させる
    • 各ノードに対して Spawn 用イベントを定義
      • public void OnなんとかButton() っていう関数を作る
        • 中身は他ノードと同様に SpawnNode にノードタイプの定数を渡すだけ
      • この名前 (なんとか部分) は後に作るGameObjectの名前と一致させることになる
  • Shaders/GraphiliaCommon.cginc
    • 今度は static const int で定数を追加
  • Shaders/GraphiliaCalculate.cginc
    • 各ノードの計算処理を記述 (Output系以外)
      • GetInput{N}(index)index ノード (現在の処理対象ノード, 要は自分) の N 番目の入力を得られる (float4)
      • SetOutput0(index, value)index ノードの出力を設定 (出力は高々1個しかないので N = 0 しか使えない)
  • この段階で Graphilia は (内部的には) ノードを生成・処理できるようになる
  • メニューへ追加
    • Hierarchy 上の Graphilia/Menu/Panel/Menu を開く
    • 追加したいノードを入れるメニュー板を開く
    • 他のノードを duplicate してボタンを増やす
    • ボタンを追加ノードに合わせて設定
      • 位置をいい感じにする
      • GameObject の名前を GraphiliaMenu.cs で設定したものに合わせる
      • もしもメニュー上の表示を GameObject 名と違うものにしたい場合はそれを Label に設定
        • 改行は \n で入れられる
  • おわり
    • 綺麗にできていたので思った通りにやれば素直にうごきました

Output系の実装

  • 今回作る Output は全て「シーンに唯一」なので、Projector の実装を参考にしました
  • 方針
    • GraphiliaCommon.cginc に、目的の出力に合わせて ConstantBuffer を定義する
    • GraphiliaCalculate.cginc で定義される関数をいい感じに呼ぶシェーダを作る
    • そのシェーダを割り当てた Material を作り、Graphilia (root) に public variable として渡しておく
    • GraphiliaNode.cs の SetupScreen 関数で Material にノード情報を渡す
    • 後はその Material で描画を実行するだけ
  • これ細かく書く必要ある?
    • ちなみに私は3つ出力を作りましたが、1つのシェーダにまとめたらコンパイル長くて心配になったので3つのシェーダに分けました
    • NumNodes の分岐・LocationIndex の分岐を満たさない場合の出力がデフォルトの計算結果として利用できます
  • もうちょっと細かく書いておく
    • まず後々便利なので出力に応じたマクロを define しておく (GRAPHILIA_CUBE_OUT_CUBE_Z みたいにしました)
    • ConstantBufferの定義
      • 自明 (_なんとかNumNodes, _なんとかNodes でノードのデータ、出力ノードの index は _なんとかかんとかIndex )
        • 命名規則は揃える必要がある (GraphiliaNode.cs で利用している為)
    • GraphiliaVertFrag.cginc をコピーしてマクロと関数呼び出しを整備する
      • GRAPHILIA_CALCULATE は計算用関数の関数名 (Calculateなんとか で良さそう)
      • GRAPHILIA_CALCULATE_NUM_NODES はノード数 (_なんとかNumNodes)
      • GRAPHILIA_CALCULATE_NODES はノードのデータ (_なんとかNodes)
      • この3つを定義した状態で #include "GraphiliaCalculate.cginc" する
        • あと呼び出しているのが vertex shader か fragment shader かに依って GRAPHILIA_CALCULATE_VERTGRAPHILIA_CALCULATE_FRAG を define する
      • Calculateなんとか を適当に呼び出す
        • 引数いっぱいあるけどぶっちゃけ全ての引数に 0 を突っ込んでも動く
          • Cube Z では uv だけ入れてそれ以外 0、Light と Back Light では全てに 0 を突っ込んでます
          • 自作の time とか入れるなら引数を増やす必要があるのかな
    • あとは Material を作って Graphilia.cs に public variable として追加、割り当て
    • GraphiliaNode.csSetupScreen 関数で SetupPass 関数などを呼ぶ (他を参考にして書けば良い)
  • こんなもんかな?

ちなみに出力はこんな感じで行われてます (32x16 RGBAFloat16 の RenderTexture に Camera で描画してる)

ここまでくればもう好きに使えば良い

描画について

やってること

  • vertex shader
    • 押し出したりする
    • 位置が同じキューブはくっつける (最も左下のキューブを拡大させて、他を全て消す)
  • fragment shader
    • pixel 毎に Light Probe を読み出してライティングさせる
    • raytrace して ambient occlusion を計算
    • 面光源の直接光を Linearly Transformed Cosines で計算
    • raytrace して LTC による光の影を計算
  • おまけ
    • AOと影は GrabPass でいい感じにぼかす

Light Probe は この記事 の内容を L1 まで拡張して (RGBAに突っ込んで) あげただけ

レイトレ部分について

  • 今回はシーンが「2次元のセル上の四角柱たち」なので、そのセルを直接 raytrace すれば良い (QuadTree Traversal, はやい)
    • これはまぁがんばる
  • AOと影を計算する (どちらも 4 samples per pixel)
    • Ambient Occlusion
      • 法線を向いた Cosine-weighted Hemisphere に向かって適当にレイを投げる
      • 衝突までの距離 L [m] に対して saturate(L) で寄与を計算 (遠いと1、近いと0)
        • どうせAOなんて最初から擬似的なもんなのでそれっぽければよい
    • 影 (面光源の見える面積として影を近似)
      • 面光源の uniform sample に向かって適当にレイを投げる
        • 真値ではないです (本来は見かけ上の面積で uniform sample するべきだと思う)
      • 光源まで当たれば 1、そうでなければ 0 として寄与を計算
    • ランダム選択はデバイス座標での Blue Noise を使って算出 (よくあるやつ)
      • ある程度高周波ノイズにしてやることで後でぼかしたときにノイズが消えやすくなる
      • バイス座標、SV_POSITION になってる値の xy を frag で取ったらそれっぽかったのでそれを使ってます

AOと影を表示するとこんな感じ (Rが影 (じゃない部分)、BがAO成分)

で、これをいい感じにぼかすことで綺麗にします

これがこう。

  • 仕組み
    • 概略
      • ぼかす為にめっちゃ GrabPass を使います
      • ついでに余計にぼかさない為に normal/depth がほしいのでそれも作ります (GBuffer みたいなもん)
      • その為にシーンの物体は3つずつおいてあります
    • 実際の処理
      • 真っ黒を描画
      • Normal を描画
      • NamedGrabPass しつつ ZWrite On, ZTest Always で o.vertex.z を far clip の depth 値にして空間を覆う (初期化)
      • レイトレ結果を描画
      • GrabPass しつつぼかす(1)
      • GrabPass しつつぼかす(2)
      • GrabPass しつつぼかす(4)
      • GrabPass しつつぼかす(8)
      • NamedGrabPass して再度 depth を初期化
      • 作ったバッファを利用してシーンをいい感じに描画する

Normal の GrabTexture はこんなかんじ (自明)

ちなみにキューブには bevel が入ってるので微妙に平坦ではない

ぼかしの実装は これ とかを参考にしました (1+4 sample で重み付き平均を取っていく)

(edge-avoid する為に normal と position を使った適当な項を突っ込んでる感じです) (position は depth から復元します)

それっぽいのでまんぞく。

Standard系拡張

  • 実はキューブ達は BakeryStandard の派生、部屋全体は FilamentedStandard の派生
    • 最初の状態だと部屋の奥の方が Reflection Probe を過剰に取ってるようにみえたので
    • どうせ最終的にはほぼ見えなくなったわけですが
  • BakeryStandard
    • Bakery.cginc をいじる
    • bakeryVertForwardBasebakeryVertForwardAdd の最初の方 (マクロの後?) で v.vertex を直接書き換えて vertex 弄りをしています
      • このタイミングなら何やっても大丈夫なはず (メッシュがもともとそういうデータだったことと区別がつかないため)
    • bakeryFragForwardBase の末尾付近 (UNITY_BRDF_PBS の直前) で gi.indirect.diffusegi.indirect.specular を好き勝手に書き換え
      • LightProbeを読み出して float4(normal, 1)dot を取るなどする
        • そういえば SphericalHarmonicsL2 に入っている成分は 1,y,z,x の順番なので注意 (テクスチャ化のときに xyz1 に揃えた)
      • 後は LTC の寄与を突っ込んだりする
      • ちなみに specular 成分は BakerySH 関数の BAKERY_LMSPEC 部分を参考に適当にでっちあげました
        • 何故か focus 使われてなかったけど使っておきました
        • まぁこのシーンではほぼ意味ないんですが…
    • ついでに bakeryFragForwardBase の最後に emission 項を直接加算
  • FilamentedStandard
    • FilamentLightIndirect.cginc をいじる
    • evaluateIBL の (UnityGI_Irradiance 後の) derivedLight にベイクされた値が入ってるっぽい (unity_Irradiance にもなんか入ってるっぽい) (よくわかってない)
    • derivedLight.attenuation にAO項を乗算
    • derivedLight.colorIntensity.rgb にバックライトの明かりを乗算してから LTC 光源の寄与を突っ込む

こんなかんじです。

おわり。

主観的等価性

よく知られていることですが、「等しさ」は判定が自明な性質ではありません。

「観点」があって初めて等しさを定義できます。2つの一円玉は「円としての価値」という観点では同一な存在ですが、明らかに違う物体ではあります。

テキストファイルをコピーして出来たテキストファイル (2) は、情報として同一ですが、格納されている場所が違います。

アバターとリアル身体は対話可能性という意味では同一ですが、存在のレベルが違います。

つまり、全ての話題に於いて、「A は B である」という言明には、「C という観点に於いて」という前置きが存在しているはずなのです。

全て。いかなる時にも。

 

では「観点とは何か?」という疑問に対する回答として参考になるのが「振る舞い等価」の考え方です。

物はそれ単体では意味をなさず、何かと関連することで効果を発揮する。だから、物の等しさは「振る舞いの等しさ」で定義できる。

一円玉は支払いに於いて「1円」として振る舞うから、2つの異なる一円玉は等しいと言える。

多少ノイズが入った写真であっても人間にとっては変わらず「風景写真」として振る舞えるから、些細なデータの違いは無視できる。

つまり観点とは、機能です。機能が等しいなら同じとみなせる。

コードで書いてもノードで書いても同じ挙動を作れるなら同じプログラムです。

綺麗なCGと綺麗な実写が区別できないなら、それは等しい。

高度な科学が魔法のように振る舞うのなら、それはもう魔法なのです。

 

クオリアが人によって違うとしても、それを区別する方法が実在しない以上、それは等しいときと同じ。

世界が5秒前にできたとしても、それを知る方法がない以上、そうでない世界と同じ。

この世界がシミュレーションだとしても、それが判断できなければそれでいいんです。

神が居たり居なかったりしても別にそれでいいんです。そんなことは考える事柄の範疇ではありません。

そんなのは意義ある哲学ではありません。

 

話を戻しますが、観点に依存して等しさが決定するということは、観点が変われば等しさが変わるということです。

「綺麗な絵」と「綺麗な絵」は、綺麗という感覚を想起させる以外に差がないのであれば、それは同じものです。

だけど、眼が良くなればそこには違いがあることがわかるようになる。例えば空の絵であることと海の絵であることが区別できるようになる。

「わけわからない文字の羅列」達が、だんだん「意味あるプログラムコード」であることがわかるようになっていく。

そして逆に。

「違う言語で書かれたプログラム」は結局「同じ意味を持つプログラム」であるように認識するようになって。

「綺麗なグラフィックスで描かれたCG空間」は「いつものUE5ぽん置きシーン」としてみえて。

「これまでに見たことのない演出」は「新規性の無いアニメーション」になります。

それは間違っていないのです。それでいいのです。そういう観点が実在すること、それ自体を否定してはいけません (できません)。

 

だから、作ったものが「区別できる」すなわち何らかの意義があるものである、と主張するならば、そこには「ある観点」と「それに見合った実態」がなければなりません。

特に、この観点は与えるものではなく湧き上がらせるものです。外から観点を強制することはできません。それ自体が「実態」に埋め込まれるだけです。

作品が何であるかを説明する文章は、それ自体を含めて作品という体系になってしまいます。

誰かが切り取った空間は、切り取られた空間となって本来の空間を侵食します。

「湧き上がる観点」がないのなら、それは自然に埋もれるだけです。そしてそれでいいのです。

 

正しく作品をその評価の場に送るにあたり、受け手は相応の「誠実な観測」を、作り手は「観点に見合う実態の制作」を行わなくてはなりません。

実態に見合わないものには相応の反応が送られるべきです。それが誠実であるということです。

名前を付けただけで「それ」になるわけではありません。

意図しない観測結果が得られたとしても、それは (それが誠実である限り) 作品の実態に備わった「観点」なのです。

まぁ、どれだけが誠実であるかは定かではありませんが…。

 

作り手の願いを適切に送信するために苦しむと同時に、受け手は作り手の願いを受信する努力をしなければなりません。

結局「ある観点」を軸にした立場としてはその2つは同じものです。

もっと対話ができるはずなのです。ただ無条件に信頼するのではなく。ただ曖昧に賛美するのではなく。


 

よくわからない文章になったのでまとめを書きます。

  • 「等しさ」は観点によって変化するもの。
  • 同じような機能を持つものを区別しない、ということが観点そのもの。
  • 観点は人や時間によって変化するもの。
    • 区別できなかったものが区別できるようになったり、区別してたものを区別しなくなったりする。
  • 作ったものを区別してほしいのなら、その為の観点と、それによってどう区別されるかを提示する必要がある。
    • ただし観点は明示的に提示できるものではない。作品が自ずと持つべき構造。
  • 受け手はその観測結果を誠実に提示するべきである。
  • 作り手と受け手は同等に苦しむべき。というか作り手が有利なのがおかしい。
  • もっとなかよくおはなししたほうがたのしいとおもう。

最近の5,6個の出来事をくっつけて喋ってるので明確ななにかがあるわけではないです。

まぁ少なくとも嘘は嫌いです。私は。


 

補足

「10回コインを投げて全て裏だったとして、思いを込めてもう一度投げたら表だった。思いは通じたのだろうか?」

記録 220701

わお。びっくりしました。今。

すごいです。

今更ながら「この見かけ」はほぼ参照無いし、確かに私がオリジナルなんだなぁと思いました。

まぁここは (うちの床に書いてあるように) 過去の記録という側面も強いわけですが…。

Quest対応してないのはぶっちゃけしんどいからで、SDK2だしgeometry shaderベースだしそのままだと流石に重いし…。

技術的には可能というやつです。

あと大体私は変な拘りがあるもので (良いことではない)、一度設計したものを再度別の目的で展開するのはやりたくなかったのです。

というわけで、対応予定は特にありませんでした。オリジナルのワールドのUnity ver.更新すらしてないし。やる時間も無いし…。

 

で、一応書いておこうと思いますが、あちらのワールドに書いてある通り私は一切何もしてません

が、これは「特に連絡を受けてない」という意味でもあります。

私個人は特に気にすることない派なので別に良いんですが、昔VRChatでそれが問題となったことがあった*1ので、一般には気にしたほうがいいんだと思います (まぁ、アレはアレで珍しいケースだったとも思いますが)。

ふんわり想像してみます。例えば予め連絡があるなどしたら私は (速やかな許可と共に) ワールドの寸法とか色の計算とか細かい制御をしている部分とかを示すことができたと思います。

が、これは「クローンをしたい」という場合には役に立つかもしれませんが、「模倣による再構成」では違うんですよね。

独自の観察によって生まれたものには当然ある種のオリジナリティが含まれます。それはそれで尊むべきものです。

また、これは「情報を得られるかもしれない」という希望が無い状態であるほうが吹っ切れられるので望ましいんだとも思います。

というわけで、これは合理的に理解可能な状況です。事実と異なっているかもしれませんが、要は「気になるほどではない」ということです。

 

しかし、ワールド作者側の立場としてはもう少しあって。今回のことというよりも一般論で。

こうなるとオリジナルのQuest対応をすることが難しくなるわけですね。

今Quest対応しました~とかやったら完全に潰そうとしているムーブじゃないですか。よくないです。善意かどうかは観測者が決めることです。

もしも対応を予定していて実際既に対応作業に入っていた、としたらまた複雑です。

フィギュアの再販可能性を直接聞くとやばい、みたいな話と似たような状況ですね。

Usability的にはオリジナルのワールドがQuest対応して同等に触れる (同じinstanceに居られる!) ことが望ましい気もするんですが、その状況を作り出すのが厳しくなります。

私にはその予定がないので特に問題ないです。一度作ったルックを崩すことに抵抗があってですね…。Questの人口がすごいのはわかるんですけどね…。

 

というわけで一般にはなんとも言えない感じではありますが、私としてはありがとうございますという他無いです。

私は面白ければ何でも良い派なので、デザインの独自性を主張するよりはそこから派生していって普遍的になる方が好きです。これは趣味制作だから言えることですけども。

「私という個人」なんて文化の中ではどうでもいいですからね。どうせ独占とかしなくたって「個性」はどうやっても奪われないみたいだし。

これは私の話ですけどね。

おわり。


 

あ、マジでデータをクローンしたやつはダメよ。VRChat Terms of Service, 12. Prohibited Conduct に you agree not to "c. share, publicly post, copy, or distribute another user’s User Content without their permission (except for Permitted Streaming)" って書いてあるので。私個人がどうとかではなく。

前に Star Wand のクローンが出た時には普通に moderation report 投げてます。

許可くださいってちゃんと言われたら物によっては普通に渡しそう。物によっては普通に無理そう。

はい。

こういうのは気持ちの問題ではなく論理的帰結による指摘であるべきなのよ。


 

おまけ

*1:「オリジナルのJapan Shrine」という言葉は最早ほとんど通じないのかも