見出し画像

World3Dで描き分ける Godot

Godotエンジン、レイヤーを使わず複数のカメラを使う話。

World3D

World3Dってリソースありますよね。内部にEnvironmentリソースと、CameraAttributeリソースを保持できます。Environmentは背景や環境光、CameraAttributeは露光やDoFに関するパラメータを持っていて、どちらも描画に関する設定です。

World3DはViewportノードにセットすることができます。world_3dプロパティです。これによって、そのViewportの描画先(派生クラスがWindowの場合は画面、SubViewportの場合はテクスチャ)の背景や環境光、露光が変わります。

World3D周辺のノードやリソース(矢印は参照保持)

でもね、Viewport.world_3dプロパティの役割、これだけではないみたいです。

レンダーレイヤー

ところでGodotにはレンダーレイヤーという機能があります。カメラ、光源、物体(VisualInstance3D派生クラス)の各ノードにレイヤーのマスク値を設定することができて、「写す/写る」「照らす/照らされる」の関係をコントロールするためにあります。同じ部屋にあるけど別々のライトで照らしたい、とか、複数のカメラで別々の物を写して、その結果をGUIに表示したい、とか。そういうことができます。

レイヤーの設定(この場合レイヤー3)

こういった「照らし分け」「写し分け」は、レンダーレイヤーのマスク値を別々に設定しないと、実現できない。かと思いきや、そうではないようです。

Viewport.world_3d

さて、Viewport.world_3dプロパティにWorld3Dプロパティが設定されていると、そのViewportの子孫ノードは、このWorld3Dに登録(register)されることになるそうです。

World3Dがセットされると登録

この状況は、Node3D .get_world_3d()関数で取得することができます。

World3D get_world_3d() const
Returns the current World3D resource this Node3D node is registered to.

Godot Engine 4.4 Dev2 Node3D ヘルプ 

そしてどうやら、別々のWorld3Dに登録されると、別々に照らされるし、別々に写されるようなのです。同じレンダーレイヤーであっても。
ええ~~~そうだったの!?
(知ってた!?)

ほぼ同じ座標にある、形状の違う4つのメッシュが、それぞれ色の違うライトで照らされ、別々のカメラに写っている様子↓

World3Dの有無とmask値 2種類

World3Dを使うと、複数のカメラで描画する状況が楽に作れそうです。

例えばキャラクター選択画面で、各キャラの動くポートレートが並んでるような状況。Subviewportでテクスチャに描画して、それをTextureRectノードでUIに張り付けるということをすると思います。このとき、レンダーレイヤーで写しわけると、別々のマスク値を設定しなければなりません。他のUIでもレンダーレイヤーを使っているなら、値がかぶらないように処理する必要もあります。さらに、この方法では表示できるのは20キャラが限界です。ユーザーにはレイヤーが20種類しか解放されてないからです。

SubViewport
  Camera       <- レイヤーA
  Light        <- レイヤーA
  Character    <- レイヤーA
SubViewport
  Camera       <- レイヤーB
  Light        <- レイヤーB
  Character    <- レイヤーB

でも、SubviewportにWorld3Dを設定すれば、レイヤーの設定は不要です。他のUIとの兼ね合いを考えなくていいし、一度に表示できる数の限界も多分ありません。素直!

SubViewport    <- World3D A
  Camera
  Light
  Character
SubViewport    <- World3D B
  Camera
  Light
  Character

World3Dは文字通り、世界を表しているんだと思います。Subviewportに写すものが別々の場所にある場合は、レイヤーで分けるのではなく、World3Dで分けるのが、Godot流な気がします。

World3Dが世界の仕切りになる

そ、そんな役割があったのか、World3D。知らなかった~~。


以上です~~

この記事が気に入ったらサポートをしてみませんか?