Sunshine

Moderator
Модератор

Sunshine

Moderator
Модератор
Сообщения
289
Реакции
95
Баллы
121
Возраст
18
Всем привет. Данная статья написана не мной, а моим коллегой , на английском языке. Статья действительно полезная и я решил перевести на русский язык. Я сам некоторое время занимался gamedev разработкой и с уверенностью могу сказать, что данная статья очень полезна, так как она описывает базовые принципы создания естественного текстурирования. Очень жаль, что когда я писал свой платформер, этой статьи ещё не было.

Итак, для начала давайте разберемся, что значит усовершенствованные? Для примера я вам покажу два изображение и вы их сравните:

Вы должны быть зарегистрированы для просмотра прикрепленных изображений
Вы должны быть зарегистрированы для просмотра изображений

Согласитесь, второй вариант лучше. Именно об этом эта статья: о том, как создать более естественные текстуры.

Одним из наиболее распространенных способов текстурирования ландшафта является смешивание нескольких тайлов. Каждый из них имеет уровень непрозрачности, который определяет степень присутствия текстуры на местности. Метод эффективен, когда нижние слои более непрозрачны, но при условии, что сумма всех уровней непрозрачности составляет 100%.
Теперь перейдем к самой интересной части - алгоритмам наложения текстур. Для простоты и наглядности наша местность будет состоять из песка и крупных булыжников.

Вы должны быть зарегистрированы для просмотра изображений

Самый простой способ наложения - умножить цвет текстуры на непрозрачность и затем суммировать результаты.
C++:
float3 blend(float4 texture1, float a1, float4 texture2, float a2)
{
    return texture1.rgb * a1 + texture2.rgb * a2;
}
Такой метод используется в Unity3D в стандартном редакторе ландшафта. Вы можете увидеть, что переход плавный, но неестественный. Камни выглядят равномерно испачканными песком, но в реальном мире такого не бывает. Песок не прилипает к камням, он падает и заполняет щели между ними, оставляя вершины камней чистыми.

Давайте попробуем смоделировать это поведение на графиках Excel. Поскольку мы хотим, чтобы песок «упал» между булыжниками, для каждой текстуры нам нужна карта глубины. В этом примере мы считаем, что карта глубины генерируется из изображения в градациях серого и сохраняется в альфа-канале текстуры. В Unity3D это можно сделать в инспекторе текстур, установив параметр «Alpha From Grayscale».
Для начала рассмотрим упрощенную модель карты глубины песка и камней:

Вы должны быть зарегистрированы для просмотра изображений

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

C++:
float3 blend(float4 texture1, float a1, float4 texture2, float a2)
{
    return texture1.a > texture2.a ? texture1.rgb : texture2.rgb;
}
Вы должны быть зарегистрированы для просмотра изображений

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

C++:
float3 blend(float4 texture1, float a1, float4 texture2, float a2)
{
    return texture1.a + a1 > texture2.a + a2 ? texture1.rgb : texture2.rgb;
}
Вы должны быть зарегистрированы для просмотра изображений
Вы должны быть зарегистрированы для просмотра изображений

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

C++:
float3 blend(float4 texture1, float a1, float4 texture2, float a2)
{
    float depth = 0.2;
    float ma = max(texture1.a + a1, texture2.a + a2) - depth;

    float b1 = max(texture1.a + a1 - ma, 0);
    float b2 = max(texture2.a + a2 - ma, 0);

    return (texture1.rgb * b1 + texture2.rgb * b2) / (b1 + b2);
}
В приведенном выше коде мы сначала видим часть земли, отображаемую на определенной глубине.

Вы должны быть зарегистрированы для просмотра изображений

А затем мы нормализуем его, чтобы получить новое смешивание.

Вы должны быть зарегистрированы для просмотра изображений

Вы должны быть зарегистрированы для просмотра изображений

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