Как обойти ограничение 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:
С height blending:
В чём проблема?
У Unity есть жёсткое ограничение: height-based blending работает только при 4 слоях или меньше.
Почему именно 4? Это связано с архитектурой splatmap (карты весов):
Unity хранит веса слоёв в RGBA-текстуре4 канала (R, G, B, A) = максимум 4 слоя на один «патч» терраинаHeight blending работает с этими 4 весами одновременно. Сам по себе лимит в 4 слоя не был бы критичным — можно использовать height blending для 4 основных материалов (трава, тропинки, песок, снег) и смешивать остальные менее значимые слои (земля, мох, гравий) обычным способом.
НО! Unity полностью отключает height blending, если на терраине больше 4 слоёв. Даже для первых четырёх!
Если на терраине больше 4ех слоев — height blending просто не работает ни для одного из них.
Решение
Идея простая: вместо проверки общего количества слоёв — проверяем тип рендер-пасса.
Как Unity рендерит многослойный терраин?
Unity разбивает рендеринг на несколько проходов:
1. Base Pass(слои 0–3): первые 4 слоя рендерятся в базовом проходе
2.Additive Pass 1(слои 4–7) следующие 4 слоя рендерятся и добавляются к базовому
3.Additive Pass 24.и так далее…
Каждый проход работает максимум с 4 слоями (RGBA).
Если это базовый проход (первые 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, эта модификация вам не нужна.
Несколько примеров До / После
Файлы
Все файлы в репозитории: https://github.com/ArtemSin/TerrainURPLitHeightBlend
TerrainURPLitHeightBlend.shader — основной шейдер
CustomTerrainLitAddPass.shader — шейдер аддитивного проходаTerrainLitPassesModified.hlsl — модифицированный файл проходов
Добавляйте Tiny Delivery и подписывайтесь куда подпишитесь , если интересен данный формат и просто интересно следить за ходом разработки
Кстати на моем бесплатном бусти эта статья вышла намного раньше , ну это так, к слову
Чао :)