Думаю, это последний пост про партикл-системы. Я нашел несколько интересных штук в движке и хотел бы ими с вами поделиться. В посте 3 основных вопроса:
1. Как улучшить, сделать красивее свою систему.
2. Что такое BatchedSpriteParticleSystem и стоит ли ее использовать.
3. Какие бывают эмиттеры.
Бонусом выкладываю вам для всеобщего использования файлик с частицами, которые я использую. Он не мой - он из движка HGE. Первая картинка - просто для удобства - она Jpeg. Качайте вторую себе - она PNG. Я везде пока использую третью слева в третьей строчке.
Ну во-первых оказалось, что системе частиц можно добавлять несколько однотипных модификаторов, если в этих модификаторах есть время начала и конца модификации. Проще пояснить на примере.
Вот мы видим 2 одинаковых модификатора. Первый параметр - время начала действия, второй - окончания. То есть второй модификатор начинает действовать в тот же момент, в который первый модификатор заканчивает свое действие.
Вот полный список модификаторов для партикл-системы двигателя корабля.
ТО есть в стартовой точке системы появилось яркое белое ядро. Цвет сначала меняется от белого до желтого, а затем уже от желтого до красного.
Однако стоит помнить - чем больше модификаторов, тем больше будет проседать ФПС. Не стоит злоупотреблять модификаторами :)
Дальше я бы хотел рассказать о своем исследовании BatchedSpriteParticleSystem
Нашел я эту штуку в движке и сразу подумал, что она сделана для улучшения производительности. Ведь SpriteBatch вроде бы для этого и служит (хотя я его еще подробно не исследовал). При исследовании выяснилось следующее. Во-первых, такая партикл-система совсем по-другому обрабатывает наложение спрайтов. Вот вам картинка для примера. (огонь не мой, а вот кораблик сверху мой - в плавильную систему частиц добавлено много частиц для наглядности).
Как видите, результат абсолютно разный. Я бы не сказал, что он хуже. В некоторых ситуациях может и понадобится батч-система. И это только во-первых.
Во-вторых, на практике никакого прибавления в производительности замечено не было. И ДАЖЕ, по-моему, производительность слегка просела. Хотя я не проводил тщательный тест производительности, а пользовался лишь парочкой относительных результатов. Если кто-то пойдет по моим стопам и захочет исследовать этот вопрос более тщательно - буду очень благодарен за информацию.
Ну и в конце я расскажу о найденным мною эмиттерах.
ИМХО, не очень удобно использовать конструкцию вроде этой:
1. PointParticleEmitter создает все частицы в одной точке.
2. CircleParticleEmitter. Ему задается радиус по Х и по У, то есть он может быть эллиптическим. Частицы создаются по всей площади эллипса.
3. СircleOutlineParticleEmitter. Частицы создаются только на периметре эллипса. Думаю, такой эмиттер подойдет для всяких там гало и телепортов.
4. RectangleParticleEmitter. Частицы создаются по всей прямоугольной площади.
5. RectangleOutlineParticleEmitter. Частицы создаются по периметру прямоугольной формы.
Для наглядности вот скриншоты простого и круглых эмиттеров:
Вот, собственно, и все на сегодня.
Я пока не решил - что исследовать в следующий раз. Скорее всего попытаюсь разобраться в текстурном менеджере. А потом займусь парсингом.
1. Как улучшить, сделать красивее свою систему.
2. Что такое BatchedSpriteParticleSystem и стоит ли ее использовать.
3. Какие бывают эмиттеры.
Бонусом выкладываю вам для всеобщего использования файлик с частицами, которые я использую. Он не мой - он из движка HGE. Первая картинка - просто для удобства - она Jpeg. Качайте вторую себе - она PNG. Я везде пока использую третью слева в третьей строчке.
Ну во-первых оказалось, что системе частиц можно добавлять несколько однотипных модификаторов, если в этих модификаторах есть время начала и конца модификации. Проще пояснить на примере.
mPS.addParticleModifier(new ColorParticleModifierОпять прошу прощения за последнюю строчку - это глюк блога.(0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0.7f, 1.0f, 0.0f)); mPS.addParticleModifier(new ColorParticleModifier (0.1f, 0.4f, 1.0f, 1.0f, 0.7f, 0.0f, 0.0f, 0.0f));
Вот мы видим 2 одинаковых модификатора. Первый параметр - время начала действия, второй - окончания. То есть второй модификатор начинает действовать в тот же момент, в который первый модификатор заканчивает свое действие.
Вот полный список модификаторов для партикл-системы двигателя корабля.
mPS.addParticleInitializer(new VelocityParticleInitializerА вот так выглядит обновленная партикл-система по сравнению со старым вариантом:(-20.0f, 20.0f, -10.0f, 300.0f)); mPS.addParticleInitializer(new ExpireParticleInitializer (0.3f, 0.8f)); mPS.addParticleInitializer(new BlendFunctionParticleInitializer (GLES20.GL_SRC_ALPHA,GLES20.GL_ONE)); mPS.addParticleModifier(new ColorParticleModifier (0.0f, 0.1f, 1.0f, 1.0f, 1.0f, 0.7f, 1.0f, 0.0f)); mPS.addParticleModifier(new ColorParticleModifier (0.1f, 0.4f, 1.0f, 1.0f, 0.7f, 0.0f, 0.0f, 0.0f)); mPS.addParticleModifier(new OffCameraExpireParticleModifier (this.sapCamera)); mPS.addParticleModifier(new ScaleParticleModifier (0.0f, 0.1f, 0.3f, 1.0f, 0.5f, 1.0f)); mPS.addParticleModifier(new ScaleParticleModifier (0.1f, 0.4f, 1.0f, 0.1f, 1.0f, 1.0f)); mPS.addParticleModifier(new AlphaParticleModifier (0.3f, 0.8f, 1.0f, 0.0f));
ТО есть в стартовой точке системы появилось яркое белое ядро. Цвет сначала меняется от белого до желтого, а затем уже от желтого до красного.
Однако стоит помнить - чем больше модификаторов, тем больше будет проседать ФПС. Не стоит злоупотреблять модификаторами :)
Дальше я бы хотел рассказать о своем исследовании BatchedSpriteParticleSystem
Нашел я эту штуку в движке и сразу подумал, что она сделана для улучшения производительности. Ведь SpriteBatch вроде бы для этого и служит (хотя я его еще подробно не исследовал). При исследовании выяснилось следующее. Во-первых, такая партикл-система совсем по-другому обрабатывает наложение спрайтов. Вот вам картинка для примера. (огонь не мой, а вот кораблик сверху мой - в плавильную систему частиц добавлено много частиц для наглядности).
Как видите, результат абсолютно разный. Я бы не сказал, что он хуже. В некоторых ситуациях может и понадобится батч-система. И это только во-первых.
Во-вторых, на практике никакого прибавления в производительности замечено не было. И ДАЖЕ, по-моему, производительность слегка просела. Хотя я не проводил тщательный тест производительности, а пользовался лишь парочкой относительных результатов. Если кто-то пойдет по моим стопам и захочет исследовать этот вопрос более тщательно - буду очень благодарен за информацию.
Ну и в конце я расскажу о найденным мною эмиттерах.
ИМХО, не очень удобно использовать конструкцию вроде этой:
class Hero extends BasicObject implements IParticleEmitter{ // ...some code... // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== public void getPositionOffset(float[] pOffset) { pOffset[VERTEX_INDEX_X] = this.getX() + HERO_ENGINE_PARTICLES_OFFSET_X; pOffset[VERTEX_INDEX_Y] = this.getY() + HERO_ENGINE_PARTICLES_OFFSET_Y; } // ...some code... }Гораздо проще оказалось добавить некий уже готовый эмиттер, как поле, а не делать самого героя эмиттером. Вот примерно как это выглядит:
class Hero extends BasicObject { // ...some code... private PointParticleEmitter mPointParticleEmitter; // ...some code... Hero(/*...constructor parameters...*/){ // ...some code.. mPointParticleEmitter = new PointParticleEmitter (HERO_ENGINE_PARTICLES_OFFSET_X, HERO_ENGINE_PARTICLES_OFFSET_Y); } // ...some code...Ну а дальше я пошел исследовать различные эмиттеры. По-сути, готовых к использованию оказалось 5 штук.
1. PointParticleEmitter создает все частицы в одной точке.
2. CircleParticleEmitter. Ему задается радиус по Х и по У, то есть он может быть эллиптическим. Частицы создаются по всей площади эллипса.
3. СircleOutlineParticleEmitter. Частицы создаются только на периметре эллипса. Думаю, такой эмиттер подойдет для всяких там гало и телепортов.
4. RectangleParticleEmitter. Частицы создаются по всей прямоугольной площади.
5. RectangleOutlineParticleEmitter. Частицы создаются по периметру прямоугольной формы.
Для наглядности вот скриншоты простого и круглых эмиттеров:
Вот, собственно, и все на сегодня.
Я пока не решил - что исследовать в следующий раз. Скорее всего попытаюсь разобраться в текстурном менеджере. А потом займусь парсингом.
Ваши статьи супер ! Осваиваю движок и опираюсь на ваши статьи ! Продолжайте в том же духе !
ОтветитьУдалитьСпасибо. Приятно, блин :)
УдалитьНо появилось мнение, что БЛОГ не соответствует своему названию. Прочитайте первое сообщение и, возможно, оставьте комментарий :)
А как избежать проседания FPS при добавлении Particle? Может как-то можно предзагрузить?
ОтветитьУдалитьЕсли честно, то хз. Пока не занимался этим вопросом.
УдалитьОдин вариант решения предполагался такой - мониторить производительность и в зависимости от нее играться с количеством частиц прямо в коде. То есть на медленных девайсах будет автоматически выбираться минимум частиц. Чем сильнее девайс, тем больше частиц.
Другой вариант мне напомнил один друг в скайпе. Вообще отказаться от частиц. Нарендерить спрайты взрывов в МАКСе или где там. И просто ставить AnimatedSprite со взрывом в нужном месте. Хотя такой подход требует тестирования. Потому как такие спрайты будут занимать много графического места. Предполагаю, что на 4-5 взрывов понадобится текстура 1024*1024 и это, опять же, просадит ФПС.
И еще. Желательно минимизировать количество инициализаторов и модификаторов для каждой системы частиц. Можно делать мнеьше частиц, но каждую больше размером. А вообще крайне трудно поймать оптимальное соотношение между красотой и производительностью.
УдалитьДень добрый. Буквально сегодня начал прочитывать ваш блог. До этого читал книгу по AndEngine на английском и , признаюсь, мозги сильно уставали. Хочу сказать вам большое спасибо за ваш труд. Со своими начальными знаниями в разработке игр, пока не столкнулся ни с какими проблема. Единственное , пока не знаю как сделать Background из повторяющихся текстур, был бы вам очень благодарен,если бы вы поделились.
ОтветитьУдалитьСпасибо за внимание
Коли створюєш TextureAtlas потрібно використати як параметр TextureOptions.REPEATING_BILINEAR_PREMULTIPLYALPHA. Для прикладу :
ОтветитьУдалитьmyTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.REPEATING_BILINEAR_PREMULTIPLYALPHA);