多分辨率

多分辨率问题

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

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

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

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

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

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

万全之策

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

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

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

参见

You can see how Godot’s support for multiple resolutions works in action using the Multiple Resolutions and Aspect Ratios demo project.

基本大小

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

../../_images/screenres.webp

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

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

备注

On this page, window refers to the screen area allotted to your game by the system, while viewport refers to the root object (accessible from get_tree().root) which the game controls to fill this screen area. This viewport is a Window instance. Recall from the introduction that all Window objects are viewports.

To configure the stretch base size at runtime from a script, use the get_tree().root.content_scale_size property (see Window.content_scale_size). Changing this value can indirectly change the size of 2D elements. However, to provide a user-accessible scaling option, using 拉伸缩放 is recommended as it’s easier to adjust.

备注

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

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

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

调整大小

There are several types of devices, with several types of screens, which in turn have different pixel density and resolutions. Handling all of them can be a lot of work, so Godot tries to make the developer’s life a little easier. The Viewport node has several functions to handle resizing, and the root node of the scene tree is always a viewport (scenes loaded are instanced as a child of it, and it can always be accessed by calling get_tree().root or get_node("/root")).

In any case, while changing the root Viewport params is probably the most flexible way to deal with the problem, it can be a lot of work, code and guessing, so Godot provides a set of parameters in the project settings to handle multiple resolutions.

拉伸设置

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

../../_images/stretchsettings.webp

拉伸模式

The Stretch Mode setting defines how the base size is stretched to fit the resolution of the window or screen. The animations below use a “base size” of just 16×9 pixels to demonstrate the effect of different stretch modes. A single sprite, also 16×9 pixels in size, covers the entire viewport, and a diagonal Line2D is added on top of it:

../../_images/stretch_demo_scene.png

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

    ../../_images/stretch_disabled_expand.gif

  • Stretch Mode = Canvas Items: 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

To configure the stretch mode at runtime from a script, use the get_tree().root.content_scale_mode property (see Window.content_scale_mode and the ContentScaleMode enum).

拉伸比例

第二个设置是拉伸纵横比. 请注意, 只有在 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 (传感器).

To configure the stretch aspect at runtime from a script, use the get_tree().root.content_scale_aspect property (see Window.content_scale_aspect and the ContentScaleAspect enum).

拉伸缩放

The Scale setting allows you to add an extra scaling factor on top of what the Stretch options above already provide. The default value of 1.0 means that no additional scaling occurs.

For example, if you set Scale to 2.0 and leave Stretch Mode on Disabled, each unit in your scene will correspond to 2×2 pixels on the screen. This is a good way to provide scaling options for non-game applications.

If Stretch Mode is set to canvas_items, 2D elements will be scaled relative to the base window size, then multiplied by the Scale setting. This can be exposed to players to allow them to adjust the automatically determined scale to their liking, for better accessibility.

If Stretch Mode is set to viewport, the viewport’s resolution is divided by Scale. This makes pixels look larger and reduces rendering resolution (with a given window size), which can improve performance.

To configure the stretch scale at runtime from a script, use the get_tree().root.content_scale_factor property (see Window.content_scale_factor).

拉伸缩放模式

Since Godot 4.2, the Stretch Scale Mode setting allows you to constrain the automatically determined scale factor (as well as the manually specified Stretch Scale setting) to integer values. By default, this setting is set to fractional, which allows any scale factor to be applied (including fractional values such as 2.5). When set to integer, the value is rounded down to the nearest integer. For example, instead of using a scale factor of 2.5, it would be rounded down to 2.0. This is useful to prevent distortion when displaying pixel art.

Compare this pixel art which is displayed with the viewport stretch mode, with the stretch scale mode set to fractional:

Fractional scaling example (incorrect pixel art appearance)

Checkerboard doesn’t look “even”. Line widths in the logo and text varies wildly.

This pixel art is also displayed with the viewport stretch mode, but the stretch scale mode is set to integer this time:

Integer scaling example (correct pixel art appearance)

Checkerboard looks perfectly even. Line widths are consistent.

For example, if your viewport base size is 640×360 and the window size is 1366×768:

  • When using fractional, the viewport is displayed at a resolution of 1366×768 (scale factor is roughly 2.133×). The entire window space is used. Each pixel in the viewport corresponds to 2.133×2.133 pixels in the displayed area. However, since displays can only display “whole” pixels, this will lead to uneven pixel scaling which results in incorrect appearance of pixel art.

  • When using integer, the viewport is displayed at a resolution of 1280×720 (scale factor is 2×). The remaining space is filled with black bars on all four sides, so that each pixel in the viewport corresponds to 2×2 pixels in the displayed area.

This setting is effective with any stretch mode. However, when using the disabled stretch mode, it will only affect the Stretch Scale setting by rounding it down to the nearest integer value. This can be used for 3D games that have a pixel art UI, so that the visible area in the 3D viewport doesn’t reduce in size (which occurs when using canvas_items or viewport stretch mode with the integer scale mode).

小技巧

Games should use the Exclusive Fullscreen window mode, as opposed to Fullscreen which is designed to prevent Windows from automatically treating the window as if it was exclusive fullscreen.

Fullscreen is meant to be used by GUI applications that want to use per-pixel transparency without a risk of having it disabled by the OS. It achieves this by leaving a 1-pixel line at the bottom of the screen. By contrast, Exclusive Fullscreen uses the actual screen size and allows Windows to reduce jitter and input lag for fullscreen games.

When using integer scaling, this is particularly important as the 1-pixel height reduction from the Fullscreen mode can cause integer scaling to use a smaller scale factor than expected.

常见使用场景

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

桌面游戏

非像素风:

  • Set the base window width to 1920 and window height to 1080. If you have a display smaller than 1920×1080, set Window Width Override and Window Height Override to lower values to make the window smaller when the project starts.

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

  • Set the stretch mode to canvas_items.

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

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

像素风:

  • Set the base window size to the viewport size you intend to use. Most pixel art games use viewport sizes between 256×224 and 640×480. 640×360 is a good baseline, as it scales to 1280×720, 1920×1080, 2560×1440, and 3840×2160 without any black bars when using integer scaling. Higher viewport sizes will require using higher resolution artwork, unless you intend to show more of the game world at a given time.

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

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

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

  • Set the stretch scale mode to integer. This prevents uneven pixel scaling from occurring, which makes pixel art not display as intended.

备注

The viewport stretch mode provides low-resolution rendering that is then stretched to the final window size. If you are OK with sprites being able to move or rotate in “sub-pixel” positions or wish to have a high resolution 3D viewport, you should use the canvas_items stretch mode instead of the viewport stretch mode.

横屏的手机游戏

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

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

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

  • Set the stretch mode to canvas_items.

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

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

小技巧

To better support tablets and foldable phones (which frequently feature displays with aspect ratios close to 4:3), consider using a base resolution that has a 4:3 aspect ratio while following the rest of the instructions here. For instance, you can set the base window width to 1280 and the base window height to 960.

竖屏的手机游戏

  • Set the base window width to 720 and window height to 1280.

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

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

  • Set the stretch mode to canvas_items.

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

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

小技巧

To better support tablets and foldable phones (which frequently feature displays with aspect ratios close to 4:3), consider using a base resolution that has a 3:4 aspect ratio while following the rest of the instructions here. For instance, you can set the base window width to 960 and the base window height to 1280.

非游戏应用

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

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

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

  • You can define a minimum window size by calling get_window().set_min_size() in a script’s _ready() function. This prevents the user from resizing the application below a certain size, which could break the UI layout.

备注

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

支持 hiDPI 高分辨率屏幕

By default, Godot projects are considered DPI-aware by the operating system. This is controlled by the Display > Window > Dpi > Allow Hidpi project setting, which should be left enabled whenever possible. Disabling DPI awareness can break fullscreen behavior on Windows.

Since Godot projects are DPI-aware, they may appear at a very small window size when launching on an hiDPI display (proportionally to the screen resolution). For a game, the most common way to work around this issue is to make them fullscreen by default. Alternatively, you could set the window size in an autoload‘s _ready() function according to the screen size.

To ensure 2D elements don’t appear too small on hiDPI displays:

  • For games, use the canvas_items or viewport stretch modes so that 2D elements are automatically resized according to the current window size.

  • For non-game applications, use the disabled stretch mode and set the stretch scale to a value corresponding to the display scale factor in an autoload‘s _ready() function. The display scale factor is set in the operating system’s settings and can be queried using screen_get_scale. This method is currently only implemented on macOS. On other operating systems, you will need to implement a method to guess the display scale factor based on the screen resolution (with a setting to let the user override this if needed). This is the approach currently used by the Godot editor.

The Allow Hidpi setting is only effective on Windows and macOS. It’s ignored on all other platforms.

备注

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

减少缩减取样的混叠

如果游戏的基本分辨率很高(如 3840×2160),当采样降到相当低的分辨率(如 1280×720)时,可能会出现锯齿。

To resolve this, you can enable mipmaps on all your 2D textures. However, enabling mipmaps will increase memory usage which can be an issue on low-end mobile devices.

处理纵横比

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

视场角缩放

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

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

使用 Viewport 以不同的方式缩放 2D 和 3D 元素

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

This is done by using the root Viewport node only for 2D elements, then creating a Viewport node to display the 3D world and displaying it using a SubViewportContainer or TextureRect node. There will effectively be two viewports in the final project. One upside of using TextureRect over SubViewportContainer is that it allows enable linear filtering. This makes scaled 3D viewports look better in many cases.

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