Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Подсказки / Пример смешивания текстур ландшафта в Titan Quest.

Пример смешивания текстур ландшафта в Titan Quest.

Автор:

Для текстурирования местности, построенной на карте высот, наибольшее распространение получил метод, использующий несколько слоев бесшовных (затайленых) текстур. Слои накладываются один поверх другого и смешиваются для получения финального изображения. В дополнение к бесшовной текстуре каждый слой имеет карту прозрачности, определяющую с каким весом текстура слоя смешивается в любой точке местности. В отличие от самой бесшовной текстуры, эта карта прозрачности растягивается на весь ландшафт, и, следовательно, имеет очень низкую детализацию.

titanquest_low | Пример смешивания текстур ландшафта в Titan Quest.
Текстурированный ландшафт в Titan Quest.

Рассмотрим простой пример. Наша местность будет состоять из двух слоев — травы и песка. В любой точке, где карта прозрачности для слоя травы хранит 1.0 (непрозрачно), мы увидим только траву. Там, где карта прозрачности хранит 0.0, мы увидим песок, и там, где было 0.5, мы увидим промежуточное состояние — песок, смешанный с травой. Обратите внимание, что самый нижний слой не имеет карты прозрачности, так как основной слой должен быть виден везде.

Операция для смешивания двух текстур будет выглядеть так:

float4 blend(float4 texture0, float4 texture1, float layerOpacity)
{
    return lerp(texture0, texture1, layerOpacity);
}

Недостаток этой простой техники в том, что если приглядеться поближе, смешивание травы и песка 50/50 выглядит не очень хорошо.

alphablend | Пример смешивания текстур ландшафта в Titan Quest.

Результат смешивания (внизу) больше напоминает зеленый песок, а не клочок травы в песке. Если бы текстуры лучше соотносились друг с другом, результат выглядел бы лучше. Проблему можно было бы решить дополнительными текстурами переходов, созданными художниками. Однако это добавляет художникам работы, и требует отрисовки дополнительного текстурного слоя. Наконец, для каждой комбинации текстур, которые мы собираемся использовать на местности, нам понадобятся разные текстуры переходов. И в конечном итоге нам понадобится несколько таких текстур.

Существует способ c простым решением, который использовался в Titan Quest. Идея в том, чтобы вместо рисования 50% текстуры в каждом пикселе, рисовать одну текстуру в 50% пикселей, и другую текстуру в других 50%.

Вот как выглядит результат в этом случае:

selectblend | Пример смешивания текстур ландшафта в Titan Quest.

Чтобы реализовать это метод, мы храним маску в альфа-канале каждой бесшовной текстуры. Эта маска использует полный диапазон значений, и определяет, будет ли виден тексель, если текстурный слой местности имеет определенную прозрачность. Иными словами, тексель отрисовывается, если значение маски меньше, чем значение непрозрачности слоя.
Эта новая «пятнистая» техника смешивания просто реализуется так:

float4 blend(float4 texture0, float4 texture1, float layerOpacity)
{
    if (texture1.a < layerOpacity)
    {
        return texture1;
    }
    else
    {
        return texture0;
    }
}

Результат выглядит более естественно, и структура пятен может быть подогнана индивидуально для каждого типа текстур. Так, текстура травы использует зашумленный узор. Текстуры с более крупными элементами — такими как камни — могут быть настроены таким образом, что смешивание будут следовать структуре. Для камней альфа-маска может хранить большие значения для трещин, и небольшие значения для плоских поверхностей. При смешивании слоя камней поверх слоя травы, трава будет появляться в трещинах в камне по мере роста прозрачности слоя.

Из-за бинарного характера сравнения, результат будет иметь жесткие границы и показывать сильный алиасинг. Гораздо лучше получается при небольшом смешивании границ между текстурами при помощи обычного альфа-блендинга.
Вот один из способов сделать это, хотя другие методы определенно могут быть использованы тоже (для Titan Quest использовался более простой метод, чтобы втиснуться в лимит на число инструкций для ps1.0):

float4 blend(float4 texture0, float4 texture1, float layerOpacity)
{
    const float blendRange = 0.1;
 
    if (texture1.a < layerOpacity - blendRange)     
    {
         return texture1;
    }
    else if (texture1.a > layerOpacity + blendRange)
    {
        return texture0;
    }
    else
    {
        float f = (texture1.a - layerOpacity + blendRange) / (2 * blendRange);
        return lerp(texture1, texture0, f);
    }
}

Вот как выглядит финальный результат:

smoothedselectblend | Пример смешивания текстур ландшафта в Titan Quest.

Хотя примеры показаны только для случая с двумя текстурами, любое количество слоев может быть смешано таким же образом, как и с простой техникой.

Этот тип смешивания также не ограничен текстурированием ландшафтов. Интересные эффекты могут быть получены анимированием прозрачности слоя. Например, вот как работает такой же тип смешивания в прототипе динамического заражения для Natural Selection 2:

Это перевод записи Blending Terrain Textures:
http://www.m4x0r.com/blog/2010/05/blending-terrain-textures/

18 мая 2010

#ландшафт, #текстурирование

2001—2017 © GameDev.ru — Разработка игр