Кодеки текстур
Nighthogg Image Codec (NHI)
Блочный кодек с потерями для сжатия текстур. Похож на ETC2 и ASTC.
Базовое использование
// Кодирование текстуры
var image = new RawImage(width, height, pixelData);
byte[] encoded = NighthoggImageCodec.Encode(image);
// Декодирование
var decoded = NighthoggImageCodec.Decode(encoded);
Параметры качества
var encoded = NighthoggImageCodec.Encode(
image,
colorBits: 6, // точность цветности (0-8)
luminanceBits: 8, // точность яркости (0-8)
alphaBits: 4, // точность альфа (0-8)
alphaMultiplierBits: 2, // точность множителя альфа (0-8)
compressionMethod: CompressionMethod.Deflate
);
Больше бит = лучше качество, но больше размер.
luminanceBits=8, colorBits=6— стандартное качество (высокая чувствительность к яркости)luminanceBits=6, colorBits=4— агрессивное сжатие (меньше размер)
Как это работает
- Разделение на блоки 2×2 — обрабатывает 4 пиксела за раз
- Преобразование в YUV — отдельно яркость и цветность
- Выбор лучшего паттерна — группирует пиксели по похожести
- Квантизация — округляет значения до нужного количества бит
- Сжатие DEFLATE — финальное сжатие результата
Типичное соотношение сжатия: 10:1 – 20:1 в зависимости от параметров.
Логирование
// Установить логгер для кодека
NighthoggImageCodec.Logger = Igdrasil.GetLogger("TextureCodec");
// Теперь кодек будет логировать ошибки (если они случатся)
Оптимизированная версия (NighthoggImageCodecOptimized)
Для больших текстур используйте оптимизированную версию:
// С параллельной обработкой блоков
var encoded = NighthoggImageCodecOptimized.Encode(
image,
colorBits: 6,
luminanceBits: 8,
useParallel: true // параллельная обработка на многоядерных ПК
);
var decoded = NighthoggImageCodecOptimized.Decode(encoded);
Улучшения:
- Параллельная обработка блоков (4× ускорение на 4-ядерном процессоре)
stackallocвместо аллокаций (меньше GC pressure)- Кешированные паттерны (5-10% ускорение)
- Быстрые математические операции (
Math.ClampвместоMathF.Max/Min)
Когда использовать:
- Текстуры > 512×512 — точно используйте оптимизированную версию
- Мобильные устройства — обычная версия достаточна
- Асинхронная загрузка — оптимизированная версия безопаснее для потоков
LoraCrunch Image Codec
Альтернативный кодек для экспериментов:
// Похожий API
var encoded = LoraCrunchImageCodec.Encode(image);
var decoded = LoraCrunchImageCodec.Decode(encoded);
Используйте для сравнения размера/качества с Nighthogg.
Интеграция с загрузкой ресурсов
public class CompressedTextureLoadingTask : GraphicsLoadingTask
{
private readonly string _path;
private Texture _texture;
protected override void OnLoad()
{
try
{
// Загружаем исходное изображение
var original = Image.Load(_path);
// Кодируем в NHI
byte[] encoded = NighthoggImageCodecOptimized.Encode(
original,
useParallel: true
);
// Сохраняем в кеш (опционально)
string cachePath = _path.Replace(".png", ".nhi");
File.WriteAllBytes(cachePath, encoded);
// Декодируем обратно для GPU
var decoded = NighthoggImageCodecOptimized.Decode(encoded);
_texture = CreateTexture(decoded);
Igdrasil.Logger.Info("Loaded compressed: {0} ({1}B)", _path, encoded.Length);
}
catch (Exception ex)
{
Igdrasil.Logger.Error("Failed to load {0}: {1}", _path, ex.Message);
throw;
}
}
protected override void OnUnload()
{
_texture?.Dispose();
}
}
Рекомендации
| Сценарий | Кодек | Параметры |
|---|---|---|
| Фон, ландшафт | Nighthogg | luminanceBits=8, colorBits=4 |
| Нормал-мап | Nighthogg | luminanceBits=6, colorBits=4 |
| UI-иконки | Nighthogg | luminanceBits=8, colorBits=6 |
| Мобиль (качество) | Nighthogg+ | useParallel=false |
| ПК (скорость) | Nighthogg+ | useParallel=true |
| Экспериментирование | LoraCrunch | стандартные |
Версия: 1.0