2D графика - зачем использовать спрайт-листы?


62

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

Я начал с 2d рендеринга спрайтов в нескольких демонстрационных приложениях, которые я сделал, имея дело с каждым кадром анимации для каждого данного типа спрайта в качестве своей собственной текстуры - и эта коллекция текстур хранится в словаре. Кажется, это работает для меня и вполне подходит для моего рабочего процесса, так как я обычно делаю свои анимации в виде файлов gif / mng, а затем извлекаю кадры в отдельные png-файлы.

Есть ли заметное преимущество в производительности при рендеринге с одного листа, а не с отдельных текстур? С современным оборудованием, способным выводить миллионы полигонов на экран сто раз в секунду, имеет ли это значение для моих двухмерных игр, которые имеют дело с несколькими десятками прямоугольников размером 50x100 пикселей?

Детали реализации загрузки текстуры в графическую память и ее отображения в XNA кажутся довольно абстрактными. Все, что я знаю, это то, что текстуры привязываются к графическому устройству, когда они загружаются, а затем во время игрового цикла текстуры визуализируются партиями. Так что мне не ясно, влияет ли мой выбор на производительность.

Я подозреваю, что есть некоторые очень веские причины, по которым большинство разработчиков 2D-игр, похоже, используют их, я просто не понимаю, почему.


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

Ответы:


69

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

Также учтите, что размеры текстур обычно имеют степень 2. Поэтому, если у вас Sprite размером 50x100 пикселей, вы будете размещать текстуры размером 64x128 пикселей или в худшем случае 128x128 пикселей. Это просто трата графической памяти. Лучше упакуйте все спрайты в текстуру 1024x1024px, что позволит использовать спрайты 20x10, и вы потеряете только 24 пикселя по горизонтали и вертикали. Иногда даже спрайты разных размеров объединяются в один огромный спрайт-лист, чтобы использовать текстуру максимально эффективно.

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


1
Спасибо, я не учел ни одного из этих пунктов. Вы знаете примерно, каково ограничение на количество доступных текстур? Я никогда не видел, чтобы этот стат упоминался в графических спецификациях - действительно ли лимит равен объему графической памяти?
— Коломбо

Обычно пределом будет память GPU, да. Я думал, что есть некоторые ограничения на количество текстур на старых картах, но я не могу найти ссылку, которая доказывает эту точку зрения.
— bummzack

12
Даже если количество не ограничено, трафик шины для перемещения большого количества маленьких изображений не так эффективен, как одна (или несколько) большая передача (и).
— Мордачай

5
Хорошие моменты, но самый важный аспект - минимизировать задержки конвейера, уменьшая количество вызовов отрисовки. Графические процессоры предпочитают небольшое количество больших рабочих мест, а не большое количество мелких рабочих мест. Помещение всех ваших спрайтов в небольшое количество больших листов означает, что вы можете настроить текстовую стадию один раз и рисовать множество спитов одновременно в пакете. Spritebatch делает это для вас. Если у вас есть несколько спрайтов, убедитесь, что spritebatch сортировал по текстуре
— Cubed2D

Добавление сжатия текстур превратит любое свободное пространство в очень маленькое количество накладных расходов, вдобавок ко всему
— Joe Plante

36

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

Это также может помочь сэкономить место, но в первую очередь это зависит от того, что вы упаковываете в таблицу спрайтов.


2
+1 Прикасается к розыгрышам. (что-то, чего я не увидел в принятом ответе)
— Майкл Коулман,

11

Каждый колл-вызов имеет определенное количество накладных расходов. Используя спрайт-листы, вы можете пакетно рисовать вещи, которые не используют один и тот же кадр анимации (или, в более общем смысле, все, что на одном материале), значительно повышая производительность. Это может не иметь большого значения для современных ПК в зависимости от вашей игры, но это определенно имеет значение, скажем, для iPhone.


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

Я определенно задаюсь вопросом, выигрывают ли текстуры спрайтов от множества текстур в 3D-оборудовании, плюс операции бит-блиттинга.
— Джо Планте

7

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

Кроме того, я кодирую в AS3, и для каждого файла изображения требуется отдельная инструкция по встраиванию. Я предпочел бы иметь одно встраивание всей таблицы спрайтов, а не 24 встраивания для всех фреймов, даже если я использую отдельный класс ресурсов.


1
+1. Хотя OP не использует Flash, встраивание или загрузка также являются преимуществом для спрайт-листов. Это также актуально, когда ресурсы загружаются с веб-сервера, где 1 запрос предпочтительнее, чем несколько сотен запросов (для каждого «фрейма»).
— bummzack

Определенно вы хотите уменьшить количество запросов к серверу для онлайн-игры. Мы рассмотрели вопрос о том, лучше ли помещать изображения в .swf или в таблицу спрайтов, потому что оба они достигают этой главной цели (в итоге мы решили, что таблицы спрайтов менее трудоемки для наших художников).
— Джоккинг

7

Другая причина использования спрайт-листов с XNA заключается в том, что при разработке Xbox360 существует известная проблема, связанная с медленным временем развертывания / загрузки по сравнению с количеством файлов в вашем проекте. Таким образом, объединение множества небольших файлов изображений в один файл изображения поможет решить эту проблему.


5

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

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

Кроме того, более чистым (с организационной точки зрения) было бы использовать файл character.png и врага.png от персонажа от 01 до до персонажа 10, затем от персонажа от 01 до персонажа 05 и так далее.


4

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

Одним из таких простых и быстрых способов управления памятью может быть то же самое, что иметь только один гигантский спрайт 4096x4096, который разрезается на несколько меньших спрайтов путем уменьшения его ширины и / или высоты вдвое. (Существует похожая одномерная техника управления памятью, но я забыл название.) В конце концов, должна быть выполнена дефрагментация.

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


3

Также не забывайте, что операции ввода / вывода могут спасти вас во время инициализации. Если вы загружаете с CD-привода, каждый файл является дополнительным вызовом ввода / вывода, и может потребоваться некоторое время для поиска (современные жесткие диски занимают около 15 мс на файл, CD, может быть, 50-100 мс?). Это может сэкономить вам много времени инициализации, так как нужно выбрать только один файл. Это также позволяет вашей ОС кэшировать эти операции ввода-вывода, если ваше приложение выполняет что-то еще (например, ожидание графического процессора).


1
С другой стороны, если вы хотите решить проблему поиска файлов, все спрайты могут быть упакованы в один файл в произвольном формате. Большинство игр делают это.
— tigrou

0

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

На мой взгляд, проще в написании кода. У меня просто есть массив объектов, таких как:

sheet = {
    img: (the actual image),
    rects: [
        {x:0, y:0, w:32, h:32},
        {x:32, y:0, w:32, h:32},
        {x:64, y:0, w:32, h:32}
    ]
};

sheets.push(sheet);

Затем для каждого элемента я даю ему два значения, лист и прямоугольник. Лист будет индексом в массиве объектов, а прямоугольник будет индексом в массиве rects этого листа.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.