Как перевернуть текстуру BC6 / BC7?

8

У меня есть некоторый код для загрузки файлов изображений DDS в текстуры OpenGL, и я хотел бы расширить его для поддержки сжатых форматов BC6 и BC7, представленных в D3D11. Поскольку DirectX и OpenGL расходятся во мнениях относительно того, находится ли источник текстуры в верхнем левом или нижнем левом углу, мой загрузчик DDS переворачивает пиксели каждого изображения вдоль оси Y перед передачей пикселей в OpenGL.

Переворачивание сжатых текстур представляет дополнительную складку: в дополнение к переворачиванию каждой строки блоков 4x4 пикселей, вам также необходимо перевернуть пиксели внутри каждого блока. Я нашел здесь код для переворачивания блоков BC1 / BC2 / BC3, и из блок-схем на MSDN было легко адаптировать переворачивающий код BC3 для обработки BC4 и BC5. В Bc6 и BC7 форматы значительно выглядеть устрашающе, хотя. Есть ли похожий трюк с переворотом, чтобы перевернуть эти форматы, или мне придется полностью распаковывать и перепаковывать каждый блок?

ОБНОВЛЕНИЕ: оказывается, что переворот текстуры был необходим только потому, что мои координаты текстуры были неправильно инвертированы во время экспорта. Удаление обоих сальто сделало код более простым и быстрым (спасибо Humus!). Переворачивание блоков BC6 / BC7 может все еще быть интересной проблемой, но это больше не относится к моему первоначальному сценарию.

postgoodism
источник
1
Обратите внимание, что если вы перевернете координаты текстуры вместо текстурных изображений, вы не сможете использовать FBO с теми же сетками / шейдерами.
msell
Это правда. Если оставить текстуры DDS незафиксированными, они также будут отображаться вверх ногами в таких инструментах, как gDEBugger . Хмм.
постгудизм

Ответы:

6

Я подозреваю, что действительно возможно перевернуть блоки BC6-7 с гораздо меньшим количеством работы, чем полное распаковывание и повторное сжатие, но это все еще не пикник и намного сложнее, чем переворачивание блоков BC1-5.

Прежде всего, BC6-7 имеют множество режимов, которые можно выбрать для каждого блока. Режимы имеют совершенно разные бинарные макеты, поэтому вам в значительной степени придется написать разные подпрограммы для каждого режима (всего их ~ 20, IIRC).

Другая сложность заключается в режимах разделения, в которых пиксели в блоке делятся на 2 или 3 подмножества, каждое из которых имеет собственный сегмент линии RGB. Раздел должен быть выбран из предопределенного набора; те для BC6 можно увидеть здесь . Проблема в том, что этот набор разделов не является симметричным при вертикальных переворотах. Тем не менее, я подозреваю , что это симметрично относительно некоторой комбинации вертикальных переворачиваются и перестановка два подмножества. Например, если посмотреть на раздел № 22 (6-я строка, 3-й столбец) по этой ссылке, то в таблице нет его версии с вертикальным переворотом, но если вы перевернете ичередуя 0 и 1, вы получите раздел № 9 (3-й ряд, 2-й столбец). Я не проверял, что каждый раздел можно перевернуть таким образом, и я не проверял те разделы для BC7 (который также включает разделы с 3 подмножествами).

Даже если это работает, вы все еще не свободны дома. В BC1-5 порядок двух конечных точек линейного сегмента RGB использовался для переключения режимов, но в BC6-7 порядок конечных точек выбирается для фиксации одного бита индексов на пиксель в каждом подмножестве разделов. Поэтому, если вы меняете раздел вокруг, вам также может потребоваться поменять местами порядок конечных точек.

И наконец, что не менее важно, в BC6-7 конечные точки часто сжимаются дельтой (т. Е. Одна конечная точка сохраняется с полной точностью, а другие хранятся как дельты с более низкой точностью от нее). Замена подмножеств разделов и порядка конечных точек переключит, какая конечная точка является высокоточной, так что вам придется перетасовывать биты низкой точности и сводить на нет некоторые дельты.

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

(Кстати, самая полная спецификация BC6-7, которую я нашел, - это спецификация ARB_texture_compression_bptc ; я также написал пост в блоге о форматах BCn некоторое время назад.)

Натан Рид
источник
Спасибо; Я достаточно напуган. Я действительно отправился на поиски вашего блога, но не смог вспомнить ссылку. Это отличный ресурс по всем вопросам BCn; это само по себе стоит вознесения!
постгудизм
0

Переворот только по умолчанию на двух форматах. Вы можете пойти против по умолчанию.

Это, вероятно, лучше делать на стороне OpenGL, потому что OpenGL находится на более низком уровне и, следовательно, с меньшей вероятностью теряет оптимизацию при выполнении подобных вещей.

Роберт Вм Рудисуэли
источник