Как решить большие требования к видеопамяти в 2D-игре?
Мы разрабатываем 2D-игру (Factorio) на языке Allegro C / C ++, и мы сталкиваемся с проблемой увеличения требований к видеопамяти по мере увеличения игрового контента.
В настоящее время мы собираем всю информацию об изображениях, которые будут использоваться первыми, обрезаем все эти изображения в максимально возможной степени и организуем их в большие атласы настолько плотно, насколько это возможно. Эти атласы хранятся в видеопамяти, размер которой зависит от системных ограничений; в настоящее время обычно это 2 изображения размером до 8192x8192, поэтому им требуется от 256 до 512 МБ видеопамяти.
Эта система работает очень хорошо для нас, поскольку с некоторыми пользовательскими оптимизациями и разделением потока рендеринга и обновления мы можем рисовать десятки тысяч изображений на экране со скоростью 60 кадров в секунду; у нас на экране много объектов, и разрешение большого уменьшения является критическим требованием. Поскольку мы хотели бы добавить больше, возникнут некоторые проблемы с требованиями к видеопамяти, поэтому эта система не может удержаться.
Одна из вещей, которую мы хотели попробовать, - иметь один атлас с наиболее распространенными изображениями, а второй - в качестве кэша. Изображения будут перемещены туда из растрового изображения памяти, по требованию. У этого подхода есть две проблемы:
- Рисование из растрового изображения памяти в растровое видео очень болезненно, в аллегро.
- В allegro невозможно работать с растровым изображением, отличным от основного потока, поэтому его практически невозможно использовать.
Вот некоторые дополнительные требования, которые у нас есть:
- Игра должна быть детерминированной, поэтому проблемы с производительностью и временем загрузки никогда не могут изменить игровое состояние.
- Игра в реальном времени и скоро станет многопользовательской. Нам нужно избегать даже самого маленького заикания любой ценой.
- Большая часть игры представляет собой один непрерывный открытый мир.
Тест состоял из рисования 10 000 спрайтов в партии для размеров от 1x1 до 300x300, несколько раз для каждой конфигурации. Я делал тесты на Nvidia Geforce GTX 760.
- От растрового изображения к графическому растровому изображению потребовалось 0,1 мкс на спрайт, когда исходное растровое изображение не менялось между отдельными растровыми изображениями (вариант атласа); размер не имел значения
- Растровое изображение видео к растровому изображению видео, в то время как исходное растровое изображение переключалось между чертежами (не атласный вариант), занимало 0,56 мкс на спрайт; размер тоже не имел значения.
- Память растрового изображения на видео растрового рисунка была действительно подозрительной. Размеры от 1x1 до 200x200 занимали 0.3us за растровое изображение, поэтому не так уж и медленно. Для больших размеров время начало увеличиваться очень резко, с 9us для 201x201 до 3116us для 291x291.
Использование атласа увеличивает производительность более чем в 5 раз. Если у меня было 10 мс для рендеринга, с атласом я ограничен 100 000 спрайтов на кадр, а без него - 20 000 спрайтов. Это было бы проблематично.
Я также пытался найти способ проверить сжатие растрового изображения и растровый формат 1bpp для теней, но я не смог найти способ сделать это в allegro.