Three.js предоставляет богатые возможности для работы с текстурами,
обеспечивая поддержку различных форматов и методов сжатия, что
критически важно для производительности веб-приложений. Понимание того,
какой формат использовать и как эффективно применять сжатие, позволяет
значительно снизить нагрузку на графический процессор и ускорить
загрузку сцены.
Основные форматы текстур
Three.js поддерживает несколько категорий форматов:
Растровые изображения (Bitmap)
- JPEG – эффективен для фотографий и изображений с
плавными переходами цвета. Отличается высокой степенью сжатия, но теряет
информацию (lossy). Не поддерживает прозрачность.
- PNG – поддерживает прозрачность (альфа-канал),
идеально подходит для спрайтов и UI-элементов. Сжатие без потерь
(lossless), поэтому размер файлов больше, чем у JPEG.
- GIF – поддерживает анимацию и прозрачность, но
ограничен 256 цветами. Практически не используется для 3D-текстур в
Three.js из-за низкого качества.
Высокодинамические изображения (HDR и EXR)
- HDR (.hdr) – используется для освещения через
environment maps. Позволяет хранить значения освещенности вне диапазона
[0,1], что важно для PBR (Physically Based Rendering).
- EXR (.exr) – аналог HDR, поддерживает 16- или
32-битные форматы с плавающей точкой. Используется в сценах с
высокодинамическим освещением и постобработкой.
Форматы сжатия для WebGL WebGL поддерживает
специализированные форматы сжатых текстур, которые загружаются напрямую
в видеопамять, минуя CPU. Three.js предоставляет загрузчики для таких
форматов:
- DDS (S3TC / DXT) – старый формат для
Windows/DirectX, поддерживает блоковое сжатие и Mipmap. Подходит для игр
с большим количеством текстур.
- KTX / KTX2 (Basis Universal) – современный формат,
поддерживающий конвертацию в GPU-native форматы на лету. KTX2 с Basis
Universal значительно уменьшает размер текстур без заметной потери
качества.
- PVR (PVRTC) – эффективен для устройств Apple,
поддерживает сжатие с потерями и быстрый рендеринг на iOS.
Сжатие текстур
Сжатие текстур критически важно для оптимизации производительности.
Различают несколько методов:
Сжатие с потерями (Lossy)
- Уменьшает размер файлов за счёт потери точности цвета.
- Примеры: JPEG, Basis Universal, PVRTC.
- Используется для больших карт диффузного цвета, где небольшие
артефакты малозаметны.
Сжатие без потерь (Lossless)
- Сохраняет исходное качество пикселей.
- Примеры: PNG, EXR.
- Не всегда эффективен для игр из-за больших размеров, но полезен для
карт нормалей и альфа-каналов.
Блоковое сжатие (Block Compression)
- Текстура делится на блоки, каждый из которых сжимается
независимо.
- Примеры: DXT1/5, ETC1/2, ASTC.
- Позволяет GPU декодировать данные без участия CPU, обеспечивая
мгновенную загрузку и рендеринг.
Работа с форматами в
Three.js
Three.js предоставляет удобные загрузчики для всех популярных
форматов:
- THREE.TextureLoader – для PNG, JPEG, GIF. Позволяет
загружать растровые изображения и автоматически создавать Mipmap.
- THREE.RGBELoader – для HDR-текстур, применяемых в
environment maps.
- THREE.EXRLoader – для EXR-файлов с
высокодинамическим диапазоном.
- THREE.KTX2Loader – для KTX2/Basis Universal.
Поддерживает конвертацию текстур в GPU-native формат через Basis
Universal transcoder.
- THREE.DDSLoader / PVRLoader – для
платформенно-специфичных сжатых форматов.
Пример загрузки KTX2-текстуры:
const ktx2Loader = new THREE.KTX2Loader()
.setTranscoderPath('js/libs/basis/')
.detectSupport(renderer);
ktx2Loader.load('textures/texture.ktx2', (texture) => {
texture.encoding = THREE.sRGBEncoding;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
material.map = texture;
material.needsUpdate = true;
});
Mipmap и фильтрация
Использование Mipmap в сжатых текстурах позволяет уменьшить артефакты
при уменьшении размера текстуры на экране. Three.js автоматически
генерирует Mipmap при загрузке большинства форматов, но для сжатых
текстур KTX2 и DDS Mipmap может быть закодирован заранее.
Фильтрация текстур управляется свойствами:
- texture.minFilter – фильтр при уменьшении
(например,
THREE.LinearMipmapLinearFilter).
- texture.magFilter – фильтр при увеличении
(например,
THREE.LinearFilter).
- texture.wrapS / wrapT – режимы повторения или
отражения текстуры (
THREE.RepeatWrapping,
THREE.MirroredRepeatWrapping).
Эффективная комбинация Mipmap и фильтров позволяет получить плавное
отображение текстур с минимальными артефактами и нагрузкой на GPU.
Выбор формата по типу карты
- Diffuse / Albedo – KTX2/Basis или JPEG для быстрого
рендеринга.
- Normal / Bump – PNG или сжатие без потерь для
точности нормалей.
- Specular / Roughness / Metalness – KTX2/Basis,
часто объединяют в каналы одного изображения (packed maps).
- Environment / Skybox – HDR или EXR для корректного
освещения сцены.
Оптимизация загрузки
- Минимизация количества текстур через texture
atlases.
- Использование Basis Universal для уменьшения веса и
кроссплатформенной совместимости.
- Загрузка текстур асинхронно с отображением
placeholder-материалов.
- Генерация Mipmap заранее для сжатых текстур, чтобы избежать затрат
GPU при первом рендеринге.
Эффективное управление форматами и сжатием текстур позволяет Three.js
обеспечивать высокую производительность даже в сложных сценах с большим
количеством материалов и освещения.