Статьи

Создание эффекта искажения в стиле ретро CRT с использованием RGB Shifting

В этом уроке вы узнаете, как разделить три цветовых канала изображения для создания эффекта смещения RGB. Я также покажу вам некоторые графические приемы, чтобы имитировать старый ЭЛТ-дисплей.


Вот пример эффекта, который мы будем создавать:

Основным выводом в этом уроке будет эффект смещения RGB, но я также покажу, как создавать линии сканирования на ЭЛТ, шум и графику с полосой прокрутки.


Каждое изображение на экране вашего компьютера отображается с использованием красного, синего и зеленого цветов. Смешивая эти три цвета в разных количествах, ваш компьютер может создавать другие цвета в спектре.

Цветовые каналы RGB

Если три цветовых канала не выровнены должным образом, изображение не будет правильно скомпоновано, и вы начнете видеть, как края отдельных каналов «кровоточат» по сторонам изображения.

Смещенные цветовые каналы

Это именно то, что мы собираемся делать в этом уроке; разделение изображения на три цветовых канала, а затем преобразование каждого по отдельности для создания эффекта искажения. Давайте доберемся до этого!

(Вы можете узнать больше о том, как работает цвет RGB в Википедии .)


Вам нужно будет создать графику, чтобы применить эффект. Я решил создать титульный экран видеоигры, но вы можете сделать любой вид графики, какой захотите.

Создайте новый мувиклип с названием «titleScreen» и поместите в него экран заголовка (или другую графику).

Я думаю, что-то с ретро-тематикой лучше всего работает с этим эффектом, поскольку напоминает мне старый неработающий аркадный экран. Я создал свой титульный экран со шрифтом Commodore 64 Pixeled . Я добавил фильтр Glow к тексту, чтобы придать ему размытый, размытый ЭЛТ-вид.

Свечение фильтра на текст

Как только вы довольны своим дизайном, добавьте к сцене MovieClip titleScreen и присвойте ему имя экземпляра titleScreen.

titleScreen Экземпляр

Создайте новый файл Actionscript с именем ‘RGBShift.as’. Сохраните этот файл в том же каталоге, что и ваш основной файл Flash. Добавьте этот код для создания оболочки для класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package {
 
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.BitmapDataChannel;
    import flash.display.BlendMode;
    import flash.events.Event;
    import flash.geom.Point;
 
    public class RGBShift extends Sprite {
 
        private var _centerX:Number;
        private var _centerY:Number;
 
        // CONSTRUCTOR
        public function RGBShift(dObj:DisplayObject) {
 
 
        }
 
 
    }
 
}

Примечание редактора: пока не устраивает кодирование на основе классов? Посмотрите этот Быстрый совет, чтобы помочь вам начать.

Этот код пока ничего не делает. Первые 10 строк или около того импортируют все дополнительные классы, которые нам понадобятся. У меня есть две приватные переменные с именами _centerX и _centerY (я использую подчеркивание для обозначения приватных переменных). Эти две переменные будут содержать координаты x и y центра нашего графика.

Обратите внимание, что функция конструктора (пока пустая) принимает объект DisplayObject. Это позволит нам использовать любой тип DisplayObject с этим эффектом (MovieClip, Sprite, Bitmap и т. Д.) Мы будем использовать titleScreen MovieClip со сцены, но наличие класса, принимающего любой DisplayObject, делает его гибким для последующего использования. ,


Мы сделали наш класс гибким, позволив ему принимать любой DisplayObject, но на самом деле нам понадобится объект BitmapData для выполнения эффекта смещения RGB. Давайте создадим функцию, которая может создавать BitmapData из DisplayObject.

Добавьте эту функцию в ваш класс RGBShift чуть ниже конструктора:

Посмотрите, что делает эта функция. Первая строка использует ширину и высоту объекта DisplayObject для создания нового прозрачного объекта BitmapData того же размера, что и объект DisplayObject. Затем он рисует объект DisplayObject в BitmapData. Наконец, он возвращает BitmapData вызывающей стороне.


Вот где происходит фактическое разделение цветов. Добавьте эту функцию в ваш класс:

Эта функция также принимает DisplayObject. Затем он передает это в функцию createBMD (), которую мы написали на предыдущем шаге, которая преобразует ее в BitmapData. Затем мы создаем три новых прозрачных объекта BitmapData; по одному на каждый цвет. Мы создаем их точно в том же размере, что и наш исходный BitmapData (из DisplayObject).

Затем мы используем метод CopyChannel () BitmapData для копирования одного цветового канала из исходного BitmapData в каждый из трех новых объектов BitmapData.

Последняя строка просто возвращает три новых объекта BitmapData, заключенных в массив.


Теперь, когда наши классы createBMD и createRGB работают вместе, давайте их использовать. Добавьте это в качестве первой строки кода в функцию конструктора для класса RGBShift:

Эта строка просто передает DisplayObject в функцию createRGB () . createRGB () использует функцию createBMD () для преобразования ее в BitmapData, а затем разделяет ее на три отдельных объекта BitmapData (по одному для каждого канала). Наконец, он возвращает массив этих трех объектов в наш локальный массив rgbBMD . Есть смысл? Хорошо.


Теперь у нас есть массив из трех объектов BitmapData. Нам нужно создать растровое изображение из каждого, чтобы отобразить их на экране. Добавьте этот цикл for в функцию конструктора RGBShift чуть ниже последней добавленной нами строки:

Примечание редактора: Приносим извинения за неудобства, отображение этого конкретного фрагмента ActionScript отключает FireFox. Не стесняйтесь скачать его здесь .

Большая часть этого довольно проста. Давайте взглянем.

  • С каждым объектом BitmapData в нашем массиве rgbBMD мы создаем новое растровое изображение.
  • Мы устанавливаем сглаживание в true, чтобы мы могли масштабировать и вращать его без пикселизации. (строка 23)
  • Затем мы создаем контейнер Sprite и добавляем новое растровое изображение в список отображения контейнера. (строки 25 и 26)
  • Теперь мы наконец-то начали использовать переменные _centerX и _centerY. Мы устанавливаем каждый в центр растрового изображения путем деления ширины и высоты пополам.
  • Мы используем эту центральную точку, чтобы сместить растровое изображение внутри контейнера Sprite, а затем сместить контейнер Sprite на сцене. Я объясню почему на следующем шаге.
  • Наконец, мы добавляем контейнер Sprite на сцену (помните, что есть контейнер для каждого из наших трех цветовых каналов).

Вы можете создать этот эффект без контейнера Sprite, просто добавив растровые изображения прямо на сцену. Мне нравится заключать их в контейнер, потому что это облегчает контроль точки трансформации, когда вы выполняете такие вещи, как масштабирование и вращение.

Обычно, когда вы выполняете масштабирование или вращение объекта, оно трансформируется из начальной точки (0,0) этого объекта. Это редко то, что я хочу случиться. Обычно я хочу, чтобы преобразования применялись из центра объекта.

Обратите внимание, что в последнем разделе мы устанавливаем x и y растровых изображений равными отрицательной половине ширины и высоты. Это размещает растровое изображение таким образом, чтобы его центральная точка находилась на 0,0 в контейнере Sprite. Если мы выполним какие-либо преобразования в контейнере Sprite, он будет преобразован из 0,0 контейнера, который теперь является центром нашего растрового изображения.

Единственная проблема в том, что теперь виден только нижний угол нашего растрового изображения, поэтому я установил для контейнера Sprite x и y половину высоты и ширины растрового изображения, чтобы все вернулось в правильное положение.

Смещение спрайта контейнера

Вот класс RGBShift до этого момента, если вы заблудились на этом пути:

Примечание редактора: Я снова, еще раз вам придется скачать AS здесь . Приносим извинения за неудобства.


Итак, у нас есть класс RGBShift, но как мы его используем? Начните с создания нового файла Actionscript с именем Main.as, затем добавьте этот код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
package {
     
    import flash.display.MovieClip;
     
    public class Main extends MovieClip {
     
        public function Main() {
             
            var rgb = new RGBShift(titleScreen);
            removeChild(titleScreen);
             
            // add it to the stage
            addChild(rgb);
             
        }
    }
 
}

Здесь мы создаем новый экземпляр класса RGBShift и передаем ему titleScreen MovieClip со сцены. Нам больше не нужен этот MovieClip, поэтому мы удаляем его со сцены и вместо этого добавляем новый экземпляр RGBShift.

Теперь нам просто нужно связать этот класс с нашим документом Flash. Вернитесь во Flash и установите для класса документа значение «Основной».

Установить класс документа

Теперь вы должны иметь возможность протестировать ваш Flash-файл («Управление» -> «Тестировать ролик») без каких-либо ошибок или предупреждений.

Первый тест

Хм, это выглядит не совсем правильно, не так ли?

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


Для правильного смешивания цветовых каналов нам нужно изменить их BlendMode на SCREEN. Мы только хотим изменить режим смешивания второго и третьего слоев. Мы оставим первый (нижний) слой нормальным и смешаем в нем два других слоя.

Добавьте этот код в цикл for в функции конструктора класса RGBShift:

Это проверяет, чтобы убедиться, что текущее изображение не является первым изображением (0), а затем устанавливает для свойства blendMode значение SCREEN.


Протестируйте свой фильм еще раз, и вы должны увидеть что-то, похожее на ваш титульный экран.

Успешный тест

Я знаю, что ты думаешь; «Это была большая работа по воссозданию того же графика, который уже был там».

Но теперь графика состоит из трех объектов, которые мы можем трансформировать по отдельности, чтобы создать искажение. Так что прекрати ныть и давай продолжим …


Мы собираемся использовать библиотеку Tweener для анимации. Загрузите его здесь, если у вас его еще нет.

Чтобы использовать Tweener, поместите главную папку ‘caurina’ в тот же каталог, что и ваш файл Flash, и добавьте этот оператор импорта в начало класса RGBShift:


Я использую эту функцию randRange как простой способ генерировать случайные целые числа в заданном диапазоне. Вы можете просто добавить эту функцию в класс RGBShift, но я использую эту функцию так часто, что мне нравится хранить ее в отдельном файле, чтобы ее было легче распространять среди разных проектов.

Создайте новый файл Actionscript с именем ‘randRange.as’ в той же папке, что и ваш основной файл Flash. Добавьте этот код:

1
2
3
4
5
6
7
package {
    // returns a random number between specified range (inclusive)
    public function randRange(min:int, max:int):int {
        var randomNum:int = Math.floor(Math.random() * (max — min + 1)) + min;
        return randomNum;
    }
}

Как видите, это всего лишь одна функция, заключенная в объявление пакета. Теперь мы можем использовать эту функцию, как если бы она была частью нашего класса.

(Для получения дополнительной информации о том, как работает эта функция, ознакомьтесь с Quick Tip от Carlos .)


Вот где происходит волшебство. Добавьте эту функцию в класс RGBShift:

Мы собираемся запустить эту функцию distort () для каждого из наших цветовых каналов отдельно, чтобы создать эффект искажения.

Функция принимает Sprite (один из наших контейнеров цветовых каналов). Затем он запускает анимацию Tweener на канале с использованием случайного значения Y (от -3 до 3) и случайной продолжительности времени (от 1 до 2 секунд). Это заставит каждый канал сдвигаться вверх и вниз на разную величину с разной скоростью.

Обратите внимание, что я снова использую переменную _centerY для смещения значения Y. Мы также переключаемся на случайное альфа-значение (от 0,8 до 1), чтобы каждый канал немного мерцал. Когда анимация заканчивается, мы используем свойство onComplete для повторного вызова той же функции distort () . Используя onCompleteParams мы отправляем ему тот же цвет канала Sprite. Это заставляет функцию искажения повторяться снова и снова на каждом из наших цветовых каналов.

Видишь, что я тебе сказал ..? Магия!

Чтобы запустить этот цикл искажения, нам нужно вызвать его один раз для каждого из наших цветовых каналов Sprites. Добавьте эту строку в конец цикла for в функции конструктора RGBShift:


Теперь вы сможете проверить свой фильм и увидеть эффект искажения в действии.

Лично мне нравится тонкий сдвиг Y, который у нас здесь происходит, но вы можете сделать много безумных вещей с искажением теперь, когда у нас есть каналы, анимирующие отдельно.

Чтобы поэкспериментировать с искажением, вы можете просто изменить свойства и значения в вызове Tweener в функции искажения . Проверьте документацию Tweener для полного списка свойств tweenable.

Вот пример некоторых серьезных искажений, которые я создал, просто добавив еще несколько свойств к вызову Tweener:

Проверьте функцию distort (), которая создала эффект:


Вы можете остановиться здесь, если хотите. Разделение и искажение RGB должны работать на этом этапе.

Для усиления эффекта ЭЛТ, я думаю, нам нужно добавить еще несколько графических элементов. В следующие несколько шагов мы добавим линии сканирования, вращающуюся черную полосу, немного статики и блестящее отражение.


Создайте новый MovieClip на сцене под названием «линии». Внутри мувиклипа нарисуйте горизонтальную линию размером 1 пиксель, которая охватывает всю ширину вашего фильма. Установите цвет обводки на черный с 40% альфа.

Теперь скопируйте и вставьте эту строку снова и снова, перемещая ее на 2 пикселя каждый раз, пока у вас не появятся линии, покрывающие всю высоту вашего фильма. Эффект, который вы хотите, это 1 пиксельная строка, затем 1 пиксельный интервал перед следующей строкой.

Линии сканирования

Теперь мы добавим черную полосу. Создайте новый мувиклип под названием «бар». Внутри нарисуйте сплошной черный прямоугольник, который охватывает всю ширину вашего фильма. Сделайте это около 40 пикселей в высоту. Установите Цветовой стиль MovieClip на Альфа на 30%.

Bar MovieClip

Создайте новый мувиклип под названием «animatingBar» и поместите клип внутри. Создайте анимацию короткой анимации движения полосы, движущейся от верхней части фильма к нижней части. Эта анимация зациклится, чтобы дать нам эффект скользящей полосы.

Поместите клип animatingBar на сцену. Выберите его и добавьте фильтр размытия. Отключите настройки размытия X и Y и установите Blur Y на 20, а Blur X на 0.

Установите режим наложения на Overlay. Это похоже на режим смешивания экрана, который мы использовали ранее, но не совсем то же самое.

AnimatingBar Blur Filter

Создайте новый файл Photoshop того же размера, что и ваш фильм. Заполните фоновый слой нейтральным серым (# 808080). Выберите «Фильтр»> «Шум»> «Добавить шум» …
Установите фильтр на 100%, гауссовский, монохромный.

Настройки шумового фильтра

Сохраните изображение как «noise.jpg». Если у вас нет Photoshop, вы можете получить мой файл noise.jpg из исходного архива.


Импортируйте изображение noise.jpg в ваш flash-файл. Создайте новый мувиклип под названием «шум» и добавьте к нему изображение. Создайте новый ключевой кадр в кадре 2 (F6) и поверните изображение на 180 градусов. Создайте еще один ключевой кадр в кадре 3 и отразите изображение по горизонтали («Модификация»> «Трансформировать»> «Отразить по горизонтали»). Создайте четвертый ключевой кадр в кадре 4 и снова поверните изображение на 180 градусов. Теперь у нас есть 4-кадровая анимация мерцающей статики.

Вы также можете создать этот шумовой эффект с помощью ActionScript, но это выходит за рамки данного руководства.

Анимационный шум

Создайте новый MovieClip на сцене под названием «сияние». Внутри нарисуйте большой овал, который проходит на полпути над верхней частью вашего фильма. Выберите верхнюю часть овала и удалите его.

Создать блеск овал

Измените заливку на линейный градиент и установите его так, чтобы он смешивался от белого 20% альфа вверху до белого 5% альфа внизу. Возьмите верхнюю часть фигуры и слегка потяните ее вверх, чтобы придать ей небольшой изгиб.

Раскрась овал

Если вы протестируете свой фильм сейчас, вы не увидите никакой новой графики, которую мы только что добавили, потому что слои RGB добавляются поверх всего. Чтобы это исправить, перейдите в класс Main и измените эту строку:

К этому:

Это добавляет объект RGBShift на самый нижний уровень списка отображения , ниже всех других графиков.


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

Как всегда, оставьте комментарий и дайте мне знать, что вы думаете. Удачи!