
Вот такой незамысловатый эффект получился при использовании pixel bender'а.
На самом деле такой эффект я впервые увидел у Andre Michelle, но сорсов он не выложил. В те времена я написал его на восьмом плеере (AS2), но с выходом новых возможностей решил повторить эксперимент. Обошлось не без приключений, зато код получился без граблей, которые приходилось строить в восьмерке.
Смотреть тут. (5 мб)
Пишем фильтр
Переменные:
src — первая входная картинка
src2 — вторая входная картинка
white — белый цвет
black — черный цвет
min — значение по которому определяем ставить белый или черный цвет в выходящее изображение
Логика фильтра такова:
— (a1) берем цвет первого пикселя первой картинки
— (a2) берем цвет первого пикселя второй картинки
— (ss) вычитаем из a1 a2
— если разница каждого цвета ss больше min тогда в выходящей картинке на месте первого пикселя будет белый цвет иначе черный
- <languageVersion : 1.0;>
-
- kernel NewFilter
- < namespace : "Your Namespace";
- vendor : "Your Vendor";
- version : 1;
- description : "your description";
- >
- {
- input image4 src;
- input image4 src2;
- output pixel4 dst;
-
- const pixel4 white = float4(1.0, 1.0, 1.0, 1.0);
- const pixel4 black = float4(0.0, 0.0, 0.0, 0.0);
- const float min = 0.05;
-
- void
- evaluatePixel()
- {
- pixel4 a1 = sampleNearest(src, outCoord());
- pixel4 a2 = sampleNearest(src2, outCoord());
-
- pixel4 ss = a1 - a2;
-
- dst = (ss.r>min && ss.g>min && ss.b>min) ? white : black;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Пишем программу
Чтение кода не должен вызвать затруднений, только поясню некоторые вещи.
bmp1 — отпечаток картинки видео самого нового кадра
bmp2 — отпечаток bmp1, то есть предыдущий кадр от самого нового
bmp3 — результирующая картинка после применения фильтра PixelBender'а
cmf — фильтр который вычитает из всех пикселей картинки альфу по 10
out — картинка которую мы видим, на нее каждый кадр накладывается bmp3, а также фильтр cmf и blur
- package {
-
- import flash.display.Bitmap;
- import flash.display.BitmapData;
- import flash.display.Shader;
- import flash.display.ShaderJob;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.filters.BlurFilter;
- import flash.filters.ColorMatrixFilter;
- import flash.geom.Point;
- import flash.media.Video;
- import flash.net.NetConnection;
- import flash.net.NetStream;
- import flash.utils.ByteArray;
-
- [SWF(width=376, height=160, backgroundColor=0x0)]
-
- public class SubstractTv extends Sprite {
-
- [Embed(source="../assets/kutu.pbj", mimeType="application/octet-stream")]
- private var pbj:Class;
-
- private var wid:uint = stage.stageWidth;
- private var hei:uint = stage.stageHeight;
-
- private var video:Video;
- private var nc:NetConnection;
- private var ns:NetStream;
-
- private var bmp1:BitmapData;
- private var bmp2:BitmapData;
- private var bmp3:BitmapData;
- private var out:BitmapData;
- private var bmp:Bitmap;
-
- private var shader:Shader;
- private var shaderJob:ShaderJob;
-
- private var blur:BlurFilter;
- private var cmf:ColorMatrixFilter;
-
- public function SubstractTv() {
- nc = new NetConnection();
- nc.connect(null);
- ns = new NetStream(nc);
- ns.client = new Object();
- ns.play("video.f4v");
-
- video = new Video(wid, hei);
- video.attachNetStream(ns);
-
- bmp1 = new BitmapData(wid, hei, true);
- bmp2 = bmp1.clone();
- bmp3 = bmp1.clone();
- out = bmp1.clone();
- bmp = new Bitmap(out, "auto", true);
- addChild(bmp);
-
- shader = new Shader(new pbj() as ByteArray);
- shader.data.src.input = bmp1;
- shader.data.src2.input = bmp2;
- createShaderJob();
-
- addEventListener(Event.ENTER_FRAME, onEnterFrame);
-
- blur = new BlurFilter(3, 3, 3);
- cmf = new ColorMatrixFilter([ 1, 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 1, -10]);
- }
-
- private function onEnterFrame(e:Event):void {
- if (shaderJob.progress != 1) return;
-
- bmp2.draw(bmp1);
- try {
- bmp1.draw(video);
- } catch(e:Error) {}
-
- createShaderJob();
-
- out.applyFilter(out, out.rect, new Point(), blur);
- out.applyFilter(out, out.rect, new Point(), cmf);
- out.draw(bmp3);
- }
-
- private function createShaderJob():void {
- shaderJob = new ShaderJob(shader, bmp3, wid, hei);
- shaderJob.start();
- }
-
- }
- }
* This source code was highlighted with Source Code Highlighter.