Вступление
На момент написания статьи последней существующей версией была версия 2.17.
Одной из самых главных особенностей программы Magic Particles (Dev) является наличие API. API позволит вам воспроизвести созданные спецэффекты из собственных программ точно так же, как это делает редактор Magic Particles. Однако, следует помнить, что для расчетов спецэффектов требуется процессорное время, поэтому важнейшим моментом при создании спецэффектов для игр является скорость их работы. Т.е. если вы сделаете красивейший спецэффект из нескольких тысяч частиц, то вероятнее всего, ваша игра при рисовании этого эффекта будет серьезно замедляться. Здесь можно привести аналогию с 3D-моделями, которые активно используются в играх. Человек, создающий 3D-модели для игры должен понимать, что если его модель содержит очень много полигонов, то ее использование в игре не приведет ни к чему хорошему – видеокарта пока просто не рассчитана на то, чтобы рисовать полноценные 3D-модели на лету. Поэтому, для игровых моделей требуется некоторая оптимизация, связанная в первую очередь с минимизацией в ней количества полигонов. Такие модели называются низкополигональными и они уже вполне могут быть обработаны видеокартой в режиме реального времени. Думаю, что аналогия понятна – спецэффекты для игр тоже нужно оптимизировать. В данной статье я постараюсь пояснить ключевые моменты в вопросе оптимизации спецэффектов, созданных при помощи Magic Particles.
1. Текстуры
a) Размер текстур
На самом деле API не занимается непосредственно визуализацией – это задача пользователя, но тем не менее, я решил начать именно с этого важнейшего момента: Не используйте больших текстур, если можно обойтись без этого.
Т.е. сделав высококачественную текстуру 512x512 и накладывая ее на частички размером 8x8, вы практически убиваете свой спецэффект для применения в игре. Не надейтесь на какой-то там супер-навороченный графический движок, который нарисует всё, что бы вы ему не подсунули – чудес тут не бывает, и рисовать будет всё та же самая видеокарта, у которой есть свои чёткие технические характеристики. Иными словами, выбрасывайте качество, которое невозможно будет рассмотреть на экране даже через лупу. Когда я проводил эксперименты с размером текстур, то обнаружил, что на моей скромной видеокарте GeForce 6600 GT при уменьшении текстуры с 512x512 до 256x256 наблюдалось возрастание FPS ориентировочно раза в 3.
Чтобы помочь пользователю оценить необходимый размер текстуры для конкретного спецэффекта, в Magic Particles на сцене появилось поле Эффективность текстур. Это поле определяет, насколько размер текстур соответствует размерам частиц. Вычисляется делением площади всех частиц на площадь всех накладываемых текстур. Идеальное значение 1. Если число меньше 1, то площадь текстур превышает площадь частиц. В этом случае текстуры можно уменьшить визуально прямо в программе, используя Хранилище. Практически, если число равно 0.1, то это значит, что текстуры можно уменьшить примерно в 10 раз. Если число больше единицы, то это означает, что текстуры меньше, чем частицы и, возможно, что их стоит увеличить. Эффективность текстур определяется 4-я числами. Первое число показывает эффективность текстур для текущего кадра, второе число показывает среднюю эффективность текстур, т.е. суммарную для всех кадров от нулевого до текущего. Следующие 2 числа показывают минимум и максимум, в котором изменялась средняя эффективность текстур.
Имейте в виду, что обычно спецэффект тормозит не из-за расчетов, а из-за визуализации. Иными словами, API вам всё рассчитает, а когда вы начнете это рисовать, то можете обнаружить, что видеокарта просто «не тянет».
b) Текстуры с размерами кратными степени 2 необязательны
Не секрет, что видеокарта приспособлена к работе только с размерами текстур, которые кратны степени 2, т.е. ширина и высота текстуры в идеале должны быть 4, 8, 16, 32, 64, 128, 256, 512 пикселя. Однако API позволяет создавать на лету текстурный атлас, который вполне может состоять и из текстур нестандартных размеров. Поэтому требование к стандартному размеру текстур не является обязательным. Т.е., если вам нужна текстура 50x34, то нет необходимости искусственно увеличивать ее до размеров 64x64. Новая версия программы научилась делать текстурный атлас прямо из редактора.
c) Автоматическая оптимизация текстур
В начальных версиях Magic Particles текстура хранилась и использовалась в том виде, в котором её загрузил пользователь. В настоящий момент Magic Particles при загрузке
текстуры определяет её "полезную" область и автоматически выбрасывает всё, что за пределами этой области. Полезная область текстуры отображается
на ней желтым прямоугольником.
"Полезная" область определяется по альфа-каналу текстуры, т.е. за пределами "полезной" области альфа-канал равен 0, поэтому никакого изображения там просто нет,
что позволяет выбросить эту часть текстуры как нечто ненужное. При этом текстура для пользователя ведет себя также, как будто из неё ничего не удалялось.
Обратите внимание, что текстуры без альфа-канала не оптимизируются подобным образом.
d) Хранилище текстур
Чтобы не дублировать одинаковые текстуры, необходимо использовать Хранилище. Вообще стоит запомнить, что использование текстуры "вне хранилища" является для создателей игры злом, так как такие текстуры дублируются в ptc-файле. Надо заметить, что API всё же будет строить текстурные атласы избегая ненужного дублирования текстур, но смысла держать текстуры "вне хранилища" всё равно нет. Используйте команду: Правка->Поместить все текстуры в хранилище, чтобы гарантированно поместить в Хранилище все текстуры. Также может получиться так, что некоторые текстуры находятся в Хранилище, но нигде не используются. Чтобы автоматически удалить такие текстуры, используйте команду: Правка->Удалить неиспользуемые текстуры.
2. Факторы, ускоряющие/замедляющие расчеты спецэффекта
a) Количество частиц – самый важный фактор влияющий на скорость расчета спецэффекта. Старайтесь свести количество частиц к минимуму. Не нужно делать спецэффекты на несколько тысяч частиц - предел в играх обычно несколько сотен частиц на экране одновременно.
b) «Частота обновления» и «Интерполяция» (находится под сценой) – эти факторы тесно связаны между собой, поэтому я рассмотрю их вместе. Частота обновления – это временной шаг, с которым обрабатывается спецэффект, т.е. если он равен 30, то спецэффект обрабатывается 30 раз в секунду, а если 10, то только 10 раз в секунду. Это очень важно, потому что чем реже происходит обработка спецэффекта, тем лучше это для процессора. Но… если спецэффект обрабатывается редко, то визуально могут начаться рывки и искажения анимации, т.е. практически «Частота обновления» – это плавность перемещения частиц. Постарайтесь понять следующее – все расчеты спецэффекта всегда происходят с той частотой, которая указана в поле «Частота обновления», т.е. между обновлениями со спецэффектом вообще ничего не происходит. Значит чем меньше «Частота обновления», тем это лучше для скорости расчета. Например, если у вас 100 частиц обрабатываются 30 раз в секунду, то это почти то же самое, что 200 частиц обрабатываются 15 раз в секунду.
Теперь разберемся с «Интерполяцией». Использование этого режима позволяет получить положение частиц в моменты времени отличные от «Частоты обновления». Приведу пример: в современных графических программах трёхмерного моделирования анимация обычно делается через указание ключевых позиций, т.е. чтобы модель переместилась из одного места в другое, нужно указать лишь начальную и конечную стадии, а промежуточные стадии рассчитываются (интерполируются) автоматически. В Magic Particles логика работы режима Интерполяции аналогична. Поясню примером: все расчеты положений частиц выполняются всегда только с шагом «Частота обновления», и именно эти состояния как бы являются «ключевыми кадрами», но, имея два ключевых кадра, можно с достаточной точностью получить положение любой частицы в момент времени «между кадрами». Так оно и происходит. Имейте в виду, что применение режима «Интерполяции» требует дополнительного расхода памяти на каждую частицу (20 байт), потому что необходимо хранить предыдущее и последующее состояние, но обычно это некритично. Кроме того, режим «Интерполяции» часто позволяет снизить «Частоту обновления» без очевидных потерь качества. Например, откройте файл demo.ptc и выберите спецэффект Salute. Выключите «Интерполяцию» (если она включена), и задайте Частоту обновления =10. Спецэффект начнет двигаться рывками. Теперь включите «Интерполяцию» и рывки пропадут. Так вы сэкономили скорость расчета спецэффекта как минимум в 2 раза, потому что реально спецэффект рассчитывается 10 раз в секунду, а не 30 как это было в начале.
Очень важно, будет ли задействован в игре режим «Интерполяции». Этот вопрос лучше разузнать заранее. Если «Интерполяция» не задействована, то желательно, чтобы «Частота обновления» у всех спецэффектов в игре была одинаковой, потому что иначе не получится их обновлять одновременно (а это очень неудобно для программистов). Также важно помнить, что «Анимированные папки» работают в редакторе в режиме «Интерполяции».
Включать и выключать режим «Интерполяции» можно программно через API.
c) Свойство «Создавать порциями»
Свойство «Создавать порциями» в выключенном состоянии замедляет процесс создания частиц. По поводу данного свойства хотелось бы заметить, что отключать его имеет смысл, только если «Частота создания новых частиц» меньше 10 (а еще лучше около 1), иначе вы вряд ли заметите разницу в поведении. Т.е. не нужно трогать эту галочку, если у вас «Частота создания новых частиц» равна, например 30.
3. Экономия памяти
a) Сложность обработки графиков заключается в том, что определить по координате X координату Y в общем случае совсем непросто. Почему так? Потому что нужно сначала обнаружить предыдущую и последующую точки, а потом, получив формулу прямой между этими точками (хорошо еще, если не кривой), найти соответствующую точку Y. Для «красных» графиков подобная операция должна была бы выполняться постоянно для каждой частицы, что не есть хорошо. Поэтому я применил следующее решение: перед началом работы эмиттера все графики предварительно просчитываются с определенным шагом и результат просчетов запоминается в массиве. Далее во время работы график становится уже не нужен, и все числа берутся напрямую из заранее подготовленных массивов. Такой подход обеспечивает высокое быстродействие API при работе с графиками. Но… есть один важный вопрос: как выбрать длину массива? На графике «Продолжительность жизни, сек» есть дополнительное свойство «Дискретизация жизни». Это число и определяет длину массивов, в которые преобразуются «красные» графики. Число это нужно подбирать так, чтобы свойства частиц менялись плавно, например, если ваша частица изменяет свой размер во время существования, то визуально это должно происходить без рывков. Если же вы впишете «Дискретизация жизни»=5, то у вас все красные графики будут разделены на 5 частей и частица будет иметь только 5 размеров – вы это сразу увидите визуально, потому что размер частиц будет меняться скачкообразно. В общем, чем больше вы ставите число, тем плавне будут изменения, но… массивы в памяти тоже будут увеличиваться. Числа в массивах хранятся в виде float (4 байта). В общем, знайте меру и не пишите 5000 туда, где вполне годится 100.
4. Очень важный момент
Недавно наблюдал такую штуку – мне прислали спецэффект, сделанный из малого количества крупных частиц, причем эти частицы двигаются в определенном направлении (не случайном). Т.е. одна частица должна лететь строго направо, а другая строго налево. Так вот… визуально вроде всё работает правильно, но, если заглянуть внутрь, то обнаруживается, что направление движения и скорость всех частиц выбирается случайным образом!!! Иными словами, это чистая случайность, что они летят именно так, а не иначе. Так вот… если требуется конкретное направление движения, то и нужно выставлять конкретный угол (график «Направление эмиттера»). Почему так? Потому что программист может включить полную случайность у эмиттера из API и в этом случае все направления движения изменятся. Ну и самое главное – нельзя гарантировать, что в очередной версии Magic Particles не изменится порядок случайных чисел. В этом случае в новой версии всё полетит не туда, и ничего с этим не поделать. Вывод: там где нужны конкретные параметры используйте именно конкретные параметры и не надейтесь на случай. Если у вас на графике одновременно присутствуют и синяя, и зеленая линии, то вы как раз и получаете случайное значение – выключайте одну из линий, тогда будет всё точно. Чтобы убедится, что ваш эффект не зависит от случая, меняйте поле «№ случайности».
5. Цвет частиц
Цвет частиц можно менять 2-мя способами.
а) Указывать изменения цвета частицы во времени:
Рис. 1
б) Подмешивать к цвету частицы другой цвет в момент её создания:
Всегда используйте только способ 1, если нет какой-то явной необходимости использовать способ 2.
Помните, что если график «Влияние оттенка» не равен постоянно 0, то это означает, что к основному цвету частицы
(а способ 1 задействован всегда), будет подмешиваться цвет с графика «Влияние оттенка» в заданной пропорции. Операция эта требует дополнительных расчетов и чаще всего является неоправданной для использования в играх. Кроме того график «Влияние оттенка» действует на все типы частиц внутри эмиттера и нужен в основном для удобства пользователей, которые к созданию игр не имеют никакого отношения.
6. Особенности эмиттера типа «Картинка»
Будет хорошо, если на картинке будет как можно меньше неиспользуемой «черной» площади. Новая версия программы будет стараться обрезать неиспользуемую прямоугольную часть изображения, но всё же не помешает знать, для чего это делается.
Чтобы быстро создавать частицы на «полезной» площади изображения, происходит создание массивов координат. Т.е. сама картинка во время работы игры не нужна, а нужен только этот список. Но, чем больше площадь картинки, тем медленнее происходит процесс построения этого списка. Галочка «вероятность» также замедляет процесс построения списка, так как алгоритм выбора позиции частицы усложняется. Но самым нерациональным может оказаться применение галочки «оттенок». Этот флажок позволяет примешивать к основному цвету частицы (рис.1) дополнительный оттенок, который берется с самой картинки. Процент смешивания этих цветов опять же определяется графиком «Влияние оттенка». Применение такого приёма часто оправдано и выглядит интересно, потому что частицу можно окрасить в тот цвет с картинки, на котором она была создана. Однако стоит помнить вот о чем. Во-первых, это опять же требует дополнительных вычислений, а, во-вторых, для быстрого получения примешиваемых цветов приходится дополнительно хранить в ОЗУ всю картинку целиком. А, если изображение у вас, например, черно-белое, то это превращается в совершенно ненужные расходы памяти и ресурсов процессора, потому что применение флага «оттенок» имеет смысл только для цветного изображения.
7. Интервал видимости
Поле «Первая граница интервала видимости» позволяет анимировать спецэффект не с начала. Иногда это очень полезно. Но нужно понимать, что спецэффект не может сразу встать, например, на 5-ю секунду анимации. Для этого делаются те же самые расчеты, но просто без вывода изображения. А когда такой эмиттер запускается в игре, то эти же расчеты нужно будет проделать и там. Враппер, который входит в состав Magic Particles, обрабатывает эту ситуацию следующим образом:
a) При первом запуске такого эмиттера происходит его расчет до первой границы интервала видимости.
b) Результат расчета сохраняется, т.е. все частицы, которые были в тот момент в составе эмиттера поштучно записываются в файл.
c) При повторном запуске такого эмиттера расчеты не производятся, а сразу происходит загрузка всех частиц из файла.
Поэтому имеет смысл располагать «Первую границу интервала видимости» как можно ближе к 0.
В API расчет выполняется при помощи функции Magic_EmitterToInterval1. Обратите внимание, что данная функция принимает параметр speed_factor, который позволяет ускорить выполнение расчета в ушерб точности.
8. Смешивание разнотипных частиц
Когда-то давно рисование частиц могло осуществляться только в определенном порядке, т.е. сначала всегда рисовались частицы одного типа, а затем другого.
Однако сейчас при рисовании разные типы частиц могут перемешиваться. Это происходит по 2-м причинам: во-первых, в 3D существует сортировка частиц по камере, т.е.
получается, что порядок рисования частиц определяется расстоянием от каждой частицы до камеры, во-вторых, в 2D можно намеренно заставить частицы перемешаться для
получения особого визуального эффекта:
Обратите внимание, что на картинке частицы дыма перемешаны с частицами огня, что и обеспечивает визуальную однородность. Однако заметьте, что частицы огня
используют свойство "Интенсивность" для свечения, а частицы дыма нет. Видеокарта же умеет одновременно использовать только один из режимов. Получается, что при рисовании
спецэффекта приходится постоянно останавливать процесс рисования, чтобы поменять режим. Поле Сейчас проходов рисования на сцене показывает, сколько раз
был переключен режим видеокарты во время рисования спецэффекта. Естественно, что максимальная скорость рисования достигается, когда удалось нарисовать спецэффект за 1 проход.
9. Использование Просмотрщика
В новой версии программы имеется возможность создавать Просмотрщик или Хранитель экрана прямо из редактора, не прибегая к помощи программиста. Для этого достаточно нажать CTRL+Q и появится диалоговое окно, предлагающее создать Просмотрщик. Все эмиттеры, которые были загружены в редактор, попадут в exe-файл и их работу можно будет посмотреть уже в условиях близких к естественным. Запустите exe-файл и можно будет примерно оценить быстродействие, с которым данные спецэффекты работают на вашем компьютере. Самый главный параметр - это FPS или количество кадров в секунду. Чем FPS больше, тем лучше.