# 17. Фон игрового поля и меню

Table of Contents

17. Фон игрового поля и меню

Цель

Уйти от плоского одноцветного меню и сделать фон партии и главного экрана единым космическим стилем: глубина за счёт градиента, живость за счёт мерцания звёзд и мягкой «туманности», не перегружая мобильный GPU.

Описание выполненной работы

Структура нового starfield_bg.gdshader

Шейдер типа canvas_item работает в пространстве UV всего экрана (0…1 по обеим осям). Вместо одного параметра sky_dark введены:

  • sky_bottom и sky_top — цвета нижней и верхней части экрана; смешивание идёт по pow(uv.y, …), чтобы низ был чуть темнее и «тяжелее», верх — слегка прохладнее (типичный night sky для портретной ориентации).

Дальше добавлены процедурные слои:

  1. Туманность — значения vnoise на двух-трёх масштабах UV, смещаемых медленно через TIME (скорости порядка 0.01…0.02 по разным осям). Это даёт мягкое движение без резких артефактов. Две палитры nebula_a и nebula_b смешиваются по второму шумовому каналу и суммируются с градиентом с ограничением clamp для контроля насыщенности.

  2. Звёзды первого слоя — прежняя логика hash по ячейкам сетки floor(uv * vec2(420, 740)), но результат смешивается с общей «дышащей» синусоидальной модуляцией по времени.

  3. Звёды второго слоя — более мелкая сетка (900 × 1580), более высокий порог smoothstep для hash, чтобы получить много мелких точек без пересвета.

  4. Гало по центру — множитель halo от расстояния до точки (0.5, 0.42) слегка прижимает яркость звёзд к краям экрана — зона HUD и центрального заголовка менее зашумлена светящимися точками.

  5. Виньетка — финальный множитель по length(uv - 0.5) затемняет углы и помогает сфокусировать внимание на доске или блоке кнопок.

Функции hash и vnoise продублированы в этом файле намеренно, чтобы не тянуть preload других скриптов — canvas_item шейдеры компилируются автономно.

Совместное использование на поле и в меню

И game_board.tscn, и title_screen.tscn используют ShaderMaterial с одним и тем же ресурсом шейдера. Это означает:

  • любое улучшение неба автоматически проявится везде;
  • при необходимости можно добавить uniform bool menu_dim или второй ShaderMaterial с другими shader_parameter через инспектор, не дублируя файл шейдера.

На титульном ColorRect установлен color = Color(1,1,1,1), чтобы TEXTURE/COLOR умножение не приглушало результат шейдера. mouse_filter = ignore отключает перехват событий фоном — клики идут в VBox как раньше.

Производительность на Android

Шейдер выполняется один раз на полноэкранный ColorRect; сложность — несколько hash/**vnoise** на пиксель плюс тригонометрия для мерцания. На типичном телефоне при 720×1280 это обычно дешевле, чем большой статический текстура-тайл высокого разрешения с прокруткой.

Если профилировщик покажет узкое место:

  • уберите второй слой звёзд или замените sin(TIME …) на редко обновляемый uniform из GDScript;
  • уменьшите число вызовов vnoise в туманности;
  • понизьте precision директивой компилятора (редко нужно).

Контент против процедурности

В плане упомянуто «фоновое изображение» — для казуальной игры процедурный фон даёт малый размер apk и отсутствие артефактов сжатия JPEG/PNG на градиентах. Если позже понадобится художественная иллюстрация:

  1. Замените ColorRect на TextureRect с expand_mode и поверх добавьте полупрозрачный ColorRect со смягчённым шейдером звёзд.
  2. Или смешайте текстуру в шейдере: uniform sampler2D bg_art и mix(tex.rgb, procedural, factor).

Текущая реализация намеренно не добавляет новые файлы png — только код.

Проверка на устройстве

Посмотрите партию при ярком солнечном свете и в темноте: если звёзды «сыпятся» слишком ярко, уменьшите коэффициенты tw1/tw2 или усильте halo/виньетку. Если верх экрана кажется пустым — слегка поднимите sky_top к более светлому голубому.

Связь с соседними шагами плана

Шаг 16 обеспечил читаемость кнопок и панелей на сложном фоне; шаг 17 добавляет атмосферу без конфликта с HUD. Шаг 18 (splash) реализован статическим кадром в той же палитре — см. posts/18-splash-screen.md; шейдер starfield_bg по-прежнему изолирован в res://shaders/.

Экспорт, mip-mapping и будущие uniform-параметры

При добавлении uniform для тонкой настройки (например star_density или nebula_strength) помните: ShaderMaterial на title_screen и game_board — это два экземпляра. Если хотите менять параметры одним местом, повесьте скрипт на корень сцены или используйте Resource ShaderMaterial с .duplicate(false) только когда нужно различие между меню и партией.

Для GLES3/мобильных драйверов** избегайте экстремальных экспонентов в **pow(uv.y, …)** без **clamp** входа — мы уже ограничиваем **uv.y** через **clamp(uv.y, 0.0, 1.0)** в смешении градиента. Если когда‑нибудь понадобится **HDR** bloom поверх неба, проще добавить отдельный **CanvasLayer** с **ColorRect** и **additive`** материалом, не меняя базовый шейдер звёзд.

UX и доступность на ярком солнце

Яркие звёзды на OLED могут утомлять; uniform-параметры sky_bottom и sky_top можно связать с опцией «контраст фона» в GameSettings в будущем: параметры шейдера доступны из material.set_shader_parameter. На первом этапе достаточно консервативных коэффициентов tw1/tw2 и усиленной виньетки — они уже делают центр экрана спокойнее для текста заголовка и счёта.

Контрольный список после правок шейдера

Просмотрите на эмуляторе и реальном устройстве: нет ли цветового бэнда на градиенте (если есть — добавьте шум dither либо повысите битность буфера через настройки рендера проекта); нет ли «шахматных» узоров при медленном движении туманности (увеличьте период TIME или сгладите vnoise дополнительным smoothstep); сохранилась ли стабильность FPS при паузе приложения (NOTIFICATION_APPLICATION_PAUSED не останавливает шейдерное время автоматически — это нормально для фона, но можно заморозить TIME через shader_parameter из GameAudio или корня дерева при желании экономить батарею).

Ссылка на проект: Third Planet

Ссылка на игру: Google Play Rustore

Next: 18. Стилизация splash screen
Аватар автора

Спасибо, что прочитали статью. Посмотрите другие материалы в архиве, там много практических разборов по разным технологиям.


godot Series

# 16. Тени

godot 16 / 19
4 min read

Тени через StyleBoxFlat у ячеек, HUD, слота баннера и карточки результата; стили кнопок на титуле и поле; лёгкий контактный затемнённый слой на шарах-планетах.

Read