ビューポート

はじめに

Viewport は、ゲームが投影されるスクリーンと考えてください。ゲームを見るためには、それを描くための表面が必要です。その表面がルート Viewport です。

../../_images/viewportnode.png

Viewports をシーンに追加して、複数のサーフェスを描画することもできます。ルートではない Viewport に描画する場合、それをレンダーターゲットと呼びます。対応する texture にアクセスすることで、レンダーターゲットのコンテンツにアクセスできます。Viewport をレンダーターゲットとして使用することにより、複数のシーンを同時にレンダーするか、シーンのオブジェクトに適用される texture にレンダーできますが、その例が動的なスカイボックスです。

Viewports には、次のようなさまざまなユースケースがあります:

  • 2Dゲーム内での3Dオブジェクトのレンダリング
  • 3Dゲームでの2D要素のレンダリング
  • 動的テクスチャのレンダリング
  • 実行時の手続き型テクスチャの生成
  • 同じシーンを複数のカメラでレンダリングする

これらすべてのユースケースに共通することは、あたかも別の画面であるかのようにテクスチャにオブジェクトを描画する機能が与えられ、結果のテクスチャをどうするかを選択できることです。

入力

Viewports は、適切に調整およびスケーリングされた入力イベントをすべての子ノードに配信する役割も果たします。通常、入力はツリー内の最も近い Viewport によって受信されますが、 'Disable Input' を 'on' にチェックすることで入力を受信しないように Viewports を設定できます。これにより、ツリー内の次に近い Viewport が入力をキャプチャできるようになります。

../../_images/input.png

Godotが入力を処理する方法の詳細については、入力イベントチュートリアル をお読みください。

リスナー

Godotは3Dサウンドをサポートしています(2Dおよび3Dノードの両方で)。詳細については、オーディオストリームチュートリアル を参照してください。このタイプのサウンドを聞き取るには、Viewport をリスナーとして有効にする必要があります(2Dまたは3Dの場合)。カスタム Viewport を使用して World を表示している場合、これを有効にすることを忘れないでください!

カメラ(2Dおよび3D)

Camera / Camera2D を使用する場合、カメラは常に最も近い親である Viewport に表示されます(ルートに向かって)。たとえば、次の階層では:

../../_images/cameras.png

CameraAはルート Viewport に表示され、MeshAを描画します。CameraBは、MeshBとともに Viewport ノードによってキャプチャされます。MeshBはシーン階層内にありますが、ルート Viewport には描画されません。同様に、MeshAは Viewport ノードからは表示されません。これは、Viewport ノードが階層内でその下のノードのみをキャプチャするためです。

アクティブなカメラは Viewport につき1つしか存在できないため、複数ある場合は、目的のカメラに "current" プロパティが設定されていることを確認するか、次の呼び出しで現在のカメラにします:

camera.make_current()

デフォルトでは、カメラはワールド内のすべてのオブジェクトをレンダリングします。 3Dでは、カメラは cull_mask プロパティを VisualInstance's layer プロパティと組み合わせて使用して、レンダリングするオブジェクトを制限できます。

スケールとストレッチ

Viewports には "size" プロパティがあり、これは Viewport のサイズをピクセル単位で表します。ViewportContainers の子である Viewports の場合、これらの値はオーバーライドされますが、他のすべての場合、これにより解像度が設定されます。

次を呼び出して、2Dコンテンツをスケーリングし、:ref`Viewport <class_Viewport>` の解像度をサイズで指定した解像度と異なるものにすることもできます:

viewport.set_size_override(true, Vector2(width, height)) # Custom size for 2D
viewport.set_size_override_stretch(true) # Enable stretch for custom size.

ルート Viewport は、プロジェクト設定のストレッチオプションにこれを使用します。スケーリングとストレッチの詳細については、次をご覧ください。Multiple Resolutions Tutorial

ワールド

3Dの場合、Viewport には World が含まれます。これは基本的に、物理演算とレンダリングをリンクする宇宙です。Spatial(3D)ベースノードは、最も近い ViewportWorld を使用して登録します。デフォルトでは、新しく作成された Viewport には World は含まれませんが、親の Viewport (ルート Viewport には常に World が含まれます。これはデフォルトでオブジェクトがレンダリングされるものです)。"World" プロパティを使用して WorldViewport に設定できます。これにより、Viewport のすべての子ノードが親 Viewport World との対話から分離されます。これは、たとえば、StarCraftのように、ゲームに3Dで乗せられた別のキャラクターを表示したい場合に特に役立ちます。

単一のオブジェクトを表示する Viewport を作成し、WorldViewport を作成したくない状況のヘルパーとして独自の World を使用するオプションがあります。これは、2DWorld で3Dキャラクターまたはオブジェクトをインスタンス化する場合に便利です。

2Dの場合、各 Viewport には常にそれ自身の World2D が含まれます。ほとんどの場合これで十分ですが、それらを共有したい場合は、Viewport World2D を手動で設定することで可能です。

これがどのように機能するかの例については、デモプロジェクト 3D in 2D および `2D in 3D <https://github.com/godotengine/godot-demo-projects/tree/master/viewport/2d_in_3d> `_ があります。

キャプチャ

Viewport コンテンツのキャプチャをクエリすることが可能です。ルート Viewport の場合、これは事実上画面キャプチャです。これは、次のコードで実行されます:

# Retrieve the captured Image using get_data().
var img = get_viewport().get_texture().get_data()
# Flip on the y axis.
# You can also set "V Flip" to true if not on the Root Viewport.
img.flip_y()
# Convert Image to ImageTexture.
var tex = ImageTexture.new()
tex.create_from_image(img)
# Set Sprite Texture.
$sprite.texture = tex

しかし、これを _ready() で、または Viewport 初期化の最初のフレームから使用すると、テクスチャとして取得するものがないため、空のテクスチャを取得します。これは(例)を使用して対処できます:

# Wait until the frame has finished before getting the texture
yield(VisualServer, "frame_post_draw")
# You can get the image after this.

ビューポートコンテナ

Viewport が:ref:ViewportContainer <class_viewportcontainer> の子である場合、アクティブになり、内部にあるものをすべて表示します。レイアウトは次のようになります:

../../_images/container.png

StretchViewportContainertrue に設定されている場合、Viewport は、その親 ViewportContainer の領域を完全にカバーします。注: ViewportContainer のサイズは、Viewport のサイズより小さくすることはできません。

レンダリング

Viewport は別のレンダリングサーフェスへの入り口であるという事実により、プロジェクト設定とは異なるいくつかのレンダリングプロパティを公開します。最初はMSAAです。Viewport ごとに異なるレベルのMSAAを使用することを選択できます。デフォルトの動作は無効です。HDRを使用するように Viewport を設定することもできます。HDRは、0.0〜1.0の範囲外のテクスチャに値を保存する場合に非常に役立ちます。

Viewport の使用方法がわかっている場合、その使用法を3Dまたは2Dに設定できます。Godotは、選択に従って Viewport の描画方法を制限します。デフォルトは3Dです。2D使用モードは、3Dに比べてわずかに高速であり、使用するメモリも少なくなります。ビューポートが3Dで何もレンダリングしない場合は、Viewport のUsageプロパティを2Dに設定することをお勧めします。

注釈

ビューポートで3Dシャドウをレンダリングする必要がある場合は、必ずビューポートの Shadow Atlas Size プロパティを0より大きい値に設定してください。それ以外の場合、シャドウはレンダリングされません。参考までに、プロジェクト設定ではデフォルトで4096に定義されています。

Godotは、「デバッグ描画」を使用して Viewport 内にすべてを描画する方法をカスタマイズする方法も提供します。デバッグ描画では、Viewport が内部に描画されたものを表示する方法について、4つのオプションのいずれかを指定できます。デバッグ描画はデフォルトで無効になっています。

../../_images/default_scene.png

デバッグ描画を無効にして描画されたシーン

他の3つのオプションは、シェーディングなし、オーバードロー、ワイヤーフレームです。シェーディングなしは、照明情報を使用せずにシーンを描画するため、すべてのオブジェクトはアルベドの色と同じ均一な色で表示されます。

../../_images/unshaded.png

デバッグ描画がUnshadedに設定された同じシーン

Overdrawは、追加ブレンドを使用して半透明のメッシュを描画するため、メッシュがどのように重なり合っているかを確認できます。

../../_images/overdraw.png

デバッグ描画をOverdrawに設定した同じシーン

最後に、Wireframeはメッシュ内の三角形のエッジのみを使用してシーンを描画します。

注釈

ワイヤフレームモードの効果は、プロジェクトの実行中ではなく、エディタでのみ表示されます。

レンダーターゲット

Viewport にレンダリングする場合、内部のものはシーンエディタに表示されません。内容を表示するには、Viewport ViewportTexture をどこかに描画する必要があります。これは、次のコードを使用してリクエストできます(例):

# This gives us the ViewportTexture.
var rtt = viewport.get_texture()
sprite.texture = rtt

または、「新規ViewportTexture」を選択してエディタで割り当てることができます

../../_images/texturemenu.png

そして、使用したい Viewport を選択します。

../../_images/texturepath.png

すべてのフレームで、Viewport のテクスチャはデフォルトのクリアカラー(または Transparent BGtrue に設定されている場合は透明カラー)でクリアされます。これは Clear Mode をNeverまたはNext Frameに設定することで変更できます。名前が示すように、Neverはテクスチャがクリアされないことを意味し、一方、次のフレームは次のフレームでテクスチャをクリアし、Neverに設定します。

デフォルトでは、ViewportViewportTexture がフレームに描画されたときに、Viewport の再レンダリングが行われます。表示されている場合、レンダリングされます。それ以外の場合はそうなりません。この動作は、手動レンダリング(1回)に変更することも、表示するかどうかに関係なく常にレンダリングすることもできます。この柔軟性により、ユーザーはイメージを一度レンダリングしてから、すべてのフレームをレンダリングするコストをかけずにテクスチャを使用できます。

ビューポートのデモを必ず確認してください!ダウンロード可能なデモアーカイブのビューポートフォルダ、または次 のURL https://github.com/godotengine/godot-demo-projects/tree/master/viewport