Оптимизация 2Д графики

» опубликован
Доброго времени суток. В этот раз хочу рассказать про одну интересную оптимизацию своей игры, которую я реализовал недавно. Сама идея оптимизации очевидна и возникла еще в начале разработки игры, но реализовать ее было сложновато и лень. Вернее сказать идей даже две.
И так, проблема в том, что каждый спрайт, который рисуется на экране, как бы прямоугольник с наложенной на него текстурой, но большинство объектов в моей игре не прямоугольны. Приведу пример
Значительная часть данной текстуры прозрачна, но прозрачные тексели тоже рендеряться видеокартой отнимая время. Логично было бы для этой текстуры создать двумерную низко полигональную модель, которая бы отсекала прозрачные области, это бы заметно снизило нагрузку.
Но строить для каждой текстуры такую модель довольно затратно, а создание алгоритма, который автоматически строит модели задача нетривиальная и я сильно сомневался что у меня получится ее решить.
Теперь изложу вторую часть идеи. Большинство спрайтов частично перекрывают друг друга в моей игре, горы, здания и т.п. на заднем плане частично закрываются объектами, находящиеся ближе к экрану. Чтобы правильно отображались все объекты, раньше все объекты сортировались по расстоянию до камеры и рисовались сначала задние спрайты, потом те что ближе и в отсортированном порядке. В результате тратится немало времени на отрисовку тех областей. которые все равно потом будут перекрыты близкими объектами. Обычно данная проблема решается использованием буфера глубины (кто не знает, вот ссылка из википедии - ru.wikipedia.org/wiki/Z-буферизация), но как оказалось в данном случае он не дает почти ни какого прироста, потому что маскирование пустых текселей на спрайте сильно снижает производительность.
И так, суть оптимизации в том, чтобы на модели текстуры отделить непрозрачную область текстуры от прозрачной (другими словами сделать отдельно модель для непрозрачной области текстуры и для полупрозрачной) и разделить процесс построения кадра на два этапа:
на первом этапе рисуются непрозрачные спрайты в порядке отдаления от камеры, на втором этапе рисуются полупрозрачные спрайты в обратном порядке. При этом буфер глубины тоже используется, но на этот раз он дает заметный прирост скорости.
Как я уже отмечал, создавать полигональные модели для каждой текстуры слишком затратно, но видя как мой телефон тормозит на уровне с кучей облаков решил что надо что-то делать. Я написал утилиту, которая автоматически строит модели для каждого спрайта. Я сомневался что утилита получится, но результат получился таким, на какой я надеялся. Вот несколько примеров моделей, которые построила утилита
На построение модели для картинки с разрешением 512 на 512 пикселей уходит около одной секунды на процессоре AMD A10-5700. Алгоритм построения моделей очень прост, вкратце он сводится к следующему. Сначала создается модель в виде квадратной решетки с узлами в каждом пикселе, а потом она упрощается.
П.С. Если вам интересно, то я могу в отдельном посте подробно описать как работает алгоритм.
Результат такой оптимизации превзошел все мои ожидания. При тестах на планшете ASUS T100 TI на одной из карт прирост FPS составил 75-85%, конечно это зависит от количества перекрываемых объектов и других факторов. Но на телефоне Sony Xperia Ion результат не очень меня порадовал - 12-19% на той же карте. Видимо от кривых драйверов, которые регулярно доставляли мне геморрой при отладке.
Сейчас я занимаюсь переосмыслением левел дизайна, делаю новые декорации для космической станции на смену старым. Вот некоторые из них (две стены и нечто вроде трубы). Примерно через неделю выложу еще скриншотов того, что у меня получилось.


Просмотров: 241

» Лучшие комментарии


PhysCraft #1 - 2 месяца назад 1
То есть, ты заменил рисунки на плоские 3d-модели и получилось, что лучше рендерить модель, которая занимает меньше места, чем весь рисунок с прозрачной частью? А по поводу отрисовки в два этапа, то ты на первом просто находишь, какую часть всего в целом нужно замаскировать, а уже на втором производишь прорисовку, как надо, с использованием буфера глубины. Ну да, тогда нужно меньше времени, так как часть текселей маскируется другими объектами при прорисовке сама по себе. Или я не правильно понял метод? Кстати, утилита справилась довольно неплохо.
DENj #2 - 2 месяца назад 0
PhysCraft, в целом так, но на первом этапе не только буфер глубины строится но и сразу рисуются непрозрачные спрайты, на втором этапе буфер глубины уже не заполняется и рисуются полупрозрачные спрайты. В целом всегда так и делается в играх - в два этапа минимум, но без моделей в 2Д игре реализовывать такое бессмысленно.
GaRiX91 #3 - 2 месяца назад 1
отлично выглядит
BrEd Pitt #4 - 2 месяца назад 1
даешь пост об алгоритме!
DENj #5 - 2 месяца назад 5
Кто хочет статью про алгоритм ставьте + этому комментарию.