Текстуры (часть 3)
В прошлой статье мы разбирали как мы можем модифицировать наши текстуры на объектах. А сейчас мы пройдем последнюю часть про текстуры, освоим фильтрацию, мипмэппинг и оптимизацию!
Если вы посмотрите на верхнюю грань куба, когда эта грань почти скрыта, вы увидите очень размытую текстуру.
Mipmapping (или "mip mapping" с пробелом) - это техника, которая заключается в создании наполовину меньшей версии текстуры снова и снова, пока не получится текстура 1x1. Все эти варианты текстуры отправляются на GPU, и GPU выбирает наиболее подходящую версию текстуры.
Three.js
и GPU уже обрабатывают все это, и вы можете просто установить, какой алгоритм фильтрации использовать. Существует два типа алгоритмов фильтрации: фильтр минификации и фильтр увеличения.
Фильтр минификации
Фильтр минификации срабатывает, когда пиксели текстуры меньше пикселей рендера. Другими словами, текстура слишком велика для поверхности, которую она покрывает.
Вы можете изменить фильтр минификации текстуры с помощью свойства minFilter
.
Вот какие значения существуют:
THREE.NearestFilter
THREE.LinearFilter
THREE.LinearMipmapNearestFilter
THREE.LinearMipmapLinearFilter
THREE.NearestMipmapNearestFilter
THREE.NearestMipmapLinearFilter
По умолчанию используется фильтр THREE.LinearMipmapLinearFilter
. Если вам не нравится то, как выглядит ваша текстура, попробуйте другие фильтры.
Мы не будем рассматривать каждый из них, но мы протестируем THREE.LinearFilter
, который дает совсем другой результат:
colorTexture.minFilter = THREE.LinearFilter;
Если вы используете устройство с соотношением пикселей больше единицы, вы не увидите особой разницы. Если нет, расположите камеру так, чтобы это грань куба была почти скрыта, и вы должны получить больше деталей и странных артефактов.
Артефакты, которые некоторого размытия, называются муаровыми узорами, и обычно их лучше избегать.
Фильтр увеличения
Фильтр увеличения работает так же, как и фильтр уменьшения, но когда пикселей текстуры больше, чем пикселей рендера. Другими словами, текстура слишком мала для поверхности, которую она покрывает.
Вы можете увидеть результат, используя текстуру checkerboard-8x8.png, которая расположена в папке static/textures/
:
const colorTexture = textureLoader.load('/textures/checkerboard-8x8.png');
Текстура становится размытой, потому что это очень маленькая текстура на очень большой поверхности.
Хотя вы можете подумать, что это выглядит ужасно, это, вероятно, к лучшему.
Можно изменить фильтр увеличения текстуры с помощью свойства magFilter
.
Есть только два возможных значения:
По умолчанию используется THREE.LinearFilter
.
Если вы протестируете THREE.NearestFilter
, вы увидите, что базовое изображение сохраняется, и вы получите пикселизированную текстуру:
Это может быть полезно, если вы хотите создать стиль с пиксельными текстурами.
Вы можете увидеть результат, используя текстуру minecraft.png
, расположенную в папке static/textures/
:
const colorTexture = textureLoader.load('/textures/minecraft.png');
И последнее слово обо всех этих фильтрах: THREE.NearestFilter
дешевле других, и вы должны получить лучшие показатели скорости отрисовки при его использовании.
Используйте мипмапы только для свойства minFilter
. Если вы используете THREE.NearestFilter
, вам не нужны мипмапы, и вы можете отключить их с помощью colorTexture.generateMipmaps = false
:
colorTexture.generateMipmaps = false; colorTexture.minFilter = THREE.NearestFilter;
Это немного разгрузит графический процессор.
Формат и оптимизация текстур
При создании текстуры, важно помнить о трех важнейших элементах:
Вес
Не забывайте, что пользователям, заходящим на ваш сайт, придется скачивать эти текстуры. Вы можете использовать большинство типов изображений, которые мы используем в Интернете, например .jpg (сжатие с потерями, но обычно легче) или .png (сжатие без потерь, но обычно тяжелее).
Попробуйте применить обычные методы, чтобы получить приемлемое изображение, но как можно более легкое. Для этого можно воспользоваться утилитами или сервисами для сжатия.
Размер
Так как каждый пиксель используемых текстур должен храниться на GPU независимо от веса изображения. А GPU, как и ваш жесткий диск, имеет ограничения по объему памяти. Это еще хуже, потому что автоматически создаваемый мипмэппинг увеличивает количество пикселей, которые необходимо хранить.
Старайтесь максимально уменьшить размер ваших изображений.
Если вы помните, что мы говорили о мипмаппинге, Three.js
будет создавать уменьшенную вдвое версию текстуры несколько раз, пока не получит текстуру 1x1. Поэтому ширина и высота вашей текстуры должны быть кратна 2. Это необходимо для того, чтобы Three.js
мог разделить размер текстуры на 2.
Некоторые примеры: 512x512, 1024x1024 или 512x2048.
512, 1024 и 2048 можно делить на 2, пока не получится 1.
Если вы используете текстуру с шириной или высотой, отличными от числа, кратного двум, Three.js
попытается растянуть ее до ближайшего числа, кратного 2, что может привести к плохому визуальному результату, и вы также получите предупреждение в консоли.
Данные
Мы еще не рассмотрели подобные примеры, потому что нам нужно сначала пройти другие вещи, но текстуры поддерживают прозрачность. Как вы, возможно, знаете, файлы jpg не имеют альфа-канала, поэтому вы можете предпочесть использовать png.
Или вы можете использовать альфа-карту, как мы увидим в одном из следующих уроков.
Где найти текстуры
К сожалению, всегда трудно найти идеальные текстуры. Существует множество сайтов, но текстуры не всегда подходят, и, возможно, вам придется заплатить.
Возможно, стоит начать с поиска в Интернете. Вот несколько сайтов, на которых я часто бываю.
Вы также можете создавать свои собственные текстуры, используя фотографии и 2D-программы, такие как Photoshop, или даже процедурные текстуры с помощью программ, таких как Substance Designer.
На этом сегодня все, надеюсь вам это было полезно!
🤖 Чтобы не пропустить новые уроки подпишись на телеграм канал!