Разработка шейдеров растительности и ветра для графики

Наша компания по разработке видеоигр ведет независимые проекты, совместно с клиентом создает игры и оказывает дополнительные операционные услуги. Опыт нашей команды позволяет нам охватить все игровые платформы и разработать потрясающий продукт, соответствующий видению клиента и предпочтениям игроков.

От иммерсивных приложений до игровых миров и 3D-сцен

Наша выделенная команда для VR/AR/MR-разработки, Unity-продакшна и 3D-моделирования и анимации с собственными кейсами и презентациями.

Посетить персонализированный сайт
Показано 1 из 1 услугВсе 242 услуг
Разработка шейдеров растительности и ветра для графики
Сложная
от 3 рабочих дней до 2 недель
Часто задаваемые вопросы
Наши компетенции
Какие этапы разработки игры?
Последние работы
  • image_games_mortal_motors_495_0.webp
    Разработка игры для компании Mortal Motors
    683
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Пошаговая стратегия в фэнтези сеттинге With Fire And Sword
    860
  • image_games_second_team_604_0.webp
    Разработка игры для компании Second term
    490
  • image_games_phoenix_ii_606_0.webp
    3D-анимация — тизер для игры phoenix 2.
    533

Разработка шейдеров растительности и ветра для графики

Деревья и трава в играх — это не статические меши. Это тысячи instances, каждый из которых должен двигаться убедительно под ветром, корректно принимать освещение через тонкие листья, не создавать z-fighting на полупрозрачных гранях и не убивать производительность на мобильных устройствах. Сделать это правильно — значит решить несколько несвязанных между собой технических проблем одновременно.

Vertex animation для ветра: почему скелетная анимация не подходит

Дерево с тысячей листьев нельзя анимировать через кости — это сотни skinned mesh renderer вызовов. Стандартное решение — vertex shader animation, где перемещение вершины закодировано в самом шейдере и управляется параметрами ветра через Material Property Block или Global Shader Property.

В ShaderGraph (URP/HDRP) алгоритм строится так: Transform Position нода → World Position → добавляем Sine-based offset по двум осям (X и Z) с Time + Phase Offset. Phase Offset — критически важный параметр: он кодируется в вершинный цвет или UV-канал меша (обычно UV2) на этапе подготовки ассета. Без phase offset все ветки дерева движутся синхронно — это выглядит как механическое покачивание, а не органический ветер.

Иерархический ветер — настоящий differentiator качественного vegetation shader'а. Движение разбивается на три уровня:

  • Trunk sway (раскачивание ствола) — низкая частота, большая амплитуда, вся геометрия дерева
  • Branch flutter (движение ветвей) — средняя частота, меньшая амплитуда, закодирована через R-канал Vertex Color
  • Leaf shimmer (трепет листьев) — высокая частота, минимальная амплитуда, G-канал Vertex Color

В шейдере каждый уровень — отдельный Sine с разными frequency и amplitude параметрами. Weight для каждого уровня берётся из vertex color канала. Это означает, что художник должен запечь vertex colors в дереве перед экспортом: у основания ствола R=0 (нет branch flutter), у концов ветвей R=1.

Двусторонняя отрисовка и alpha clipping

Листья — это полигональные карточки (billboard quads или meshcard strips) с alpha texture. Проблемы два типа:

Alpha blending vs Alpha Clipping. Blending правильно сортирует полупрозрачность, но требует правильного depth sorting всех листьев, что невозможно без GPU-side sorting. На практике для vegetation используют Alpha Clipping (Alpha Test): жёсткая граница по порогу, без blending. Это даёт артефакты на краях, но работает корректно с depth buffer и инстансингом. Порог (Cutoff) обычно 0.4–0.6 в зависимости от текстуры.

Двустороннее освещение. Lit шейдер по умолчанию освещает только front face. Для листьев нужен Two Sided материал с Flip Normals на back face — иначе задняя сторона листа будет чёрной при любом освещении. В ShaderGraph это Two Sided checkbox в Graph Settings + Facing нода для применения normal flip.

Subsurface scattering для листьев. Реальные листья просвечиваются на солнце. В URP для vegetation используют Translucency аппроксимацию: берём dot product между Light Direction и View Direction, добавляем его к Albedo через Lerp с translucency color (тёплый зелёный). Это ~4 ноды в ShaderGraph, добавляет +0.1ms к стоимости шейдера, но разница в визуальном качестве очевидна.

Инстансинг и GPU Instancing

Трава и деревья требуют GPU Instancing — иначе каждый куст это отдельный draw call. В Unity для vegetation правильный подход:

  • Graphics.DrawMeshInstanced или Graphics.DrawMeshInstancedIndirect для процедурной растительности
  • Unity Terrain Detail Mesh — встроенный инстансинг для детализации террейна
  • SpeedTree integration (встроен в Unity, но требует лицензию SpeedTree для редактирования)

Шейдер должен поддерживать #pragma instancing_options и использовать UNITY_SETUP_INSTANCE_ID в вершинном шейдере. В ShaderGraph это автоматически, но при написании кастомного HLSL через Custom Function нода нужно явно добавить эти pragma.

Material Property Block позволяет передавать per-instance параметры (phase offset, wind strength multiplier) без создания отдельного Material на каждый instance — это критично для performance при сотнях инстансов с разными параметрами.

Настройка ветра через Global Shader Properties

Ветер в сцене — это глобальный параметр. Правильная архитектура: WindController MonoBehaviour устанавливает Shader.SetGlobalFloat("_WindStrength", strength) и Shader.SetGlobalVector("_WindDirection", dir) каждый кадр (или по событию изменения ветра). Все vegetation шейдеры читают эти глобальные параметры через Global нодой в ShaderGraph (Custom Function: UNITY_ACCESS_INSTANCED_PROP для per-instance или просто float из Global для shared).

Это даёт возможность делать динамические эффекты ветра: усиление при шторме, порыв при взрыве рядом, смена направления через день-ночной цикл — всё через один контроллер без изменения материалов.

Тип задачи Срок
Шейдер травы (URP, mobile, с ветром) 2–4 дня
Шейдер дерева (URP, иерархический ветер, PBR листья) 4–7 дней
Vegetation shader set (трава + кусты + деревья) 1–2 недели
HDRP с subsurface + translucency 1–2 недели

Стоимость рассчитывается индивидуально по результатам обсуждения рендер-пайплайна, целевой платформы и стиля графики.