Эффект объёмного искажения или как я изобретал велосипед.


Началось все с того, что одним из обычных вечеров после продуктивной работы над проектом, чувствуя изрядную усталость от написания кода, я решил сделать небольшой перерыв и расслабиться жмякая по кнопкам геймпада. «Broforce». Среди множества сладостей, которыми игра может порадовать – возможность поиграть одним из множества персонажей культовых боевиков. Одним из таких персонажей, которым мне довелось поиграть был агент J из фильма «Люди в черном». Как и в фильме, персонаж игры бегает с футуристическим пистолетом «Сверчек», при выстреле из которого и возникал тот самый эффект взрывной волны искажающий пространство и именно этот эффект мне жутко захотелось повторить.
Садясь за работу, я поставил перед собой задачу написать класс, с помощью которого можно было бы без особых усилий создавать подобные эффекты. На разработку класса начиная от черкания каких то формул и алгоритмов на листочке, исправления недочетов алгоритма и до работоспособной версии было потрачено примерно 2 дня. Проделанной работой я был доволен, но единственное что меня сильно смущало – производительность, а она сильно страдала при большом кол-ве эффектов на сцене, а также от размеров самих эффектов, поэтому я решил обратиться за помощью по поднятию перфоманса к комраду Кролику (он же TheRabbit, он же Антон Азаров). Просмотрев мое «творчество» Кролик указал на допущенные мной ошибки, которые я незамедлительно принялся исправлять, но на этом участие TheRabbit в этой эпопее не закончилось. Углубившись в изучение кода, он меня «обрадовал», сказав что я пытаюсь изобрести велосипед, к тому же с жутко квадратными колесами, в то время как он уже давным-давно изобретен, попутно дав кучу ссылок на этот самый велосипед, а назывался он как оказалось — DisplacementMapFilter.
Я, конечно же, жутко расстроился, но все же стал потихоньку вникать и писать систему классов для упрощения создания эффектов с использованием DisplacementMapFilter. Хочу сказать что он мне сильно не понравился из за сложности подготовки шейдера, хотя возможно сложным он кажется только мне.
Как итог реализовал два способа реализации задуманных эффектов, у каждого из которых по моему скромному мнению есть свои плюсы и минусы:
  • Мой самописный метод.
  • Простой в подготовке шейдеров различной формы и сложности, но, к сожалению, очень ресурсоемкий.
  • Метод с использованием DisplacementMapFilter.
  • Очень быстрый в плане перфоманса, но как мне показалось, сложен в подготовке шейдеров.

Для игр, конечно же, лучше использовать второй вариант, но честно говоря, мне жалко выкидывать свой вариант а посему оставлю его тут, мало ли может кому то пригодится)

Примеры использования эффекта:
Самописный метод:




DisplacementMapFilter:
Кликаем по приведениям что бы увидеть эффект в действии.


Пользоваться классам очень просто. Для создания нужного нам эффекта необходимо создать новый экземпляр интересующего нас класса и передать внего два обязательных параметра:
zoomMask или mask — имя мувика который будет выполнять роль шейдера.
sourse — ссылка на конейтер из которго и будет браться изображение для его дальнейшейго обработки и создания эффекта.
далее просто добавляем наш эффект на сцену в нужный нам слой и не забываем обновлять его при смене кадра вызывая метод update.

Примечание: во избежания артефактов при накладывании двух эффектов друг на друга эффект лучше не добавлять на слой с графикой которая будет использоваться для создания эффекта. Лучшим вариантом будет создать отдельный слой для эффектов поверх остальной графики.

Так же у класса есть несколько общедоступных методов, таких как :play(), stop(), gotoAndPlay(),gotoAndStop(),onComplete() и несколько параметров loop (true/false) и onCompleteParams (Object)

Подготовка шейдеров:

Для моего самописного эффекта в качестве шедера используется изображение с разным значением альфы, где нулевое значение альфа канал соответствует отсутствию зума изображения в этом участке изображения, а максимальное значения альфа канала — соответствует максимальному зуму изображения.
Пример:


С подготовкой шейдера для DisplacementMapFilter чуть сложнее, поэтому что бы не запутать вас дам ссылку на статью где это более внятно описано — www.emanueleferonato.com/2007/12/03/understanding-flash-displacement-map-filter/
help.adobe.com/ru_RU/FlashPlatform/reference/actionscript/3/flash/filters/DisplacementMapFilter.html?filter_flex=4.1&filter_flashplayer=10.2&filter_air=2.6

Исходники:
Самописный метод — Download

Метод с использованием DisplacementMapFilter — Download

В завершении хотел бы поблагодарить Антона Азарова (TheRabbit) за оказанную помощь, а также форумчанина Winged_Doom за помощь в подготовке презентационных роликов и предоставленную графику к ним.">

Комментарии (9)

+2
А я думал, что всех разработчиков, без предупреждения включающих на веб-странице звук, расстреляли еще в 37м…
0
Не всех, мы в подполье ушли)
Просто хотелось добавить атмосферности. Если сильно раздражает — могу убрать.
0
Нормальные люди делают проигрывание роликов/звуков по действию пользователя (клику).
0
Музыку совсем убрал, дабы не раздражала никого.
0
Убери. Через музыку текст читать не хочется.
+1
Поправил.
0
подскажите пожалуйста название композиции!
0
Heavy Rain — Ost
Ethan Mars' Main Theme
0
Давно делал похожий эффект. Здесь можно посмотреть restingames.com/shooting/try-2-survive

P.S. игра не взлетела:)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.