Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями

Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями

В этой статье я покажу, как обойти ограничение Unity на 4 слоя при height-based blending на терреине. Это простая модификация включает height blending для первых 4 слоёв независимо от общего количества слоёв (8, 12, 16+)

Важно:
Height-based blending будет работать только для первых 4 слоёв; дополнительные слои будут использовать стандартное альфа-смешение. Ссылка на гит в конце

Решение реализовано в Unity 6.3 (URP)
Поскольку я использовал исходники Terrain Lit Shader от Unity, совместимость с версиями ниже Unity 6 или HDRP зависит от того, были ли изменены оригинальные шейдеры терраина в тех версиях.

Это решение я сейчас использую в своей игре Tiny Delivery . Хотя возможно позже я сделаю что то более универсальное вообще без ограничений

Что такое Height-Based Blending вообще?

Если коротко: каждый слой терраина может иметь Mask Map — специальную текстуру с дополнительными данными материала:

  • R — Metallic
  • G — Ambient Occlusion
  • B —Mask/Height — вот это нам и нужно
  • A — Smoothness
свойства слоев террейна
свойства слоев террейна

Height blending использует данные высоты из B-канала, чтобы переходы между слоями выглядели не как альфа-смешение, а как что-то реальное — трава прорастает сквозь гравий, земля выглядывает из-под снега и т.д.

Пример

Представьте переход между травой, тропинкой и плиткой:

Без height blending:

Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями

С height blending:

Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями

В чём проблема?

У Unity есть жёсткое ограничение: height-based blending работает только при 4 слоях или меньше.

Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями

Почему именно 4? Это связано с архитектурой splatmap (карты весов):

Unity хранит веса слоёв в RGBA-текстуре4 канала (R, G, B, A) = максимум 4 слоя на один «патч» терраинаHeight blending работает с этими 4 весами одновременно. Сам по себе лимит в 4 слоя не был бы критичным — можно использовать height blending для 4 основных материалов (трава, тропинки, песок, снег) и смешивать остальные менее значимые слои (земля, мох, гравий) обычным способом.

НО! Unity полностью отключает height blending, если на терраине больше 4 слоёв. Даже для первых четырёх!

// оригинальный TerrainLitPasses.hlsl #ifdef _TERRAIN_BLEND_HEIGHT if (_NumLayersCount <= 4) //проблема тут! HeightBasedSplatModify(splatControl, masks); #endif

Если на терраине больше 4ех слоев — height blending просто не работает ни для одного из них.

Решение

Идея простая: вместо проверки общего количества слоёв — проверяем тип рендер-пасса.

Как Unity рендерит многослойный терраин?

Unity разбивает рендеринг на несколько проходов:

1. Base Pass(слои 0–3): первые 4 слоя рендерятся в базовом проходе

2.Additive Pass 1(слои 4–7) следующие 4 слоя рендерятся и добавляются к базовому

3.Additive Pass 24.и так далее…

Каждый проход работает максимум с 4 слоями (RGBA).

#ifdef _TERRAIN_BLEND_HEIGHT #ifndef TERRAIN_SPLAT_ADDPASS // новая проверка! HeightBasedSplatModify(splatControl, masks); #endif #endif

Если это базовый проход (первые 4 слоя) → применяем height blendingЕсли это аддитивный проход (слои 5+) → используем стандартное смешение

Первые 4 слоя получают красивые реалистичные переходы, дополнительные слои работают в штатном режиме.
Расписывать весь код не особо вижу смысла , тк тут все же главное принцип , по этому сразу перейдем к готовому решению:

Имплементация

1: Импортировать Unity Package: https://github.com/ArtemSin/TerrainURPLitHeightBlend

2: Создать материал для терреина

  • Создать новый материал (ПКМ → Create → Material)
  • Назначить шейдер: Custom/TerrainURPLitHeightBlend

Шаг 3: Применить к терраину

  • Выбрать Terrain в сцене
  • В Inspector → Terrain Settings → Material
  • Назначить созданный материал
  • Включить Enable Height Blend
  • Настроить Height Transition (рекомендую 0.1–0.3)

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

Влияние на FPS: практически нулевое (менее 1–2%)Height blending применяется только к 4 слоям (как и раньше)Аддитивные проходы работают ровно как в оригиналеНикаких дополнительных сэмплов текстур или вычислений

Ограничения и альтернативы

Height blending работает только для первых 4 слоёв

Слои 5+ используют стандартное альфа-смешение.

Если мы говорим о том что бы все слои юзали Height blending , то конечно же нужно более сложное решение - это либо рендерить в несколько текстур и считывать в additive pass , либо как то по другому обыгрывать .Думаю я этим займусь уже позже, если пойму что heigh blend нужен будет под все текстуры, ну а пока что вот так :)
А если у кого то такое решение уже есть , я всегда буду рад его принять :D

Примечания

Более продвинутые платные решения, скорее всего, есть в Asset Store, но я не исследовал, что там сейчас есть.
Предупреждение Unity: С этим решением предупреждение Unity о количестве слоёв никуда не денется. Можно написать кастомный Editor скрипт, чтобы убрать его, если хочется, но лично мне не мешает.
Тестирование: Шейдер протестирован на Unity 6.3 (URP) с терраинами от 4 до 16 слоёв. Если у вас меньше 4 слоёв — используйте стандартный шейдер Unity, эта модификация вам не нужна.
Несколько примеров До / После

Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями
Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями
Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями
Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями
Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями
Как обойти ограничение Unity на Height Blending у терреина с 4+ слоями

Файлы

Все файлы в репозитории: https://github.com/ArtemSin/TerrainURPLitHeightBlend
TerrainURPLitHeightBlend.shader — основной шейдер
CustomTerrainLitAddPass.shader — шейдер аддитивного проходаTerrainLitPassesModified.hlsl — модифицированный файл проходов
Добавляйте Tiny Delivery и подписывайтесь куда подпишитесь , если интересен данный формат и просто интересно следить за ходом разработки
Кстати на моем бесплатном бусти эта статья вышла намного раньше , ну это так, к слову
Чао :)

14
1
1
12 комментариев