размеры текстуры должны быть степенями двойки как исправить
Текстура в OpenGL(не степень двойки)
Как текстуру со сторонами некратными степени двойки, наложить на объект.
Если в качестве параметров Height и Width функции glTexImage2D пишу, к примеру, 375 и 500 текстура не накладывается.
И правда ли то, что для двумерной текстуры размеры массива образа должны быть степенью этой самой двойки?
Используй GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle и т.п.
[правка] при копи-пейсте потерялся суперскрипт для обозначения степени
Nvidia-это хорошо(у меня их аксель), но будут ли эти расширения работать на картах ATI?
Есть ли еще способы?
Заранее спасибо.
>Nvidia-это хорошо(у меня их аксель), но будут ли эти расширения работать на картах ATI?
Diman3d
arb_texture_rectangle, nv_texture_rectangle, ext_texture_rectangle суть синонимы. если одно из них есть на карте, работать будет.
там, если не ошибаюсь, прикол в том, что константы GL_TEXTURE_RECTANGLE_NV и GL_TEXTURE_RECTANGLE_EXT просто напросто одинаковы.
>КАМПАНЕНТ ДЛЯ СИДЬМОЙ ДЕЛЬФИ
Бывает и такое. Хотя я думаю, что чувак таким образом пытается прикалываться.
А где взять эти расширения, если я програмирую на Delphi?
А если скопировать твое изображение в картинку со сторонами кратными степени двойки (например 512×512) и использовать соответствующие текстурные координаты. Или изменить размеры картинки в Photoshope до размеров, кратных степени двойки? Работать будет всегда и везде 🙂
Можно конечно, но тогда приходится менять саму картинку.
Но я пишу загрузчик 3D-моделей и этот вариант, к сожалению не подходит. Я должен грузить ту текстуру, которая прилагается к файлу, а они не всегда с «правильными» сторонами.
>Я должен грузить ту текстуру, которая прилагается к файлу
Я не моделлер, но насколько мне известно, игровые модели обычно делаются именно с текстурами, отвечающими условиям кратности степени двойки.
текстуры в игре не кратные степени 2. как?
собственно во всех манах по DX8, DX9 сказано множество раз что текстура по ширине и высоте должна быть кратна степени двойки иначе разные драйвера по разному ее будут приводить к этому соотношению.
собственно я и придерживаюсь сего правила. из-за этого приходится держать утилиту, упаковывающую множество текстур в текстурные атласы с описателями что и где лежит.
НО. ковырныл намедни архив с игрой luxor-3, вытащил все игровые ресы из нее. и о чудо. все текстуры не кратны степени 2.
анимация, коей сотни кадров представлена как отдельный файл для каждого кадра. КАК они сделали это? то что они собирают текстуры в атласы на лету я не верю.
юзают они DX7. может в семерке нет такого требования к размерам?
В luxor-3 сделано вообще тупо: спрайт кладётся в бОльшую текстуру размером ближайшей степени двойки.
Т.е. для картинки размером 80х80 создастся текстура 128х128, и она в неё положится. Атласов нет.
Хотя генерировать текстурные карты на лету вполне можно. Аллокатор, наверное, будет не очень оптимальный, но ж лучше, чем никакого.
BUzer
>В luxor-3 сделано вообще тупо: спрайт кладётся в бОльшую текстуру размером
>ближайшей степени двойки.
сомнительно. ибо памяти он жрет меньше чем могло бы быть при таком подходе.
NPOT с некоторыми ограничениями (conditional NPOT в DX) поддерживается с очень старых карт (ati7500).
То, как они хранятся в видеокарте, не должно волновать, главное смотреть на Pitch при заливке через Lock текстуры.
NULL_PTR
>NPOT с некоторыми ограничениями (conditional NPOT в DX) поддерживается с очень
>старых карт (ati7500).
>То, как они хранятся в видеокарте, не должно волновать, главное смотреть на
>Pitch при заливке через Lock текстуры.
дык, однако я так понимаю что это приведет к определенным тормозам в графике.
>>однако я так понимаю что это приведет к определенным тормозам в графике.
На старых может и приведёт, на новых нет.
>>дык
дык, наверно так там и сделано.
хм, а в чем проблема создания атласа на лету?
my.name
>хм, а в чем проблема создания атласа на лету?
в целесообразности.
ни один алгоритм не упакует так же хорошо, как человек ручками.
progman
и выйграет пару % свободного пространства, уж лучше автоматом паковать и не задумываться потом об этом, в итоге сэкономишь кучу времени.
еще как вариант, сжимать/расжимать (кому как «нравится») при загрузке текстуры до ближайшего кратного двойке.
Aroch
>progman
>и выйграет пару % свободного пространства, уж лучше автоматом паковать и не
>задумываться потом об этом, в итоге сэкономишь кучу времени.
>еще как вариант, сжимать/расжимать (кому как «нравится») при загрузке текстуры
>до ближайшего кратного двойке.
ну во первых не пара %, тулза от NVidia очень плохо разношерстные текстуры пакует. у меня выигрыш от ручной упаковки до 100% доходит.
во вторых разные дрова по разному растягивают ATI, если память не изменяет увеличивает размер текстуры до кратных 2, но картинку не масштабирует. NVidia картинку масштабирует или наоборот. но факт в том что по разному себя ведут они с некратными текстурами.
>>но факт в том что по разному себя ведут они с некратными текстурами.
Рисуют одинаково, и славно. А то, знаешь ли, шейдеры они тоже компилят в совершенно разные команды!
NULL_PTR
>>>но факт в том что по разному себя ведут они с некратными текстурами.
>Рисуют одинаково, и славно. А то, знаешь ли, шейдеры они тоже компилят в
>совершенно разные команды!
дык, в том то и дело что рисуются не одинаково, косяков слишком много ловится на этом 🙁
>>дык, в том то и дело что рисуются не одинаково, косяков слишком много ловится на этом 🙁
Всё рисуется одинаково. Если руки кривые, это другое дело.
NULL_PTR
>>>дык, в том то и дело что рисуются не одинаково, косяков слишком много ловится
>>>на этом 🙁
>Всё рисуется одинаково. Если руки кривые, это другое дело.
хех. имеем текстуру 513х513, один драйвер ее скайлит до 1024х1024 вместе с картинкой и в итоге она отрендерится нормально.
другой ее не скайлит, а просто увеличивает площадь, и в итоге при рендеринге мы видим 511 пикселей черноты. слева и снизу.
и где тут одинаковость?
текстурные координаты в обоих случаях 1.0, 1.0
Почему, когда размер текстуры не является степенью двойки, она отображается размытой?
Почему когда размер текстуры не является степенью двойки, она отображается размытой? Можно ли это победить? Вот текстура:
Размеры текстуры 640x480px, рисую с таким же размером.
2 ответа 2
Почему когда размер текстуры не является степенью двойки, она отображается размытой?
Дело в том, что вы используете растровое изображение. При растяжении или сжатии такого изображения, в отличие от векторного, оно будет размываться, поскольку информации в нём ровно столько, сколько можно закодировать в пикселях. Когда размер отображаемой области совпадает с размером текстуры, к ней не применяется никаких преобразований, соответственно картинка отображается «как есть». Однако, такая ситуация в 3D-моделировании встречается крайне редко, если не сказать никогда. И натянуть текстуру на полигоны — ещё полбеды. Практически всегда к картинке будут применяться преобразования.
В приведённом примере имеет смысл заменить линейный фильтр GL_LINEAR_MIPMAP_NEAREST хотя бы на бикубический и использовать текстуру с достаточно большим разрешением, если у вас задача получить красивую картинку на экране. Если же задача стоит именно в отображении конкретной картинки без преобразования, то придётся подгонять каждую текстуру под поверхность.
Почему текстуры всегда имеют квадратную степень двойки? Что если они не?
Почему разрешение текстур в играх всегда равно двум (128х128, 256х256, 512х512, 1024х1024 и т. Д.)? Разве не было бы разумно сэкономить на размере файла игры и сделать текстуру точно подходящей для развернутой модели UV?
Что случилось бы, если бы была текстура, которая не была степенью двойки?
Было бы неправильно иметь текстуру размером 256х512 или 512х1024? Или это может вызвать проблемы, которые могут возникнуть из-за не-степени двух текстур?
Почему разрешение текстур в играх всегда равно двум (128х128, 256х256, 512х512, 1024х1024 и т. Д.)?
Как следует из байта 56, ограничения размера «степень двух» заключаются (были) в том, что каждое измерение должно быть независимо степенью двойки, а не то, что текстуры должны быть квадратными и иметь размеры, равные степени двойки.
Однако на современных картах и в современных графических API-интерфейсах это «ограничение» было значительно ослаблено, так что размеры текстур могут быть, в пределах разумного, практически чем угодно. Тем не мение:
Разве не было бы разумно сэкономить на размере файла игры и сделать текстуру точно подходящей для развернутой модели UV? Что случилось бы, если бы была текстура, которая не была степенью двойки?
Гарантируя, что размеры текстуры являются степенью двойки, графический конвейер может воспользоваться преимуществами оптимизации, связанной с эффективностью работы с степенями двойки. Например, это может быть (и совершенно точно было несколько лет назад, когда у нас были выделенные графические процессоры и чрезвычайно умные оптимизирующие компиляторы) быстрее делиться и умножаться на степени двух. Работа в степенях двух также упрощает операции в конвейере, такие как вычисление и использование mip-карт (число, равное степени двух, всегда делится равномерно пополам, что означает, что вам не нужно иметь дело со сценариями, в которых вы должны округлять ваши размеры mipmap вверх или вниз).
Это правда, что вы «тратите» некоторое пространство таким образом, но дополнительное место обычно стоит компромисса в производительности рендеринга. Кроме того, существуют методы, такие как сжатие или упаковка нескольких изображений в одно текстурное пространство, которые могут уменьшить часть отходов хранения.
Почему текстуры всегда имеют квадратную степень двойки?
Проблема в том, что некоторые аппаратные средства имеют ограниченную поддержку текстур, которые не имеют мощности двух измерений.
3 На уровнях характеристик 9_1, 9_2 и 9_3 устройство отображения поддерживает использование двумерных текстур с размерами, не равными степеням двух, при двух условиях. Во-первых, для каждой текстуры может быть создан только один уровень MIP-карты, и, во-вторых, запрещены режимы сэмплера обтекания для текстур (то есть члены AddressU, AddressV и AddressW D3D11_SAMPLER_DESC не могут быть установлены в D3D11_TEXTURE_ADDRESS_WRAP).
4 На уровнях характеристик 10_0, 10_1 и 11_0 устройство отображения безоговорочно поддерживает использование двумерных текстур с размерами, не равными степеням двойки.
Графическое оборудование оптимизировано для матричных операций, операций с фрагментами и векторных операций. Проще говоря, с квадратными матрицами легче работать, так как вычисления могут выполняться в блоках (называемых фрагментами), аппаратное обеспечение оптимизировано для операций с блоками, поэтому существуют такие вещи, как файловые буферы, блит оперативной памяти не копирует на диск до блока был заселен. То же самое относится и к графической памяти.
Буфер кадра состоит из фрагментов, которые являются квадратными. Например, на экране с разрешением 800×600 и цветовым пространством RGB (0-255) имеется 800×600 точек с 3 байтами на каждый канал, а общее количество адресов 3x800x600 = 1440 000 байт для адресации в буфере кадров. Это означает, что имеется 1875 адресуемых фрагментов размером 256x256x3 байта. Поскольку данные текстуры являются квадратными, это значительно упрощает отображение из матрицы GRAM в матрицу экранного буфера с использованием бикубического масштабирования, где, как если бы это не было квадратным смещением для более длинной стороны, потребовалось бы больше времени для вычисления, когда это необходимо для быть масштабированным.
Многие графические API принимают данные текстуры, не имеющие квадратной формы, потому что они принимают координаты UV-отображения в качестве данных с плавающей запятой, однако, как только они отправляются в GPU, к данным текстуры добавляется заполнение, потому что фактические пропорции изображения не изменяют отображение кажется незатронутым, однако к данным текстуры добавляется заполнение, потому что графический процессор любит обращаться к нему как к идеальному квадрату.
Таким образом, если используется изображение 100×1024 и используется изображение 1024×1024, что означает, что 946,176 байт будут потрачены впустую. Тем более, если нужно выполнить компоновку, потому что необходимо добавить альфа-канал, чтобы указать, что данные заполнения не должны влиять на составную текстуру.
Формат текстур
Размеры
Поскольку рендер каждого кадра в игре производится аппаратно, нужно использовать все доступные возможности для ускорения этого процесса. Видеопамять организована таким образом, что быстрее всего происходит доступ к данным, расположенным по быстро вычислимым адресам. Такие адреса получаются операцией сдвига и соответствуют степеням двойки (2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048. ). Исходя их этого, оптимально расположатся в памяти текстуры с размером стороны, равным степени двойки. При этом текстура не обязательно должна быть квадратной. Возможно использование и текстур других размеров, но при этом, если текстура не объединяется с другими при загрузке в игре, будет нерационально расходоваться видеопамять за счет дополнения текстуры до размеров степени 2 (и в этом случае память будет расходоваться бесконтрольно!).
Нужно привести текстуру в любое возможное соответствие с размерами сторон 2n. В крайнем случае, можно немного пожертвовать пропорциями текстуры и учесть это при наложении на модель (например, 256×280 лучше превратить в 256×256, чем доращивать до 256×512). Или же оставить по краям небольшие пустые места (если текстура «не дотягивает» до нужных размеров) – возможно, они даже понадобятся в дальнейшем.
Небольшое исключение можно сделать для текстур, сжимаемых в формат DXT# (см. следующий пункт) – для этих текстур важно, чтобы размер сторон был кратен 4 (соответствует размеру кванта сжатия). Но все равно рекомендуется использовать только размеры степени 2.
Важно: текстуры с размером стороны, равным 1, нежелательно создавать, поскольку возникнут проблемы с фильтрацией при рендере. Минимальный размер стороны текстуры равен 2. Максимальный размер всей текстуры, для большей совместимости с различными видеокартами, не рекомендуется делать больше 2048х2048 (такой размер тоже нужно использовать только в крайнем случае).
Сжатие
Если вы выберете формат, который не поддерживается напрямую игрой, скорее всего такая текстура загрузится, но будет выдано предупреждение о неверном формате цвета (например при использовании R8G8B8).