Android atc dxt etc1 etc2

Android: Формат сжатых текстур

Привет. Хотел узнать у вас по поводу «железных» текстур.

Сделал поддежку 3х форматов

  • S3DS (DXT 1 — 5) Это для чипов NVIDIA Tegra
  • PVR — для PowerVR’s
  • ATITC — для Adreno

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

    Выбор по расширирениям

    И еще вопрос, как быть с Mali ?
    Из расширений которые они поддерживают
    Все какие то не ведомые

    GL_OES_texture_compression_astc
    GL_KHR_texture_compression_astc_hdr
    GL_KHR_texture_compression_astc_ldr
    GL_OES_compressed_ETC1_RGB8_texture — не пойдет, по причине отсуцтвия альфа канала. Вариант с двумя текстурами, тоже вариант, но пока не до него!

    Раздел Android Texture Formats: https://docs.unrealengine.com/latest/INT/Platforms/Android/Refere… extureformats
    Я делал билды с ETC2, и нормально работало на малишных девайсах.

    wmask
    > Раздел Android Texture Formats:
    > https://docs.unrealengine.com/latest/INT/Platforms/Android/Refere…
    > extureformats
    > Я делал билды с ETC2, и нормально работало на малишных девайсах.
    Супер, спасибо.

    А как узнать поддерживает ли устройсво ETC2 ?
    Чет сколько смотрю, у всех GL_OES_compressed_ETC1_RGB8_texture, а чтобы ETC2 ни у кого не ведать

    К примеру вот последний Mali

    Или поддежка Open GL ES 3.0 автоматически гарантирует 100% что будет работать ETC2 ?

    Просто к примеру проц который используется в iPhone 5s хоть и поддерживает ES 3.0 но ETC2 точно нет!

    FDsagizi
    > А как узнать поддерживает ли устройсво ETC2 ?
    Не знаю. Я просто в википедии смотрел: если у девайса гпу мали, то делал билд под ETC2.

    FDsagizi
    > GL_OES_texture_compression_astc
    > GL_KHR_texture_compression_astc_hdr
    > GL_KHR_texture_compression_astc_ldr
    Это вообще самый крутой формат. Поддерживает всё, можно регулировать степень сжатия. Можно даже сжать так, что плотность данных будет меньше бита на пиксель. Вроде этот формат планируют вводить в следующие версии OpenGL и OpenGL ES.

    FDsagizi
    > Или поддежка Open GL ES 3.0 автоматически гарантирует 100% что будет работать ETC2 ?
    Не факт, что аппаратной поддержки достаточно. Надо, чтобы ещё версия Android была от 4.3.

    FDsagizi
    > Просто к примеру проц который используется в iPhone 5s хоть и поддерживает ES
    > 3.0 но ETC2 точно нет!
    А вообще айфоны поддерживают OpenGL ES 3.0? Если проц поддерживает, то не факт, что драйвер есть. Они вроде как свой API Metal продвигать хотели, а на OpenGL ES выше 2.0 забить. Но я не очень за ним слежу, могу и ошибаться.
    В общем, если устройство заявляет поддержку OpenGL ES 3.0, но не поддерживает ETC2, то оно врёт и OpenGL ES 3.0 не поддерживает, потому что ETC2 часть стандарта.

    FDsagizi
    > Все наборы текстур будут идти в комплекте с игрой, и в зависимости от типа
    > поддерживаемого расширения будут загружаться нужные
    Почему бы не собирать разные APKшки с разными форматами текстур под разные GPU, чтобы пользователи качали только нужные им текстуры? Если ты уже используешь Gradle (а не устаревший ADT), это делается элементарно.

    FDsagizi
    > И еще вопрос, как быть с Mali ?
    Грузить tga.
    > Все ли верно?
    Да. Я так-же делаю. Но ты врядли встретишь расширение GL_ATI_texture_compression_atitc. GL_AMD_compressed_ATC_texture достаточно
    wmask
    > Я делал билды с ETC2, и нормально работало на малишных девайсах.
    >если у девайса гпу мали, то делал билд под ETC2.
    ETC2 не держат Mali ниже T6x т.е. те что не держат OpenGL ES 3.x. Например очень распространенные Mali 400/Mali 450. На каких девайсах это могло работать? может для старых все таки были tga/png ?

    Andrey
    > ETC2 не держат Mali ниже T6x т.е. те что не держат OpenGL ES 3.x. Например
    > очень распространенные Mali 400/Mali 450.
    Странно все это. Вот тут Mali 400 упоминается, а по ссылке в моем первом посте написано, что для мали нужно ставить ETC2. В общем, это уже сами разбирайтесь, я глубоко не копался, даю ссылки на вики UE4. Можно, кстати, посмотреть там исходный код, как они определяют, что использовать.

    Сам я, естественно, не тестил на старых девайсах, но эпики пишут: Expected — Device has passed Functional testing

    Читайте также:  Pixaloop pro для андроид

    Так — по скольку у нас OpenGL ES 3.0 обязателен, и Areno 330 мин видео карта.

    Получается что ATI TC не нужен, т.к. Adreno 330 прекрасно работает с ETC2

    Adreno 330 и Mali — ETC2
    Nvidia — DXT1
    Pover WR — PVR

    кстати а как дела с графикой от Intel ? Которая на андроиде идет? На компе то — она спокойно работаетc S3TC(DXT1)

    Кстати посмотреть поддежку текстур, лучше смотреть через — OpenGL Extension Viewer

    FDsagizi
    >и Areno 330 мин видео карта.
    точнее 305 минимум
    >Nvidia — DXT1
    >Pover WR — PVR
    А разве они в случае OpenGL ES 3.0 не держат ETC2 ? если так то для OpenGL ES 3.0 вообще выбрать ETC2, а лучше GL_OES_texture_compression_astc

    Andrey
    > > vidia — DXT1
    > > over WR — PVR
    > А разве они в случае OpenGL ES 3.0 не держат ETC2 ? если так то для OpenGL ES 3.0 вообще выбрать ETC2

    Нету таких устройств, надо смотреть — у нас в городе(Астана) либо блотные, либо дешевые, а на тегре — для геймеров уже несыщешь. На каком форме можно задать вопрос, чтобы узнать такую инфу ?

    Andrey
    > а лучше GL_OES_texture_compression_astc

    Хорошо посмотрю! А не подкинете ссылку, где можно глянуть сравнение и как сжать — либу. А то гугл меня немного в ступор вводит))

    FDsagizi
    > Нету таких устройств, надо смотреть — у нас в городе(Астана) либо блотные, либо
    > дешевые, а на тегре — для геймеров уже несыщешь. На каком форме можно задать
    > вопрос, чтобы узнать такую инфу ?
    То есть ты не веришь, что ETC2 есть везде, где есть OpenGL ES 3.0 и хочешь это проверить?

    FDsagizi
    > Хорошо посмотрю! А не подкинете ссылку, где можно глянуть сравнение и как
    > сжать — либу. А то гугл меня немного в ступор вводит))
    Если не ошибаюсь, есть тулза от Mali, которая сжимает в ASTC и ETC1\2. Только для её скачивания надо вроде бы зарегистрироваться на их сайте.

    Зачем удалил моё сообщение? Каким таким правилам оно не соответствует?

    Источник

    Сжатие мобильной графики в формат ETC1 и открытая утилита

    При развитии free-to-play мобильной игры вместе с новыми фичами регулярно добавляется и новая графика. Часть ее включается в дистрибутив, часть скачивается в ходе игры. Для возможности запуска приложения на устройствах с небольшим размером оперативной памяти разработчики применяют аппаратно сжатые текстуры.

    Формат ETC1 обязателен к поддержке на всех Android-устройствах с OpenGL ES 2.0 и является хорошей отправной точкой оптимизации потребляемой оперативной памяти. По сравнению с форматами PNG, JPEG, WebP загрузка текстур ETC1 осуществляется без интенсивных расчетов обычным копированием памяти. Также улучшается производительность игры по причине меньших размеров данных текстур пересылаемых из медленной памяти в быструю.

    На любом устройстве с OpenGL ES 3.0 возможно использование текстур в формате ETC1, являющимся подмножеством улучшенного формата ETC2.

    Использование сжатых текстур в формате ETC1

    Формат ETC1 содержит только компоненты цвета RGB, поэтому он подходит для непрозрачных фонов, которые рекомендуется рисовать с отключенным Alpha-blending.

    Что делать с прозрачной графикой? Для нее задействуем две текстуры ETC1 (далее — 2xETC1):

    — в первой текстуре храним исходный RGB;
    — во второй текстуре храним исходную альфу (далее — A), скопировав ее в компоненты RGB.

    Тогда в пиксельном шейдере 2xETC1 восстановим цвета таким образом:

    Особенности подготовки атласов перед сжатием в формат ETC1

    Формат ETC1 использует независимые блоки 4×4 пикселя, поэтому положение помещаемых в атлас элементов желательно выравнивать на 4 пикселя, чтобы исключить попадание разных элементов в общий блок.

    Все элементы при помещении в атлас слегка увеличиваются по площади, потому что нуждаются в дополнительной защитной рамочке толщиной 1-2 пикселя. Это связано с дробными координатами отрисовки (при плавном движении спрайтов) и с билинейной фильтрацией текстур. Математическое обоснование причин происходящего заслуживает отдельной статьи.

    В случае полигональных атласов элементы разводятся на приемлемое расстояние. Все блоки ETC1 при размере 4×4 состоят из пары полосок 2×4 или 4×2, поэтому даже расстояние в 2 пикселя может иметь хороший изолирующий эффект.

    Чем можно качественно сжать в формат ETC1?

    Имеется выбор среди бесплатных утилит:

    Для качественного сжатия графики приходится задавать perceptual метрику, учитывающую особенности восприятия, а также выбирать медленные режимы best и slow. Один раз попробовав качественно сжать текстуру 2048×2048 понимаешь, что это долгий процесс… Возможно поэтому многие разработчики ограничиваются быстрыми альтернативами medium и fast. Можно ли сделать лучше?

    Читайте также:  Efficient android threading pdf

    История создания с нуля собственной утилиты EtcCompress одним из программистов Playrix берет начало в январе 2014 года, когда финальное сжатие графики в формат ETC1 превысило по длительности трехчасовой поход в гости.

    Идеи качественного сжатия в формат ETC1

    Формат ETC1 является форматом с независимыми блоками. Поэтому мы используем классический подход сжатия отдельных блоков, который хорошо распараллеливается. Конечно, можно пытаться улучшить стыковку блоков, рассматривая наборы блоков, но в таком случае потребуется информация о принадлежности элементам атласа и резко возрастает вычислительная сложность задачи.

    Для сравнения результатов сжатия подходит утилита dssim.

    Для каждого блока придется перебрать все 4 возможные режима кодирования, чтобы найти наилучший, в коде функция CompressBlockColor:

    — две полоски 2×4, каждая имеющая свой базовый 4-битный цвет, в коде вызовы CompressBlockColor44(…, 0);
    — две полоски 4×2, каждая имеющая свой базовый 4-битный цвет, в коде вызовы CompressBlockColor44(…, 1);
    — две полоски 2×4, первая имеющая базовый 5-битный цвет, вторая отличающаяся базовым цветом от первой в диапазоне 3-бит, в коде вызовы CompressBlockColor53 (…, 2);
    — две полоски 4×2, первая имеющая базовый 5-битный цвет, вторая отличающаяся базовым цветом от первой в диапазоне 3-бит, в коде вызовы CompressBlockColor53 (…, 3).

    2×4, 444+444 4×2, 444+444 2×4, 555+333 4×2, 555+333

    Кстати об ошибке, во многих утилитах используется классический PSNR. Мы тоже используем эту метрику. Выберем весовые коэффициенты из таблицы.

    Перейдем к целочисленным значениям, умножив коэффициенты на 1000 и округлив. Тогда начальная ошибка блока 4×4 составит kUnknownError = (255^2) * 1000 * 16 + 1 , где 255 — максимальная ошибка цветовой компоненты, 1000 – фиксированная сумма весов, 16 — количество пикселей. Такая ошибка укладывается в int32_t . Можно заметить, что целочисленное квадрирование близко по смыслу учету гаммы 2.2.

    У PSNR есть слабые места. Например, кодирование заливки цветом c0 выбором из палитры c1 = c0 — d и c2 = c0 + d вносит одинаковую ошибку d^2 . Это означает случайный выбор между c1 и c2 влекущий всевозможные шашки.

    Для улучшения результата финальный расчет в блоке выполним по SSIM. В коде это делается в функции ComputeTableColor с использованием макросов SSIM_INIT, SSIM_UPDATE, SSIM_CLOSE, SSIM_OTHER, SSIM_FINAL. Идея в том, что для всех решений с наилучшим PSNR (в найденном режиме кодирования) выбирается решение с наибольшим SSIM.

    Для каждого режима кодирования блока придется перебрать все возможные комбинации базовых цветов. В случае независимых базовых цветов функция CompressBlockColor44 выполняет независимое сжатие полосок двумя вызовами функции GuessColor4.

    Функция GuessColor4 выполняет перебор отклонений и компонент базового цвета:

    В случае зависимых базовых цветов возрастает алгоритмическая сложность из-за двойной вложенности циклов полосок. Функция CompressBlockColor53 выполняет перебор отклонений.

    Функция AdjustColors53 выполняет перебор компонент двух базовых цветов:

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

    В случае графики 2xETC1 полностью прозрачные пиксели в общем случае могут иметь произвольный цвет RGB, который будет умножен на нулевую альфу.

    Незначащие пиксели мы можем не учитывать, поэтому отфильтруем их в самом начале, в коде это вызовы FilterPixelsColor. С другой стороны, не всякий прозрачный пиксель является незначащим, вспомним хотя бы защитную рамочку в 1-2 пикселя и эффект отбеливания границ.

    Поэтому сделаем трафарет, в котором ноль будет означать незначащий пиксель, а положительная величина покажет значимый пиксель. Трафарет создается на основе канала A применением обводки, чаще размера 1 или 2 пикселя, в коде это функция OutlineAlpha.

    Как показала практика, при использовании трафарета улучшаются сжатые границы объектов, а невидимые блоки быстро принимают хорошо пакуемый zip черный цвет. Именно идея трафарета дает заметный выигрыш по качеству в сравнении с раздельным сжатием RGB и A, в том числе перечисленными утилитами.

    Таким образом, сжатие 2xETC1 можно представить следующими шагами, реализованными в функции EtcMainWithArgs:

    1) сжимаем канал A в формат ETC1;
    2) распаковываем сжатый канал A обратно;
    3) делаем обводку видимого, где A > 0, получая трафарет;
    4) сжимаем каналы RGB в формат ETC1 с учетом трафарета.

    Идеи ускорения качественного сжатия в формат ETC1

    Чтобы утилита нашла свое применение, помимо качества результата важно и время работы. Рассматриваемый переборный алгоритм сжатия блока достоин быстрой начальной эвристической оценки и полезных отсечений в ходе работы, в том числе на основе жадных алгоритмов.

    Читайте также:  Android нет sim меню

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

    В данном случае упаковщик пытается прочитать выходной файл, распаковать его и рассчитать имеющуюся ошибку, это будет начальным решением. Если же файла нет, то берется начальное решение из нулей. В коде это LoadEtc1, CompressBlockColor, MeasureHalfColor.

    Последующие шаги должны пытаться улучшить имеющееся решение алгоритмами по возрастанию сложности. Поэтому сначала вызываются быстрые CompressBlockColor44, лишь затем медленные CompressBlockColor53. Такая цепочечная конструкция в перспективе позволит интегрировать сжатие в формат ETC2.

    Перед началом перебора вложенными циклами есть смысл найти решение в разрезе цветовых компонент. Дело в том, что наилучшее решение не может иметь ошибку меньше, чем суммарная ошибка наилучших решений для каждой из компонент G, R, B. Часто результирующая ошибка будет существенно больше, что характеризует нелинейность и сложность алгоритма ETC1.

    Решения в разрезе цветовых компонент представлены структурами GuessStateColor и AdjustStateColor. Для каждого значения из таблицы отклонений g_table рассчитываются ошибки полосок Half и сохраняются в поля node0, node1, node2. Причем в GuessStateColor в индексах [0x00..0x0F] хранятся рассчитанные ошибки для всех возможных базовых цветов g_colors4, а в индексе [0x10] наилучшее решение. Для AdjustStateColor наилучшее решение хранится в индексе [0x20], все возможные базовые цвета берутся из g_colors5.

    Расчет ошибки по компонентам цвета осуществляется функциями ComputeLevel, GuessLevels, AdjustLevels на основе таблиц g_errors4, g_errors5, предварительно рассчитанных функцией InitLevelErrors.

    Перебор цветовых компонент есть смысл сделать в порядке возрастания вносимой ими ошибки, для этого осуществляется сортировка полей node0, node1, node2 функциями SortNodes10 и SortNodes20.

    Для ускорения самой сортировки применяются сортирующие сети, рассчитанные на тематическом сайте.

    Перед выполнением сортировки есть смысл отбросить большие ошибки, превышающие найденное решение. При этом заметно уменьшается количество элементов в полях node0, node1, node2, что существенно ускоряет сортировку и дальнейший перебор.

    Третий вложенный цикл по цветовым компонентам G, R, B можно попытаться отсечь, найдя наилучшее решение для текущих G, R функцией ComputeErrorGR, которая в 2 раза быстрее функции ComputeErrorGRB. Это, кстати, горячие места в профилировщике.

    В режиме зависимых базовых цветов хорошее ускорение дает поиск наилучшего решения по каждой половинке, потому что найденная ошибка часто превышает оптимистичный прогноз по цветовым компонентам и одновременно является критерием отсечения.

    Этим занимаются функции Walk и Bottom.

    64 вызова функции AdjustColors53 могут привести к повторным вызовам функций ComputeErrorGR и ComputeErrorGRB с одинаковыми параметрами базового цвета, поэтому будем кэшировать результаты вызовов. В свою очередь, для быстрой инициализации кэша можно использовать ленивые вычисления по третьему цветовому компоненту.

    В структуре AdjustStateColor поля ErrorsG, ErrorsGR и поле ErrorsGRB очищаемое LazyGR дают существенный прирост производительности.

    После различных алгоритмических улучшений пришло время использовать SIMD, в данном случае опубликовано решение на целочисленном SSE4.1. Данные одного пикселя храним как int32x4_t.

    Команды _mm_adds_epu8 и _mm_subs_epu8 удобны для расчета четырехцветной палитры из базового цвета и отклонений.

    В функциях ComputeErrorGRB и ComputeErrorGR сначала применяются частично развернутые циклы, оптимизированные командой _mm_madd_epi16, так как в большинстве случаев достаточно ее разрядности. В случае же больших погрешностей работает второй цикл на «медленных» командах _mm_mullo_epi32.

    Функция ComputeLevel рассчитывает ошибку сразу для четырех значений базового цвета.

    Для сжатия одного канала A можно упростить полученный код сжатия RGB. Будет заметно меньше вложенных циклов и повысится производительность.

    Достигнутые результаты

    Изложенные подходы позволяют уменьшить требования к оперативной памяти в Android-версиях игр за счет использования сжатых текстур в аппаратном формате ETC1.

    В скриптах формирования атласов и самой утилите сжатия уделяется внимание вопросам предотвращения артефактов и повышения качества сжатой графики.

    На удивление, вместе с повышением качества сжатой графики удалось ускорить само сжатие! В нашем проекте Gardenscapes сжатие атласов в формат ETC1 на процессоре Intel Core i7 6700 занимает 24 секунды. Это быстрее генерации самих атласов и в несколько раз быстрее предыдущей утилиты сжатия в режиме fast. Предложенное инкрементальное сжатие происходит за 19 секунд.

    В заключение приведу пример сжатия текстуры 8192×8192 RGB представленной утилитой EtcCompress под Win64 на процессоре Intel Core i7 6700:

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

    Источник

  • Оцените статью