多分辨率

多分辨率问题

开发人员经常会遇到麻烦, 不知道如何在他们的游戏中最好地支持多种分辨率. 对于桌面和控制台游戏, 这或多或少是简单的, 因为大多数屏幕长宽比是16:9, 分辨率是标准的720p, 1080p, 1440p, 4K,…….

对于手机游戏来说,起初,这很容易。许多年来,iPhone 和 iPad 使用相同的分辨率。当实行 Retina 后,他们只是将像素密度提高了一倍;大多数开发商不得不以默认和双倍的分辨率提供素材。

如今, 情况已不再如此, 因为有很多不同的屏幕尺寸, 密度和长宽比. 非传统的尺寸也越来越受欢迎, 如超宽显示屏.

对于3D游戏来说, 没有太大的必要支持多种分辨率(从审美角度来看).3D几何图形将根据视场填充屏幕, 而不考虑长宽比. 在这种情况下, 人们可能想要支持的主要原因是为了 性能 的原因(以较低的分辨率运行以增加每秒的帧数).

对于2D和游戏UI, 这是一个不同的问题, 因为设计需要在Photoshop, GIMP或Krita等软件中使用特定的像素尺寸来创建.

由于布局, 长宽比, 分辨率和像素密度会有很大的变化, 因此不再可能为每个特定的屏幕设计UI. 必须使用另一种方法.

万全之策

最常见的方法是使用一个单一的 基础 分辨率, 然后将其适用于其他所有情况. 这个分辨率是大多数玩家预期的玩游戏的方式, 鉴于他们的硬件. 对于移动设备, 谷歌在网上有有用的 统计资料 , 对于桌面设备,Steam 也有 .

举个例子,Steam显示最常见的 主要显示分辨率是 1920×1080, 所以明智的做法是为这个分辨率开发一个游戏, 然后期处理不同尺寸和长宽比的缩放.

Godot 还提供了一系列通用的容器.

基本大小

窗口的基本尺寸可以在项目设置中的 Display → Window 下指定.

../../_images/screenres.png

然而, 它的作用并不完全明显; 引擎将 尝试将显示器切换到此分辨率. 相反, 将此设置视为 “设计大小”, 即您在编辑器中使用的区域的大小. 此设置直接对应于2D编辑器中蓝色矩形的大小.

通常需要支持具有与该基本大小不同的屏幕和窗口大小的设备. Godot提供了许多方法来控制视区的大小调整和拉伸到不同的屏幕大小.

备注

Godot遵循了现代多种分辨率的方法. 引擎永远不会自行改变显示器的分辨率. 虽然改变显示器的分辨率是最有效的方法, 但这也是最不可靠的方法, 因为如果游戏崩溃, 它可能会让显示器卡在一个低分辨率上. 这在macOS或Linux上很常见, 因为它们对分辨率变化的处理不如Windows.

更改显示器的分辨率还会取消游戏开发者对过滤和纵横比拉伸的控制, 这对于确保像素游戏的正确显示画面非常重要.

最重要的是, 更改显示器的分辨率会使游戏的Alt-Tab键切换速度变慢, 因为每次切换时显示器都必须更改分辨率.

调整大小

市面上有着各种各样的设备, 拥有各种类型的屏幕, 依次有着不同的像素密度和分辨率. 处理所有的类型工作量巨大, 所以Godot试图让开发者的生活变得更简单. Viewport 节点提供了几个处理大小调整的函数, 而场景树的根节点始终是一个Viewport (场景将作为它的子节点被实例化, 并且始终可以通过调用 get_tree().get_root()get_node("/root") 来访问它.

在任何情况下,虽然更改根 Viewport 的参数可能是解决问题的最灵活方法,但这样做的可能包含大量工作、大量代码、大量推测过程,因此 Godot 在项目设置中提供了一组简单的参数来处理多分辨率问题。

拉伸设置

拉伸设置位于项目设置中, 提供了几个选项:

../../_images/stretchsettings.png

拉伸模式(Stretch Mode)

Stretch Mode 设置定义了基本尺寸如何被伸展以适应窗口或屏幕的分辨率.

../../_images/stretch.png

下面的动画使用仅16×9像素的 “基本大小” 来演示不同拉伸模式的效果. 单个精灵, 大小也是16×9像素, 覆盖整个视区, 并在其上添加一个对角线 Line2D :

../../_images/stretch_demo_scene.png

  • Stretch Mode = Disabled (默认). 不发生拉伸. 场景中的一个单位对应于屏幕上的一个像素. 在这种模式下, Stretch Aspect 设置没有效果.

    ../../_images/stretch_disabled_expand.gif

  • Stretch Mode = 2D: In this mode, the base size specified in width and height in the project settings is stretched to cover the whole screen (taking the Stretch Aspect setting into account). This means that everything is rendered directly at the target resolution. 3D is unaffected, while in 2D, there is no longer a 1:1 correspondence between sprite pixels and screen pixels, which may result in scaling artifacts.

    ../../_images/stretch_2d_expand.gif

  • Stretch Mode = Viewport : 视窗缩放意味着根 Viewport 的尺寸被精确地设置为在项目设置的 Display 部分指定的基本尺寸. 场景首先被渲染到这个视窗. 最后, 这个视窗被缩放以适应屏幕(考虑 Stretch Aspect 的设置).

    ../../_images/stretch_viewport_expand.gif

拉伸比例(Stretch Aspect)

第二个设置是拉伸纵横比. 请注意, 只有在 Stretch Mode 被设置为 Disabled 以外的情况下, 这才会生效.

在下面的动画中, 您会注意到灰色和黑色区域. 黑色区域由引擎添加, 无法绘制. 灰色区域是场景的一部分, 可以绘制. 灰色区域对应于您在2D编辑器中看到的蓝色框架外的区域.

  • Stretch Aspect = Ignore : 在拉伸屏幕时忽略长宽比. 这意味着原始分辨率将被拉伸以完全填满屏幕, 即使它更宽或更窄. 这可能会导致不均匀的拉伸, 事物看起来比设计的更宽或更高.

    ../../_images/stretch_viewport_ignore.gif

  • Stretch Aspect = Keep : 在拉伸屏幕的时候保持长宽比. 这意味着无论屏幕分辨率如何, 视窗都会保留原来的尺寸, 黑条会被添加到屏幕的顶部或底部(“宽屏模式 “)或侧面(“ 竖屏模式”).

    如果您事先知道目标设备的宽高比, 或者您不想处理不同的宽高比, 这是一个不错的选择.

    ../../_images/stretch_viewport_keep.gif

  • Stretch Aspect = Keep Width : 在拉伸屏幕时保持长宽比. 如果屏幕比基本尺寸宽, 则会在左右两边添加黑条(竖屏模式). 但如果屏幕比基本分辨率高, 视窗将在垂直方向上增长(更多的内容将在底部可见). 你也可以把它看作是 “垂直扩展” .

    这通常是创建可扩展的GUI或HUD的最佳选择, 因此一些控件可以锚定到底部( 大小和锚点).

    ../../_images/stretch_viewport_keep_width.gif

  • Stretch Aspect = Keep Height : 在拉伸屏幕时保持长宽比. 如果屏幕比基本尺寸高, 则会在顶部和底部添加黑条(宽屏模式). 但如果屏幕比基本分辨率宽, 视窗将在水平方向上增长(更多的内容将在右边可见). 你也可以把它看作是 “水平扩展” .

    这通常是水平滚动的2D游戏的最佳选择(如跑步者或平台游戏者).

    ../../_images/stretch_viewport_keep_height.gif

  • Stretch Aspect = Expand : 在拉伸屏幕时保持长宽比, 但既不保持基本宽度也不保持高度. 根据屏幕的长宽比, 视窗将在水平方向(如果屏幕比基本尺寸宽)或垂直方向上变大(如果屏幕比原始尺寸高).

    ../../_images/stretch_viewport_expand.gif

小技巧

为了以类似的自动确定的比例系数支持纵向和横向模式,请将您的项目的基本分辨率设置为 方形 (1:1长宽比)而不是矩形。例如,如果你希望以1280×720为基本分辨率进行设计,但又希望同时支持纵向和横向模式,那么在项目设置中使用720×720作为项目的基本窗口尺寸。

为了让用户在运行时选择自己喜欢的屏幕方向,记得将**Display > Window > Handheld > Orientation** 设置为 sensor (传感器).

拉伸收缩

Shrink 设置允许你在上面的 Stretch 选项已经提供的基础上增加一个额外的缩放系数. 默认值为1意味着不发生缩放.

例如, 如果你将 Shrink 设置为4, 并将 Stretch Mode 置于 Disabled 状态, 那么你的场景中的每个单元将对应于屏幕上的4×4像素.

如果 Stretch Mode 被设置为除 Disabled 之外的其他参数, 根视窗的大小就会按 Shrink 的系数缩减, 而输出中的像素则按相同的量放大. 这对2D游戏很少有用, 但可以通过在较低的分辨率下渲染来提高3D游戏的性能.

来自脚本

要在运行时从脚本中配置拉伸, 请使用 get_tree().set_screen_stretch() 方法(见 SceneTree.set_screen_stretch() ).

常见使用场景

如果要适配多种分辨率和纵横比,推荐使用以下设置。

桌面游戏

非像素风:

  • 将基础窗口宽度设置为 1920、窗口高度设置为 1080。如果你的显示器小于 1920×1080,就将 Test WidthTest Height(测试宽度和测试高度)设置为较小的值,项目启动时就会将窗口调小。

  • 或者如果你主要针对的是高端设备,那么就把基础窗口宽度设置为 3840、窗口高度设置为 2160 。这样你就可以提供更高分辨率的 2D 素材,用更高的内存占用和文件大小换取更清晰的画面。注意,这样做会让未做 mipmap 的纹理在低分辨率设备上具有颗粒感,请参考 减少缩减取样的混叠 进行操作。

  • 将拉伸模式(Stretch Mode)设置为 2d

  • 将拉伸比例(Stretch Aspect)设置为 expand (扩展)。这样可以支持多种分辨率,并且能够更好地利用较长的智能手机屏幕(例如 18:9 和 19:9 的长宽比)。

  • 使用 布局 菜单将 Control 节点的锚点吸附到正确的角落。

像素风:

  • 将基础窗口大小设置为你想要使用的视图尺寸。多数像素风游戏使用的视图尺寸在 256×224 和 640×480 之间。视图尺寸越大,所需素材的分辨率也就越高,除非你想要显示更大的游戏世界区域。

  • 将拉伸模式(Stretch Mode)设置为 viewport (视图)。

  • 将拉伸比例(Stretch Aspect)设置为 keep (保持)可以(通过添加黑条的方式)强制使用固定的长宽比。如果你想支持不同长宽比的话,也可以把拉伸模式设置为 expand (扩展)。

  • 如果选用 expand 拉伸比例,使用 布局 菜单将 Control 节点的锚点吸附到正确的角落。

备注

viewport 拉伸模式会先以较低分辨率渲染,然后拉伸到最终窗口的大小。如果你能够接受精灵可以移动或者旋转到“次像素”位置,或者希望有高分辨率的 3D 视图,可以把 viewport 拉伸模式换成 2d 模式。

Godot 目前无法在使用 2dviewport 拉伸模式时强制使用整数倍缩放,也就是说,如果最终的窗口大小不是基础窗口大小的倍数,像素画的显示效果可能比较糟糕。可以使用类似 Integer Resolution Handler 的插件解决这一问题。

横屏的手机游戏

Godot 默认使用横屏模式,所以你无需在项目设置中调整显示方向。

  • 将基础窗口宽度设置为 1280,窗口高度设置为 720

  • 或者如果你主要针对的是高端设备,那么就把基础窗口宽度设置为 1920、窗口高度设置为 1080。这样你就可以提供更高分辨率的 2D 素材,用更高的内存占用和文件大小换取更清晰的画面。很多设备拥有更高分辨率的显示屏(1440p),但因为智能手机的屏幕比较小,所以很难看出和 1080p 的区别。注意,这样做会让未做 mipmap 的纹理在低分辨率设备上具有颗粒感,请参考 减少缩减取样的混叠 进行操作。

  • 将拉伸模式(Stretch Mode)设置为 2d

  • 将拉伸比例(Stretch Aspect)设置为 expand (扩展)。这样可以支持多种分辨率,并且能够更好地利用较长的智能手机屏幕(例如 18:9 和 19:9 的长宽比)。

  • 使用 布局 菜单将 Control 节点的锚点吸附到正确的角落。

竖屏的手机游戏

  • 将基础窗口宽度设置为 720,窗口高度设置为 1080

  • 或者如果你主要针对的是高端设备,那么就把基础窗口宽度设置为 1080、窗口高度设置为 1920。这样你就可以提供更高分辨率的 2D 素材,用更高的内存占用和文件大小换取更清晰的画面。很多设备拥有更高分辨率的显示屏(1440p),但因为智能手机的屏幕比较小,所以很难看出和 1080p 的区别。注意,这样做会让未做 mipmap 的纹理在低分辨率设备上具有颗粒感,请参考 减少缩减取样的混叠 进行操作。

  • Display > Window > Handheld > Orientation 设置为 portrait (竖屏)。

  • 将拉伸模式(Stretch Mode)设置为 2d

  • 将拉伸比例(Stretch Aspect)设置为 expand (扩展)。这样可以支持多种分辨率,并且能够更好地利用较长的智能手机屏幕(例如 18:9 和 19:9 的长宽比)。

  • 使用 布局 菜单将 Control 节点的锚点吸附到正确的角落。

非游戏应用

  • 将基础窗口宽高设置为你想要支持的最小窗口尺寸。这不是必须的,但是可以保证你在设计 UI 时考虑较小的窗口尺寸。

  • 保持拉伸模式(Stretch Mode)为默认值 disabled(禁用)。

  • 保持拉伸比例(Stretch Aspect)为默认值 ignore(忽略) (因为拉伸模式是 disabled ,所以这里的值不会被用到)。

  • 你可以在脚本的 _ready() 函数中通过设置 OS.min_window_size 来定义窗口的最小尺寸。这样可以防止用户将应用窗口缩得过小,导致 UI 布局的问题。

备注

Godot 尚未支持手动设置 2D 缩放比例,所以无法在非游戏应用中支持 hiDPI。因此,推荐为非游戏应用禁用 Allow Hidpi 选项,操作系统会回退到低 DPI。

支持 hiDPI 高分辨率屏幕

默认情况下,操作系统会认为 Godot 项目是 DPI 无关的。因为操作系统的 DPI 回退缩放比让应用程序自己做缩放要快很多(即便用的是 viewport 拉伸模式),所以这样做可以提高在低端系统上的性能。

不过操作系统的 DPI 回退缩放功能在全屏模式下并不好用。如果你想在 hiDPI 显示器下得到清晰的画面,又或者想要支持全屏,那么推荐启用项目设置中的 Display > Window > Dpi > Allow Hidpi

Allow Hidpi(允许 hiDPI) 仅在 Windows 和 macOS 上有效,其它平台会忽略这个选项。

备注

Godot 编辑器本身是打开了这个选项,与 DPI 相关的。但在编辑器中运行项目时,只有在项目设置里启用 Allow Hidpi 才会让项目与 DPI 相关。

减少缩减取样的混叠

如果游戏的基本分辨率很高(如 3840×2160),当采样降到相当低的分辨率(如 1280×720)时,可能会出现锯齿。可以通过在加载时将所有图像缩小 2 倍来减少锯齿的出现。这可以通过在加载游戏数据之前调用下面的方法来实现:

  1. VisualServer.texture_set_shrink_all_x2_on_set_data(true)

或者, 也可以在所有2D纹理上启用mipmap. 然而, 启用mipmap会增加内存的使用量, 这个在低端移动设备上可能会出现问题.

处理纵横比

一旦考虑到不同分辨率的缩放, 请确保你的 user interface 也能为不同的长宽比进行缩放. 这可以使用 anchors 和/或 containers 来完成.

视场角缩放

3D相机节点的 Keep Aspect 属性默认为 Keep Height 缩放模式(也称为 Hor+ ). 在横屏模式下, 这通常是桌面游戏和手机游戏的最佳选择, 因为宽屏显示器会自动使用更宽的视野.

然而, 如果您的3D游戏打算使用纵向模式, 那么使用 Keep Width保持宽度 称为( Vert- )可能会更有意义. 这样, 宽高比大于16:9(例如19:9)的智能手机将使用 更高 的视野, 这在这里更符合逻辑.

使用视图端口以不同的方式缩放 2D 和 3D 元素

使用多个视图窗口节点, 可以对不同的元素使用不同的比例. 例如, 您可以使用此选项以低分辨率渲染3D世界, 同时将2D元素保持在原生分辨率. 这可以显著提高性能, 同时保持HUD和其他2D元素的清晰度.

这是通过只对2D元素使用根Viewport节点, 然后创建一个Viewport节点来显示3D世界并使用ViewportContainer或TextureRect节点来实现的. 最终项目中实际上将有两个视图窗口. 与ViewportContainer相比, 使用TextureRect的一个好处是它允许启用线性过滤. 这使得缩放的3D视图窗口在许多情况下看起来更好.

有关示例, 请参见 3D 视窗缩放演示 .