Как стать автором
Обновить

Cocos2D вода на основе SPH

Время на прочтение2 мин
Количество просмотров8K


Если необходимо реализовать воду, которая работает, как контроллер уровня, и тела попав на неё, всплывают, то SPH (Smoothed Particle Hydrodynamics) нам не поможет. Реализация подобного типа воды хорошо, например, описана здесь.
Стояла задача реализовать воду именно на основе гидродинамики сглаженных частиц.
Реализацию можно разбить на две, в общем-то, абсолютно не связанные подзадачи:
  • Физика (Model)
  • Графика (View)

Физический мир


Для реализации был выбран физический движок Box2D.
На самом деле тут всё очень просто: необходимо создать много одинаковых маленьких частиц, которые обладают следующими параметрами:
  1. Частицы гладкие, т. е. Friction=0;
  2. Частицы круглые;
  3. Частицы друг с другом взаимодействуют.

Количество подсчетов скорости и позиции (velocityIterations & positionIterations) можно задать 3 и 1 соответственно. Этого вполне достаточно, для обеспечения нормальной работы.
Результат можно посмотреть на краткой видео демонстрации.

Как видно в физическом мире всё прекрасно «живёт» так, как нужно.

Графика


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

Первый и как, мне сначала показалось самый разумный – выделить группы объектов, и обвести полученные в результате не выпуклые (concave) полигоны, используя триангуляцию.
На этот замечательный способ я потратил несколько дней, и в результате ничего хорошего не получил, дальше продолжать не было никакого смысла.

Другой способ: рисовать частицы воды кружочками большего диаметра, чем физические объекты. Это очень простой способ, но для того, чтобы вода была похожа на воду, необходимо сделать ее прозрачной, и применить ряд других спецэффектов.
Для начала был испробован способ наложения маски на рисуемый слой с использований возможностей openGL ES 1.0 по следующему методу.

В результате использования пяти CCRenderTexture была получена неплохая в общем-то вода с эффектом motion blur и искажением просвечивающего через воду изображения.


Оптимизация


К великому огорчению всё это ужасно тормозило на iPad1, хорошо работая на iPad2 и iPhone 4S.
Конечно считать такой результат удовлетворительным было нельзя.
Была проделана огромная работа по оптимизации кода, однако это почти ничего не изменило.
После изысканий на тему кто работает быстрее Chimpmunk или Box2D было выяснено, что действительно Chimpmunk работает быстрее.
Тем не менее результат всё равно продолжал тормозить. Можно было использовать до 100 частиц, на iPad1 чего в общем-то маловато.
Был сделан вывод, что графическая реализация тормозит, тогда как физическая часть работает вполне удовлетворительно.

Cocos2d 2.0 Brunch, шейдеры


Очевидным решением проблемы являются шейдеры и использование OGL ES 2.0.
Хорошо что существует Cocos2d 2.0 Brunch c OGL ES 2.0. Перенос на который из Cocos2d оказался абсолютно безболезненным, и простым.
Использование маскирующего и искажающего шейдера позволило сделать воду с 300 частицами на iPad 1 и FPS 30.
Видео результата в начале топика.
Теги:
Хабы:
Всего голосов 22: ↑16 и ↓6+10
Комментарии14

Публикации

Истории

Работа

Swift разработчик
14 вакансий
iOS разработчик
9 вакансий

Ближайшие события

11 – 13 февраля
Epic Telegram Conference
Онлайн
27 марта
Deckhouse Conf 2025
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань