Pull to refresh

Comments 29

>Такой способ применялся еще в первых консольных приставках

Несколько раньше. Спрайтовая анимация существует столько же, сколько вся компьютерная графика. Она намного старше, чем OpenGL.

Слово «спрайт» было придумано в 1970-е годы одним сотрудником компании Texas Instruments: их новая микросхема TMS9918 могла аппаратно отображать небольшие картинки поверх неподвижного фона


За статью спасибо. Отличное справочное пособие по быстрому началу «плоского» OpenGL-приложения.
Речь не о спрайтах же. А о текстурных атласах.
Я, видимо, в двух терминах запутался. Я всегда понимал онятие «спрайт» двояко. Во-первых, прямоугольная картинка, выводимая на экран, а во-вторых — картинка, текстура которой вырезается из карты. Видимо, надо лучше матчасть учить…
Спрайт это совокупность положения, текстуры, анимации и т.п.
Железо — это металл. А металл — это железо?
sptire-sheet — это частный случай текстурного атласа.
Так что назвать sprite-sheet текстурным атласом — вполне корректно. А вот обратное — не всегда корректно.
Большое спасибо. Очень интересно почитать про OpenGL. Некоторое время назад занимался его изучением (остановился на таком — камера, текстуры, вывод текста, освещение без теней), но в настоящее время подзабил. Пожалуйста, пишите еще!
Такой способ применялся еще в первых консольных приставках


А как решать такие проблемы:
1. Просадка кадров. Когда текстура — это 150 кадров, рассчитана на анимацию 2 секунды по 75 кадров, а получается только например 50 кадров? Пропускать кадры просто?

2. Когда кадров в текстуре 30 и рассчитана на секунду, а фпс получается 75?
Я у себя в движке решаю так: знаю что анимация занимает 2,5 сек. При каждом рендере кадра обновляю анимацию — вычисляю кадр так:
текущий кадр = (прошло времени после старта / общая время анимации) * количество кадров
потеряются кадры только, если будет просадка по производительности

Основная идея — не привязываемся к FPS, смотрим только на время
Плюс для остальных вещей, типа обработки перемещений объектов и т. п., можно использовать deltaTime.
Спасибо. В целом, я так и думал, но так как я только начал вникать в эту тему, то я мало в чем уверен.
Вообще, хотелось бы почитать про the best practice.
>>2. Когда кадров в текстуре 30 и рассчитана на секунду, а фпс получается 75?

Я у себя, например, интеполирую кадры анимации, получая более плавную картинку.
Интерполируете как? fade? Дает ощущение мыла… ИМХО — лучше просто четкое переключение. Тем более если FPS у нас хотя бы 30, мгновенная смена кадра даст вполне нормальный результат.
Нет, двунаправленно по motion flow векторам.
Извините, что так долго, вылетело из головы.
Собрал демку с разверткой из этой статьи:
http://quad-engine.com/public/motionflow.zip

Именно так я и делаю интерполяцию. Мышкой можно поводить по окну для регулировки скорости.
Из предыдущего коммента поглядите как даже на высоком фпс видно разницу в плавности анимации, на малой скорости или даже средней разница невероятная.
А что значит интерполировать? В данной ситуации разве это не то же самое, что и
текущий кадр = (прошло времени после старта / общая время анимации) * количество кадров
?

Если нет, то можете посоветовать где почитать что-нибудь?
Нет, не тоже самое. попробуйте замедлить скорость смены кадров до 5-10 в секунду и все будет дерганым. Да и даже на 25 все не сказать чтобы жутко плавно было. Речь о том, чтобы именно не было этой дерганности.
Это не простая штука — на сколько я понял, нужно определить вектор движения каждого пикселя. Исходя из этого, когда грубо говоря знаем от куда и куда перемещается пиксель — определяем где он должен быть между кадрами.
В этой статье написано как это делается.

>>Пропускать кадры просто?
А что Вас удивляет? Разумеется пропускать, нельзя показать все 150.

Вы еще учтите, что такое количество кадров жрет нехило памяти, и это очень жирно, даже сейчас с гигабайтами.
Здесь нет смысла объединять текстурки с кадрами в одну, лучше тупо сделать 36 маленьких текстур и при рендере ставить нужную.
Вы от этого способа только проигрываете:
1)Немного меньше скорость чтения из такой текструры, чем из кадра отдельно
2)Проблемы с фитрацией на краях кадров
3)Из количества кадров должен извлекаться корень, что бы не было пустых мест на текстуре
4)Количества кадров ограничено максимальным размером текстуры
5)Такую текстуру тяжелее стримить без пролагов чем отдельные небольшие кадры(т.е. плавно прогружать уже по ходу игры)

А если очень хочется всё в кучу свалить, то специально для таких вещей есть Array Texture
https://www.opengl.org/wiki/Array_Texture
Если нужно нужно использовать текстуры размером например 100х200 (не буду ручаться за все видеокарты), некоторые видеокарты выделят память 256х256. и так для каждого кадра.
Так же прирост в производительности если плавно переключатся между кадрами(интерполировать два кадра), использовать несколько анимаций в одной текстуре, или если рендерятся несколько объектов где одна и та же анимация не синхронная — в таких случаях не надо каждый раз переключатся между текстурами.
>>лучше тупо сделать 36 маленьких текстур
И чем же лучше? У вас на экране, скажем 100 таких анимаций одновременно, но все в разных стадиях, на разных кадрах. В вашем случаем мы получаем 100 смен стейтов, 100 Draw Call. Ужас, кошмар и тормоза.
Если текстура не кратная степени двойки, то в вашем случае будет довольно немалый оверхед по памяти лишней съеденной.

>>1)Немного меньше скорость чтения из такой текструры, чем из кадра отдельно
Наложение текстуры по UV всей текстуры или кусочка не отличается по скорости никак.

>> 2)Проблемы с фитрацией на краях кадров
Какие у вас проблемы, покажите пример?

>> 3)Из количества кадров должен извлекаться корень, что бы не было пустых мест на текстуре
Это вообще я не понял что за минус такой.

>> 4)Количества кадров ограничено максимальным размером текстуры
Вам кто-то запрещает бить анимации на несколько подобных атласов, или не хватает 4096х4096 текстур?

>> 5)Такую текстуру тяжелее стримить без пролагов чем отдельные небольшие кадры(т.е. плавно прогружать уже по ходу игры)
Такую текстуру можно грузить по мипмапам, и анимация будет уже целиком в памяти в худшем качестве, пока ваши 36 картинок будут еще грузиться.
1.
>Наложение текстуры по UV всей текстуры или кусочка не отличается по скорости никак.

Немного но отличается. При чтении данных из текстуры берётся блок из нескольких пикселей и помещается в кэш. Потом чтение соседних пикселей происходит из этого кэша. При рисовании небольшого спрайта из большой текстуры, в кэш попадают блоки содержащие пиксели за границей спрайта. Следовательно нужно больше блоков копировать в кэш, чем если просто рисовать маленькую текстуру. Я давно тестировал потери от этого на видюхе ati radion HD 4850. В эксперименте я составил каллаж из маленьких спрайтов рандомного размера в диапазоне 20-400 пикселей, общий размер текстуры 4096х4096. Затем я рандомно рисовал спрайты отдельными текстурами и аналогично, вырезая из большой. Потери в скорости при этом были около 20%

2.
>Какие у вас проблемы, покажите пример?

Пример:
В анимации есть яркие(белые спрайты) и тёмные(чёрные). Они находятся рядом. Тогда при включённой линейной интерполяции у белых будет образовываться чёрная рамка, у чёрных наоборот белая. При мипмапинге, сжатии текстур и анизотропной фильтрации заползания будут только увеличиваться.

3.
>> 3)Из количества кадров должен извлекаться корень, что бы не было пустых мест на текстуре
Это вообще я не понял что за минус такой.

Если увас будет 16 кадров, то они хорошо лягут в спрайт щит. Они будут в виде таблицы 4x4. Если спрайтов 11, то в последних 2 строчках будут пустые места.
16 кадров__11 кадров
+ + + +_____+ + + +
+ + + +_____+ + + +
+ + + +_____+ + + 0
+ + + +_____0 0 0 0

4.
>> 4)Количества кадров ограничено максимальным размером текстуры
Вам кто-то запрещает бить анимации на несколько подобных атласов, или не хватает 4096х4096 текстур?

Мне никто не запрещает, 4096х4096 мне не хватает. А вам?

5.
>> 5)Такую текстуру тяжелее стримить без пролагов чем отдельные небольшие кадры(т.е. плавно прогружать уже по ходу игры)
Такую текстуру можно грузить по мипмапам, и анимация будет уже целиком в памяти в худшем качестве, пока ваши 36 картинок будут еще грузиться.

Мипмапы с такими штуками не очень хорошо работают, поскольку соседние кадры залезают в один мипмап(см пункт 2). И это всё равно будет хуже. У вас просто будет мыло. А отдельные кадры можно подгружать уже по ходу воспроизведения анимации и тут также можно использовать мипмапы.

>>Потери в скорости при этом были около 20%
Довольно голословно. Демку бы.

>> будет образовываться чёрная рамка, у чёрных наоборот белая
Анимации на атласе имеют обыкновение по краям быть прозрачными, либо не менять свой цвет от кадра к кадру так сильно. Надумано довольно.

>>Если спрайтов 11, то в последних 2 строчках будут пустые места
Бывает такое, но это не очень критично, если честно.

>> 4096х4096 мне не хватает. А вам?
А мне хватает 2048х2048

>>А отдельные кадры можно подгружать уже по ходу воспроизведения анимации
А если не успеете? Всё будет крешиться? Или не рисоваться?
Мне такой подход кажется неприемлемым. Пользователь не должен видеть подгрузку ни в каком виде.
Анимации на атласе имеют обыкновение по краям быть прозрачными, либо не менять свой цвет от кадра к кадру так сильно. Надумано довольно.

Так и любой нормальный упаковщик текстур умеет добавлять заданный зазор между изображениями, специально для того, чтобы такая проблема не проявлялась.
Sign up to leave a comment.

Articles