Múltiples resoluciones

El problema de las resoluciones múltiples

Los desarrolladores a menudo tienen problemas para entender cómo apoyar mejor las resoluciones múltiples en sus juegos. Para los juegos de escritorio y consola, esto es más o menos sencillo, ya que la mayoría de las relaciones de aspecto de la pantalla son 16:9 y las resoluciones son estándar (720p, 1080p, 1440p, 4K, ...).

Para los juegos de móvil, al principio, fue fácil. Durante muchos años, el iPhone y el iPad usaron la misma resolución. Cuando se implementó Retina, sólo duplicaron la densidad de píxeles; la mayoría de los desarrolladores tuvieron que suministrar activos en resoluciones predeterminadas y dobles.

Hoy en día, esto ya no es así, ya que hay muchos tamaños, densidades y relaciones de aspecto de pantalla diferentes. Los tamaños no convencionales también se están haciendo cada vez más populares, como las pantallas ultra-anchas.

Para los juegos 3D, no hay mucha necesidad de soportar múltiples resoluciones (desde el punto de vista estético). La geometría 3D sólo llenará la pantalla en función del campo de visión, sin tener en cuenta la relación de aspecto. La principal razón por la que uno puede querer apoyar esto, en este caso, es por razones de rendimiento (correr en una resolución menor para aumentar los fotogramas por segundo).

En el caso del 2D y de las interfaces de juegos, es un asunto diferente, ya que el arte necesita ser creado usando tamaños de píxeles específicos en software como Photoshop, GIMP o Krita.

Dado que los diseños, las relaciones de aspecto, las resoluciones y las densidades de píxeles pueden cambiar tanto, ya no es posible diseñar interfaces para cada pantalla específica. Se debe utilizar otro método.

Una talla única para todos

El enfoque más común es usar una resolución única base y luego ajustarla a todo lo demás. Esta resolución es como se espera que la mayoría de los jugadores jueguen el juego (dado su hardware). Para móviles, Google tiene útiles "estadísticas" en la red https://developer.android.com/about/dashboards>`_, y para el escritorio, Steam `también lo hace en https://store.steampowered.com/hwsurvey/>`_.

Como ejemplo, Steam muestra que la resolución primaria de la pantalla más común es 1920×1080, por lo que un enfoque sensato es desarrollar un juego para esta resolución, y luego manejar el escalado para diferentes tamaños y relaciones de aspecto.

Godot proporciona varias herramientas útiles para hacer esto fácilmente.

Tamaño Base

El tamaño base de la ventana se puede especificar en Ajustes del Proyecto en la sección Display → Window.

../../_images/screenres.png

Sin embargo, lo que hace no es completamente obvio; el motor no intentará cambiar el monitor a esta resolución. Más bien, piensa en este ajuste como el "tamaño de diseño", es decir, el tamaño del área con la que trabajas en el editor. Este ajuste corresponde directamente al tamaño del rectángulo azul en el editor 2D.

A menudo es necesario soportar dispositivos con tamaños de pantalla y ventana diferentes a este tamaño base. Godot ofrece muchas maneras de controlar cómo se redimensionará el viewport y se estirará a diferentes tamaños de pantalla.

Nota

Godot sigue un enfoque moderno de múltiples resoluciones. El motor nunca cambiará la resolución del monitor por sí solo. Aunque cambiar la resolución del monitor es el enfoque más eficiente, también es el menos fiable, ya que puede dejar el monitor atascado en una resolución baja si el juego se cae. Esto es especialmente común en MacOS o Linux que no manejan los cambios de resolución tan bien como Windows.

Cambiar la resolución del monitor también elimina cualquier control del desarrollador del juego sobre el filtrado y el estiramiento de la relación de aspecto, lo que puede ser importante para asegurar la correcta visualización de los juegos de pixel art.

Además, cambiar la resolución del monitor hace que la entrada y salida del juego sea mucho más lenta, ya que el monitor tiene que cambiar la resolución cada vez que lo hace.

Cambiando el tamaño

Hay varios tipos de dispositivos, con varios tipos de pantallas, que a su vez tienen diferente densidad de píxeles y resoluciones. Manejar todos ellos puede ser un montón de trabajo, así que Godot intenta hacer la vida del desarrollador un poco más fácil. El nodo Viewport tiene varias funciones para manejar el redimensionamiento, y el nodo raíz del árbol de escenas es siempre un viewport (las escenas cargadas se instancian como un hijo de él, y siempre se puede acceder a él llamando a get_tree().get_root() o get_node("/root")).

En cualquier caso, aunque cambiar los parámetros de la raíz de Viewport es probablemente la forma más flexible de tratar el problema, puede suponer mucho trabajo, código y adivinanzas, por lo que Godot proporciona un sencillo conjunto de parámetros en la configuración del proyecto para manejar múltiples resoluciones.

Ajustes de estiramiento

Los ajustes de estiramiento se encuentran en los ajustes del proyecto y proporcionan varias opciones:

../../_images/stretchsettings.png

Stretch Mode

El ajuste del Modo de Estiramiento define cómo se estira el tamaño de la base para que se ajuste a la resolución de la ventana o la pantalla.

../../_images/stretch.png

Las siguientes animaciones utilizan un "tamaño base" de sólo 16×9 píxeles para demostrar el efecto de los diferentes modos de estiramiento. Un solo sprite, también de 16×9 píxeles de tamaño, cubre toda la vista, y una diagonal Línea2D se añade encima:

../../_images/stretch_demo_scene.png
  • Modo de estiramiento = Desactivado (por defecto): No hay estiramiento. Una unidad en la escena corresponde a un píxel en la pantalla. En este modo, el ajuste de Stretch Aspect no tiene ningún efecto.

    Esta es una buena opción si quieres tener un control total sobre cada píxel de la pantalla, y es probablemente la mejor opción para los juegos 3D.

    ../../_images/stretch_disabled_expand.gif
  • Modo de estiramiento = 2D: En este modo, el tamaño especificado en pantalla/ancho y pantalla/altura en los ajustes del proyecto se estira para cubrir toda la pantalla (teniendo en cuenta el ajuste de Stretch Aspect). Esto significa que todo se renderiza directamente en la resolución del objetivo. La 3D no se ve afectada en gran medida, mientras que en la 2D, ya no hay una correspondencia 1:1 entre los píxeles de los sprites y los píxeles de la pantalla, lo que puede dar lugar a artefactos de escala.

    Esta es una buena opción si su obra de arte 2D tiene una resolución suficientemente alta y no requiere una representación pixelada. Considera la posibilidad de habilitar el filtrado de texturas y el mipmapping en tus texturas y fuentes 2D.

    ../../_images/stretch_2d_expand.gif
  • Modo de estiramiento = Viewport: El escalado de Viewport significa que el tamaño de la raíz Viewport se ajusta con precisión al tamaño base especificado en la sección 'Project Settings' Display. La escena se renderiza primero en este Viewport. Finalmente, esta ventana se escala para que se ajuste a la pantalla (teniendo en cuenta la configuración de Stretch Aspect).

    Este modo es útil cuando se trabaja con juegos de precisión de píxeles, o para renderizar a una resolución menor para mejorar el rendimiento.

    ../../_images/stretch_viewport_expand.gif

Aspecto de estiramiento

El segundo ajuste es el aspecto de estiramiento. Tenga en cuenta que esto sólo tiene efecto si el Modo de estiramiento está configurado en algo distinto a Desactivado.

En las siguientes animaciones, notará áreas grises y negras. Las áreas negras son añadidas por el motor y no pueden ser dibujadas. Las áreas grises son parte de tu escena, y pueden ser dibujadas. Las áreas grises corresponden a la región fuera del marco azul que ves en el editor 2D.

  • Aspecto de estiramiento = Ignorar: Ignorar la relación de aspecto al estirar la pantalla. Esto significa que la resolución original se estirará para llenar exactamente la pantalla, incluso si es más ancha o más estrecha. Esto puede dar lugar a un estiramiento no uniforme: las cosas se ven más anchas o más altas de lo diseñado.

    ../../_images/stretch_viewport_ignore.gif
  • Aspecto de estiramiento = Mantener: Mantener la relación de aspecto al estirar la pantalla. Esto significa que el visor conserva su tamaño original independientemente de la resolución de la pantalla, y se añadirán barras negras en la parte superior/inferior de la pantalla ("letterboxing") o en los laterales ("pillarboxing").

    Esta es una buena opción si conoces de antemano la relación de aspecto de tus dispositivos de destino, o si no quieres manejar diferentes relaciones de aspecto.

    ../../_images/stretch_viewport_keep.gif
  • Aspecto de estiramiento = Mantener el ancho: Mantener la relación de aspecto al estirar la pantalla. Si la pantalla es más ancha que el tamaño de la base, se añaden barras negras a la izquierda y a la derecha (pillarboxing). Pero si la pantalla es más alta que la resolución de base, la vista crecerá en dirección vertical (y más contenido será visible hacia abajo). También puedes pensar en esto como "Expandir verticalmente".

    Esta suele ser la mejor opción para crear GUIs o HUDs que escalen, por lo que algunos controles pueden anclarse al fondo (Tamaño y anclas).

    ../../_images/stretch_viewport_keep_width.gif
  • Aspecto de estiramiento = Mantener la altura: Mantener la relación de aspecto al estirar la pantalla. Si la pantalla es más alta que el tamaño de la base, se añaden barras negras en la parte superior e inferior (letterboxing). Pero si la pantalla es más ancha que la resolución de base, la vista crecerá en la dirección horizontal (y más contenido será visible a la derecha). También puedes pensar en esto como "Expandir horizontalmente".

    Esta suele ser la mejor opción para los juegos 2D que se desplazan horizontalmente (como corredores o plataformas).

    ../../_images/stretch_viewport_keep_height.gif
  • Aspecto de estiramiento = Expandir: Mantenga la relación de aspecto al estirar la pantalla, pero no mantenga ni el ancho ni la altura de la base. Dependiendo de la relación de aspecto de la pantalla, la vista será mayor en la dirección horizontal (si la pantalla es más ancha que el tamaño de la base) o en la dirección vertical (si la pantalla es más alta que el tamaño original).

    ../../_images/stretch_viewport_expand.gif

Truco

To support both portrait and landscape mode with a similar automatically determined scale factor, set your project's base resolution to be a square (1:1 aspect ratio) instead of a rectangle. For instance, if you wish to design for 1280×720 as the base resolution but wish to support both portrait and landscape mode, use 720×720 as the project's base window size in the Project Settings.

To allow the user to choose their preferred screen orientation at run-time, remember to set Display > Window > Handheld > Orientation to sensor.

Stretch Shrink

El ajuste Shrink te permite añadir un factor de escala extra además de lo que las opciones Stretch de arriba ya proporcionan. El valor por defecto de 1 significa que no se produce ninguna escalada.

Si, por ejemplo, pones Shrink en 4 y dejas Stretch Mode en Disabled, cada unidad de tu escena corresponderá a 4×4 píxeles en la pantalla.

Si Modo de estiramiento está configurado a algo distinto de Desactivado, el tamaño de la vista de la raíz se reduce por el factor Encogimiento, y los píxeles de la salida se amplían en la misma cantidad. Esto es raramente útil para juegos 2D, pero puede ser usado para aumentar el rendimiento en juegos 3D renderizándolos a una resolución menor.

Desde scripts

Para configurar el estiramiento en tiempo de ejecución de un script, use el método get_tree().set_screen_stretch() (vea SceneTree.set_screen_stretch()).

Common use case scenarios

Se recomiendan las siguientes configuraciones para admitir múltiples resoluciones y relaciones de aspecto.

Desktop game

Non-pixel art:

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

  • Alternatively, if you're targeting high-end devices primarily, set the base window width to 3840 and window height to 2160. This allows you to provide higher resolution 2D assets, resulting in crisper visuals at the cost of higher memory usage and file sizes. Note that this will make non-mipmapped textures grainy on low resolution devices, so make sure to follow the instructions described in Reducir el alias en la reducción de la muestra.

  • Set the stretch mode to 2d.

  • Set the stretch aspect to expand. This allows for supporting multiple aspect ratios and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios).

  • Configure Control nodes' anchors to snap to the correct corners using the Layout menu.

Pixel art:

  • 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. Higher viewport sizes will require using higher resolution artwork, unless you intend to show more of the game world at a given time.

  • Set the stretch mode to viewport.

  • Set the stretch aspect to keep to enforce a single aspect ratio (with black bars). As an alternative, you can set the stretch aspect to expand to support multiple aspect ratios.

  • If using the expand stretch aspect, Configure Control nodes' anchors to snap to the correct corners using the Layout menu.

Nota

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 2d stretch mode instead of the viewport stretch mode.

Godot currently doesn't have a way to enforce integer scaling when using the 2d or viewport stretch mode, which means pixel art may look bad if the final window size is not a multiple of the base window size. To fix this, use an add-on such as the Integer Resolution Handler.

Mobile game in landscape mode

Godot is configured to use landscape mode by default. This means you don't need to change the display orientation project setting.

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

  • Alternatively, if you're targeting high-end devices primarily, set the base window width to 1920 and window height to 1080. This allows you to provide higher resolution 2D assets, resulting in crisper visuals at the cost of higher memory usage and file sizes. Many devices have even higher resolution displays (1440p), but the difference with 1080p is barely visible given the small size of smartphone displays. Note that this will make non-mipmapped textures grainy on low resolution devices, so make sure to follow the instructions described in Reducir el alias en la reducción de la muestra.

  • Set the stretch mode to 2d.

  • Set the stretch aspect to expand. This allows for supporting multiple aspect ratios and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios).

  • Configure Control nodes' anchors to snap to the correct corners using the Layout menu.

Mobile game in portrait mode

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

  • Alternatively, if you're targeting high-end devices primarily, set the base window width to 1080 and window height to 1920. This allows you to provide higher resolution 2D assets, resulting in crisper visuals at the cost of higher memory usage and file sizes. Many devices have even higher resolution displays (1440p), but the difference with 1080p is barely visible given the small size of smartphone displays. Note that this will make non-mipmapped textures grainy on low resolution devices, so make sure to follow the instructions described in Reducir el alias en la reducción de la muestra.

  • Set Display > Window > Handheld > Orientation to portrait.

  • Set the stretch mode to 2d.

  • Set the stretch aspect to expand. This allows for supporting multiple aspect ratios and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios).

  • Configure Control nodes' anchors to snap to the correct corners using the Layout menu.

Non-game application

  • Set the base window width and height to the smallest window size that you intend to target. This is not required, but this ensures that you design your UI with small window sizes in mind.

  • Keep the stretch mode to its default value, disabled.

  • Keep the stretch aspect to its default value, ignore (its value won't be used since the stretch mode is disabled).

  • You can define a minimum window size by setting OS.min_window_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.

Nota

Godot doesn't support manually overriding the 2D scale factor yet, so it is not possible to have hiDPI support in non-game applications. Due to this, it is recommended to leave Allow Hidpi disabled in non-game applications to allow for the OS to use its low-DPI fallback.

hiDPI support

By default, Godot projects aren't considered DPI-aware by the operating system. This is done to improve performance on low-end systems, since the operating system's DPI fallback scaling will be faster than letting the application scale itself (even when using the viewport stretch mode).

However, the OS-provided DPI fallback scaling doesn't play well with fullscreen mode. If you want crisp visuals on hiDPI displays or if project uses fullscreen, it's recommended to enable Display > Window > Dpi > Allow Hidpi in the Project Settings.

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

Nota

The Godot editor itself is always marked as DPI-aware. Running the project from the editor will only be DPI-aware if Allow Hidpi is enabled in the Project Settings.

Reducir el alias en la reducción de la muestra

Si el juego tiene una resolución de base muy alta (por ejemplo, 3840×2160), podría aparecer el "aliasing" al reducir la muestra a algo considerablemente más bajo como 1280×720. El aliasing puede hacerse menos visible encogiendo todas las imágenes por un factor de 2 al cargarlas. Esto puede hacerse llamando al método siguiente antes de que se carguen los datos del juego:

VisualServer.texture_set_shrink_all_x2_on_set_data(true)

Alternativamente, también puedes habilitar mipmaps en todas tus texturas 2D. Sin embargo, habilitar los mipmaps aumentará el uso de la memoria, lo que puede ser problemático en los dispositivos móviles de gama baja.

Trabajando con relaciones de aspecto

Una vez que se tiene en cuenta el escalado para diferentes resoluciones, asegúrese de que su interfaz de usuario también escala para diferentes relaciones de aspecto. Esto puede hacerse usando anchors y/o containers.

Escalado del campo de visión

La propiedad Keep Aspect del nodo de la Cámara 3D se ajusta por defecto al modo de escala Keep Height (también llamado Hor+). Este suele ser el mejor valor para los juegos de escritorio y los juegos para móviles en modo apaisado, ya que las pantallas panorámicas utilizarán automáticamente un campo de visión más amplio.

Sin embargo, si tu juego 3D está pensado para ser jugado en modo retrato, puede tener más sentido usar Mantener el ancho en su lugar (también llamado Vert-). De esta manera, los smartphones con una relación de aspecto superior a 16:9 (por ejemplo, 19:9) usarán un campo de visión más alto, lo cual es más lógico aquí.

Escalando elementos 2D y 3D de manera diferente usando Viewports

Usando múltiples nodos de Viewport, puedes tener diferentes escalas para varios elementos. Por ejemplo, puedes usar esto para renderizar el mundo 3D a baja resolución mientras mantienes los elementos 2D a la resolución nativa. Esto puede mejorar el rendimiento de forma significativa mientras se mantiene el HUD y otros elementos 2D nítidos.

Esto se hace utilizando el nodo raíz de Viewport sólo para los elementos 2D, luego creando un nodo de Viewport para mostrar el mundo 3D y mostrándolo utilizando un nodo ViewportContainer o TextureRect. Habrá efectivamente dos Viewports en el proyecto final. Una ventaja de usar TextureRect en lugar de ViewportContainer es que permite habilitar el filtrado lineal. Esto hace que las vistas 3D escaladas se vean mejor en muchos casos.

Ver demostración de escalado del viewport 3D para conocer algunos ejemplos.