Если вы уверены, что понимаете чего ожидать от формата DXT5, то проверьте себя: в спойлере анимация — слева PNG картинка 4x4 пикселя, справа — преобразованная в DDS(DXT5)
Если вас это не удивит — смело проходите дальше.

Да, я точно знаю как происходит конвертация в DXT5.
image

Если вы искали инструмент или возможность на лету увидеть, что будет с вашим PNG изображением после преобразования в DXT5 — милости прошу в статью.

Цель


Общий обзор формата DXT5 и инструмента, который позволяет увидеть результат конвертации на лету.

Статья не рассчитана на профи, она ознакомительная.

Для кого


  • Кто не сталкивался с созданием текстур
  • Рисуете растровые картинки: pixelart/2D
  • Кому стало интересно, что за зверь такой S3TC/DXT
  • Кто не ищет лёгких путей в создании игр
  • Кто пытается создавать игры без известных фреймворков(Unity и т.д.)
  • Используете UNIX систему(т.к. инструмент, который рассмотрим дальше, тестировался только под Ubuntu)

Что такое S3TC / DXT


Если очень кратко — это сжатие изображения для того, чтобы: а) оно использовало меньше (v)RAM; б) быстрее загружалось в (v)RAM.

Тут я позволю себе оставить ссылку на табличку, где есть краткая сводка форматов и зачем/когда их использовать вот.

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

Проблематика


DXT5(я его взял как пример, т.к. его использую в текущем проекте) является форматом сжатия с потерей, поэтому мы жертвуем цветом. Первое — цвета будут не в формате по 8 бит на RGB, т.е. не RGB888, а в формате RGB565. С этим ещё пол беды. Но самая главная проблема(на мой взгляд) — это то, что в рамках одного текселя(texel), который составляет 4 на 4 пикселя, на выходе будет максимум 4 цвета: 2 базовых и 2 дополнительных.

Представим, что вы разработчик (или дизайнер / художник), который до этого не сталкивался с разработкой игр(как пример) и решили создать красивый разноцветный спрайт в стиле pixelart/2D, или просто картинку на фон(опять таки растровую, а не векторную).

Взяли в руки мышь/планшет, нарисовали. Вроде красиво(примем условность, что это красиво).

image

Чтобы преобразовать его в DDS, нужно воспользоваться GIMPом, фотошопом с плагинами или чем-то подобным. Но результат вы увидите только после того, как откроете получившийся файл.

Давайте же посмотрим, что получилось(представим, что видим только правую часть картинки, в случаете открытия DDS файла GIMPом):

image

Девушка определённо погрустнела, цветы завяли, диадема стала верёвочкой. «Мда» скажете вы. Вот если бы я видел, что получится раньше… А вот тут может помочь (условно помочь) инструмент, который я собрал для своих нужд — Pyglet PNG to DDS editor

Зачем


Для редактирования / правки исходного файла, подбор приблизительных цветов, составление приблизительной палитры.

Данный «редактор» на лету преобразует PNG изображение в DDS и сразу видно, что получится при конвертации и вставке спрайта в игру.

Почему


Потому, что я не нашел инструментов, которые позволяют на лету увидеть то, как будет выглядеть твоя картинка/текстура.

И это всё?


На данном этапе да. Много чего можно допилить в такой «редактор», но всему своё время.

Больше хотелось бы узнать у сообщества: как вы решаете такие ситуации, когда нужна проверка того, что будет с текстурой на выходе.

P.S.: редактор относительно нормально работает с картинками до 512*512. Течёт по памяти, но не сильно :) (в коде можно найти этот метод по комментарию "!!!ACHTUNG!!!").

Комментарии (8)


  1. AntonSazonov
    14.12.2019 06:48

    Я так и не понял, какое отношение имеет формат PNG к статье?


    1. Impressio Автор
      14.12.2019 11:34

      PNG являются исходными файлами, которые преобразуются в DDS. Т.к. создавать файлы сразу в DDS возможности не представляется.


      1. GCU
        15.12.2019 23:19

        Формулировка

        Сжатие PNG в DDS в формате DXT5
        на мой взгляд несколько сбивает с толку, потому что палитровый PNG сам по себе 1 байт на пиксель, да ещё и сжат DEFLATE (т.е. он изначально меньше чем DXT5, как его ещё можно «сжать» ?)
        Кроме того из статьи неясно почему таки PNG. Это же Python — можно взять, например, pillow и работать с практически любым форматом. Ну или воспользоваться конвертером типа ImageMagick.
        Статья скорее «Особенности S3TC DXT5», что там на вход PNG и вывод DDS по сути не так важно.


        1. Impressio Автор
          15.12.2019 23:55

          1. pillow не конвертирует в DDS.
          2. Таки на счёт формулировки согласен, лучше заменить слово «сжатие» на «конвертацию», заголовок поправил.
          3. ImageMagick принимает много форматов на вход и на выходе даст тоже DDS. PNG взят за пример. Можно было рассмотреть BMP, но проблемы после преобразования в DXT5 останутся такими же.
          PNG действительно может занимать меньше места на диске, чем DDS. Мой контекст был касательно использования ресурсов памяти оперативной/видеокарты.


  1. GCU
    15.12.2019 17:42

    Не совсем понятно зачем заморачиваться с DXT5 для пиксель арта. Пикселей не так много, такого же сжатия можно добиться палитрой на 256 цветов. Дополнительно палитру можно будет менять для ретро эффектов.


    1. Impressio Автор
      15.12.2019 21:16

      Да, можно, но бывает такое, что надо. Зачем и почему — возможно в будущем напишу статью. И да, если маленькие пиксельные картинки — то лучше оставлять PNG с малой палитрой, но если картинка большая и растровая — то тут без сжатия будет сильно много ресурсов будет использоваться. Данная небольшая картинка была приведена лишь как пример.


      1. JKot
        16.12.2019 00:52

        Так с большими и растровыми картинками и DXT5 лучше справляется. К тому-же можете глянуть на YCoCg-DXT5, если хочется качества.


        1. Impressio Автор
          16.12.2019 01:05

          1. Потому, что не знал о его существовании.
          2. Посмотрю. При беглом ознакомлении не уверен, что текущие инструменты в моём проекте будут его поддерживать(pyglet/Wand). Т.к. насколько я понял надо будет отделять альфа канал от RGB для YCoCg-DXT5
          Я то и на распространённыеDXT1/DXT5 еле нашел инструментарий под python, мало кто таким вообще занимается извращением.