视口

介绍

想到一个 Viewport 作为一个屏幕,游戏被投影到上面。为了看到游戏,我们需要一个表面来绘制它;这个表面是根。 Viewport .

../../_images/viewportnode.png

Viewports 也可以添加到场景中,以便有多个要绘制的曲面。当我们画到 Viewport 这不是根,我们称之为呈现目标。我们可以通过访问渲染目标的相应内容来访问其内容。 texture . 通过使用 Viewport 作为渲染目标,我们可以同时渲染多个场景,也可以渲染到 texture 应用于场景中的对象,例如动态SkyBox。

Viewports 有各种各样的用例,包括:

  • 在二维游戏中渲染三维对象

  • 在三维游戏中渲染二维元素

  • 渲染动态纹理

  • 在运行时生成程序纹理

  • 在同一场景中渲染多个摄影机

所有这些用例的共同点是,您被赋予了将对象绘制到纹理上的能力,就像它是另一个屏幕一样,然后可以选择如何处理生成的纹理。

输入

Viewports 还负责向其所有子节点传递适当调整和缩放的输入事件。通常,输入由最近的 Viewport 在树上,但你可以设置 Viewports 不通过将“禁用输入”选中为“打开”来接收输入;这将允许下一个最近的 Viewport 在树中捕获输入。

../../_images/input.png

有关godot如何处理输入的详细信息,请阅读 Input Event Tutorial .

倾听者

Godot支持3D声音(在二维和三维节点中);有关更多信息,请参见 Audio Streams Tutorial . 对于可听见的此类声音, Viewport 需要作为侦听器启用(对于二维或三维)。如果使用自定义 Viewport 显示您的 World ,不要忘记启用此功能!

照相机(二维和三维)

当使用 Camera / Camera2D ,摄像头将始终显示在最近的父级上 Viewport (向根部)。例如,在以下层次结构中:

../../_images/cameras.png

cameraa将显示在根目录上 Viewport 它会画出玛莎。camerab将被 Viewport 节点和网格。即使meshb在场景层次中,它仍然不会绘制到根 Viewport . 同样,从 Viewport 节点,因为 Viewport 节点仅捕获层次结构中低于它们的节点。

每个只能有一个活动摄像头 Viewport ,因此,如果有多个摄像头,请确保所需的摄像头设置了“当前”属性,或者通过调用以下命令将其设置为当前摄像头:

camera.make_current()

缩放和拉伸

Viewports 具有“大小”属性,该属性表示 Viewport 以像素为单位。为了 Viewports 哪些是的孩子 ViewportContainers ,这些值将被重写,但对于所有其他值,这将设置它们的分辨率。

也可以缩放二维内容并使 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,a Viewport 将包含 World . 这基本上就是把物理和渲染联系在一起的宇宙。空间基节点将使用 World 最接近的 Viewport . 默认情况下,新创建的 Viewports 不包含 World 但要和他们的父母一样 Viewport (根 Viewport 始终包含 World ,这是默认情况下渲染到的对象)。一 World 可以设置在 Viewport 使用“world”属性,这将分离该属性的所有子节点 Viewport 与父母互动 Viewport's World . 这在一些场景中特别有用,例如,你可能想在游戏中显示一个三维的独立角色(比如在星际争霸中)。

作为要创建的情况的帮助者 Viewports 显示单个对象且不希望创建 WorldViewport 可以选择使用自己的 World . 当您要在二维中实例三维字符或对象时,此选项非常有用。 World .

对于2d,每个 Viewport 总是包含自己的 World2D . 在大多数情况下,这就足够了,但是如果需要共享它们,可以通过设置 Viewport's World2D 手动。

有关如何工作的示例,请参见演示项目 3D in 2D2D 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

但如果您在ou ready()中或从 Viewport's 初始化时,您将得到一个空纹理,因为没有什么可以作为纹理获得。您可以使用(例如)处理它:

# Let two frames pass to make sure the screen can be captured.
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
# You can get the image after this.

如果返回的图像是空的,捕获仍然没有发生,请稍等,因为Godot的呈现API是异步的。有关这方面的工作示例,请查看 Screen Capture example 在演示项目中

视区容器

如果 Viewport 是一个孩子的 ViewportContainer ,它将变为活动状态并显示其内部的所有内容。布局如下:

../../_images/container.png

这个 Viewport 将覆盖其父区域 ViewportContainer 如果“拉伸”设置为“真” ViewportContainer . 注:尺寸 ViewportContainer 不能小于 Viewport .

致使

因为事实上 Viewport 是进入另一个渲染曲面的入口,它会显示一些与项目设置不同的渲染属性。第一个是MSAA;您可以选择对每个MSAA使用不同级别的MSAA。 Viewport ;默认行为被禁用。您也可以设置 Viewport 要使用hdr,hdr对于要在0.0-1.0范围之外的纹理中存储值非常有用。

如果你知道 Viewport 如果要使用,可以将其用法设置为3d或2d。然后godot将限制 Viewport 根据您的选择绘制;默认值为3D。

Godot还提供了一种自定义内部绘制方式的方法。 Viewports 使用“调试绘图”。Debug Draw允许您指定以下四个选项之一: Viewport 会显示里面画的东西。默认情况下禁用调试绘图。

../../_images/default_scene.png

禁用调试绘制的场景

其他三个选项是无阴影、透支和线框。无阴影绘制场景而不使用照明信息,因此所有对象都显示为其反照率的颜色。

../../_images/unshaded.png

调试绘图设置为非阴影的同一场景

透支使用加法混合绘制半透明的网格,以便可以看到网格是如何重叠的。

../../_images/overdraw.png

调试绘图设置为透支的同一场景

最后,线框仅使用网格中三角形的边绘制场景。注意:在本文(v3.0.2)中,线框模式不起作用,目前场景呈现正常。

渲染目标

当渲染到 Viewport ,场景编辑器中将看不到其中的内容。要显示内容,必须绘制 Viewport's ViewportTexture 在某个地方。这可以通过使用(例如)的代码来请求:

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

也可以在编辑器中通过选择“new viewporttexture”来指定。

../../_images/texturemenu.png

然后选择 Viewport 你想用。

../../_images/texturepath.png

每一帧, Viewport 的纹理将使用默认的“清除颜色”(如果“透明背景”(Transparent BG)设置为true,则为透明颜色)清除。这可以通过将清除模式设置为从不或下一帧来更改。顾名思义,“从不”意味着永远不会清除纹理,而“下一帧”将清除下一帧上的纹理,然后将自身设置为“从不”。

默认情况下,重新呈现 Viewport 发生在 ViewportViewportTexture 已绘制在框架中。如果可见,将呈现;否则,将不呈现。无论是否可见,此行为都可以更改为手动渲染(一次),或始终渲染。这种灵活性允许用户一次渲染一个图像,然后使用纹理,而不会产生渲染每帧的成本。

确保检查视区演示!可下载演示档案中的viewport文件夹,或https://github.com/godotenine/godot-demo-projects/tree/master/viewport