Open 0x4E69676874466F78 opened 11 months ago
Не очень понятно вообще, как к этому подступаться.
Из каких-то быстрых идей может быть следующая: каким-то образом к каждому ребру геометрии подтаскивать метаданные вида "граничу с такой-то тестурой, должны быть такие-то текстурные координаты в вершинах". Тогда в шейдере можно понять, насколько мы далеко от такой грани, и как-то смешивать.
Но эту идею придумать было быстро, а реализовать хз как, и долго.
Обычно в играх это делается через terrain blending, опишу своими словами как понимаю (дилетанстки) без всякого гуглежа сам:
Дальше идём искать примеры:
https://habr.com/ru/companies/pixonic/articles/490226/ обширная статья на все случаи, конкретно крути вниз к "текстуры с весовыми коэффициентами для смешивания слоев" https://github.com/jensnt/TerrainHeightBlend-Shader пример реализации для юнити https://codeberg.org/sparseMatrix/Height-Blending-Terrain-Shader/src/branch/master/Adam-HeightBlendTerrain ещё один https://www.shadertoy.com/view/WsB3zc какой-то пример на шейдертое не знаю уместный ли.
Совсем забыл упомянуть трипланарную проекцию которая для гор важна, иначе текстуры могут некрасиво растягиваться.
В целом @lifekilled сам вроде писал подобный шейдер, можно узнать у него как такое можно сделать более оптимально.
Для других игр где есть ландшафт это будет необходимо.
Базовый функционал шейдера для terrain это splat map - текстуры масок. Один цветовой канал (R, G, B или A) это маски текстур. Очень удобно, если текстуры лежат в массиве. Можно сэмплить только те, у которых маска больше 0. Этих масок может быть много, если надо больше четырех текстур. Логика простая. Фактически это просто задачка смешивания нескольких текстур по одной маске, такими пользуются дизайнеры в Анриле.
Я писал шейдер для terrain в Юнити, потому что в базовом шейдере не хватало фич. Я добавлял triplanar, cellshading и heightmap blending. То есть не просто мягкое смешивание текстур по маске, а особый алгоритм, чтобы на границе был резкий переход по формам, заданным текстурой высоты. Например, чтобы на границе травы и камней пучки травы пробивались между щелей в камнях
Вот этот блендинг это уже следующий (самый простой) шаг, после того, как мы понимаем, что с чем блендить, поэтому я его упомянул только на уровне "как-то смешивать", он сам собой разумеется.
Самое сложное в этой задаче это как раз сообразить, что у нас разрыв, понять, чего с чем разрыв алгоритмически, и как-то дотащить эти сведения до блендинга.
Это можно захачить через (пока отсутствующие, но я как раз хотел попробовать их сделать через такой блендинг) декали -- руками во все найденные разрывы накидать полигонов с декалями, чтобы они блендились с обоими участниками разрыва. Неясно, насколько муторно будет делать инструментарий для этого, и насколько оно будет выглядеть не погано.
Если будет какой-то буфер с декалями ("коробка", которая ее проецирует в виде матрицы, номер материала), то можно в отдельном пассе спроецировать их на уже готовые буферы base_color_a, material_rmxx и normals_gs, не используя лучи. Главное просто сделать их список в шейдере. Остальное просто
Кстати, разноображивать декалями террейн и окружение - рабочий способ, которым пользуются дизайнеры. Шейдер террейна это просто грубая основа, а всё самое основное делается декалями и модельками камушков
Облепить резкие швы между брашами с помощью декалей - неплохая идея. А трипланар в этом случае будет эффективным только если получится сгладить в этих местах нормали, потому что именно по мягким нормалям можно смешивать разные стороны трипланара. Если оставить переходы резкими, трипланар не сработает
Это техника уже есть в rtx remix, но она там на тот момент как я смотрел была глобальна и из-за этого коряво работает, мы же можем воспользоваться правилами материалов или патчей, что вот такие-то текстуры смешать между собой на границах.
Сейчас у нас наблюдается подобное: PBR-текстурами это особо не спасти:
Можно зафорсить одну текстуру, но это не везде поможет и в целом текстура начнёт угадываться.