<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jozef Chúťka&#039;s blog &#187; Shader</title>
	<atom:link href="http://blog.yoz.sk/tag/shader/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.yoz.sk</link>
	<description>My life, my work</description>
	<lastBuildDate>Tue, 31 Jan 2012 12:40:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Pixel Bender Inputs &#8211; Vector or ByteArray</title>
		<link>http://blog.yoz.sk/2010/08/pixel-bender-inputs-vector-or-bytearray/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pixel-bender-inputs-vector-or-bytearray</link>
		<comments>http://blog.yoz.sk/2010/08/pixel-bender-inputs-vector-or-bytearray/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 13:07:13 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[ByteArray]]></category>
		<category><![CDATA[Endian]]></category>
		<category><![CDATA[pixel bender]]></category>
		<category><![CDATA[Shader]]></category>
		<category><![CDATA[ShaderJob]]></category>
		<category><![CDATA[Vector]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=2105</guid>
		<description><![CDATA[Pixel Bender for Flash Player lets you play some more advanced games. Based on your needs you can force your kernels to &#8220;eat&#8221; not only BitmapData, but also ByteArray-s or Vector-s. With this knowledge, you can simply use Pixel Bender kernels for some fast math or processing like 3D engines (3D to 2D projection) etc. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/pixelbender.png" alt="" title="pixelbender" width="200" height="100" class="alignleft size-full wp-image-2130" /></p>
<p><a href="http://www.adobe.com/devnet/pixelbender/">Pixel Bender</a> for Flash Player lets you play some more advanced games. Based on your needs you can force your kernels to &#8220;eat&#8221; not only BitmapData, but also ByteArray-s or Vector-s. With this knowledge, you can simply use Pixel Bender kernels for some fast math or processing like 3D engines (3D to 2D projection) etc. Lets have a look at some simple demos, how to push vector and raw bytes directly into shader via ShaderJob:</p>
<p><span id="more-2105"></span></p>
<h3>Vector.&lt;Number&gt;</h3>
<p>Simple (one-dimension) vector may be recognized by pixel bender as 3-channel input just as simple as providing correct width/height for shader:</p>
<pre class="brush: as3; title: ; notranslate">var src:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();
while(someLooping)
{
    src.push(x);
    src.push(y);
    src.push(z);
}

var shader:Shader = new Shader(code);
shader.data.src.input = src;
shader.data.src.width = src.length / 3; // forces pixel bender to use image3 as input
shader.data.src.height = 1;

var res:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();
var job:ShaderJob = new ShaderJob(shader, res, src.length / 3, 1);
job.start(true);

for(var i:uint=0; i&lt;src.length; i+=3)
{
    x = res[i];
    y = res[i+1];
    z = res[i+2];
}</pre>
<h3>ByteArray</h3>
<p>If you are more in &#8220;low-level&#8221; things, try using raw bytes as input. Do not forget to setup LITTLE_ENDIAN for source and result variables. Also make sure width*height*4 results in source bytes length.</p>
<pre class="brush: as3; title: ; notranslate">var src:ByteArray = new ByteArray();
src.endian = Endian.LITTLE_ENDIAN;
src.position = 0;
while(someLooping)
{
    src.writeFloat(x);
    src.writeFloat(y);
    src.writeFloat(z);
}

var shader:Shader = new Shader(code);
shader.data.src.input = src;
shader.data.src.width = 256; // e.g.
shader.data.src.height = src.length/4/256;

var res:ByteArray = new ByteArray();
res.endian = Endian.LITTLE_ENDIAN;

var job:ShaderJob = new ShaderJob(shader, res, 256, src.length/4/256);
job.start(true);

res.position = 0;
for(var i:uint = 0; i&lt;src.length/4; i++)
{
    x = res.readFloat();
    y = res.readFloat();
    z = res.readFloat();
}</pre>
<p>Lets have a look at how pixel bender handles input and outputs. As with current version of pixel bender/flash player it seems like:</p>
<pre class="brush: plain; title: ; notranslate">'res' : cannot have 1 or 2 channel outputs</pre>
<p>&#8230; but you can use 3 or 4 channel outputs (float3, pixel3).</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;
kernel threed &lt;namespace : &quot;sk.yoz&quot;;vendor : &quot;Yoz&quot;;version : 1;&gt;
{
    input image3 src;
    output float3 res; // or pixel3
    void evaluatePixel()
    {
        res = sample(src, outCoord());
        // we have res.x, res.y and res.z
    }
}</pre>
<p>Where to go from here:</p>
<ul>
<li><a href="http://www.flashmagazine.com/tutorials/detail/using_pixel_bender_to_calculate_information/">Using Pixel Bender to calculate information</a></li>
<li><a href="http://www.huesforalice.com/project/47">Number crunching with as3 and pixelbender</a></li>
<li><a href="http://www.adobe.com/devnet/flex/articles/flashbuilder4_pixelbender.html">Using Pixel Bender with Flash Builder 4 as a number crunching engine</a></li>
<li><a href="http://www.unitzeroone.com/blog/2009/03/18/flash-10-massive-amounts-of-3d-particles-with-alchemy-source-included/">Flash 10, Massive amounts of 3D particles with Alchemy (source included).</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/08/pixel-bender-inputs-vector-or-bytearray/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Pixel Bender Disco</title>
		<link>http://blog.yoz.sk/2010/02/pixel-bender-disco/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pixel-bender-disco</link>
		<comments>http://blog.yoz.sk/2010/02/pixel-bender-disco/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 11:24:09 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[BitmapData]]></category>
		<category><![CDATA[fps]]></category>
		<category><![CDATA[pixel bender]]></category>
		<category><![CDATA[Shader]]></category>
		<category><![CDATA[ShaderJob]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=1117</guid>
		<description><![CDATA[While playing with pixel bender, I created some simple sahders that when combined, reminds me of winamp visualizations effects. Feel free to use any in your own projects. Click and drag mouse to make some disco effects. (wait while page header flash finishes loading so it runs smoothly) Rotation pixel bender Blur pixel bender Colorize [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/pixelBenderDisco.jpg" alt="" title="pixelBenderDisco" width="200" height="100" class="alignleft size-full wp-image-1124" /></p>
<p>While playing with pixel bender, I created some simple sahders that when combined, reminds me of winamp visualizations effects. Feel free to use any in your own projects.</p>
<p><span id="more-1117"></span></p>
<p style="clear:both;">Click and drag mouse to make some disco effects. (wait while page header flash finishes loading so it runs smoothly)</p>
<p><iframe width="100%" height="300" style="border:none;" src="http://blog.yoz.sk/examples/pixelBenderDisco/"></iframe></p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; layout=&quot;absolute&quot;
    enterFrame=&quot;enterFrame()&quot; applicationComplete=&quot;init()&quot;
    backgroundColor=&quot;#ffffff&quot; frameRate=&quot;50&quot;
    mouseMove=&quot;mouseMoveHandler(event)&quot;
    mouseDown=&quot;mouseDownHandler(event)&quot;
    mouseUp=&quot;mouseUpHandler(event)&quot;&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
    private var drawing:Boolean = false;
    private var color:uint = 0x0;
    private var bitmap:Bitmap = new Bitmap();
    private var lineX:Number = 0;

    [Bindable]
    private var fps:Number = 0;
    private var fpsDate:Date = new Date();
    private var fpsFrames:uint = 0;

    [Bindable]
    private var rotationTime:uint = 0;

    [Bindable]
    private var blurTime:uint = 0;

    [Bindable]
    private var colorizeTime:uint = 0;

    [Bindable]
    private var twirlTime:uint = 0;

    [Embed(source=&quot;../pbj/rotation.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const ROTATION_CLASS:Class;
    private static const ROTATION_SHADER:Shader = new Shader(new ROTATION_CLASS());

    [Embed(source=&quot;../pbj/blur.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const BLUR_CLASS:Class;
    private static const BLUR_SHADER:Shader = new Shader(new BLUR_CLASS());

    [Embed(source=&quot;../pbj/colorize.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const COLORIZE_CLASS:Class;
    private static const COLORIZE_SHADER:Shader = new Shader(new COLORIZE_CLASS());

    [Embed(source=&quot;../pbj/twirl.pbj&quot;, mimeType=&quot;application/octet-stream&quot;)]
    private static const TWIRL_CLASS:Class;
    private static const TWIRL_SHADER:Shader = new Shader(new TWIRL_CLASS());

    private function init():void
    {
        placeholder.addChild(bitmap);
    }

    private function mouseDownHandler(event:MouseEvent):void
    {
        drawing = true;
        color = Math.random() * 0xffffff;
    }

    private function initGraphics():void
    {
        container.graphics.clear();
        container.graphics.moveTo(mouseX, mouseY);
        container.graphics.lineStyle(10, color, 1);
    }

    private function mouseUpHandler(event:MouseEvent):void
    {
        drawing = false;
    }

    private function mouseMoveHandler(event:MouseEvent):void
    {
        if(!drawing)
            return;
        container.graphics.lineTo(event.localX, event.localY);
    }

    private function countFps():void
    {
        if(++fpsFrames &lt; 10)
            return;
        fps = Math.round(1 / (new Date().time - fpsDate.time) * 10000);
        fpsDate = new Date();
        fpsFrames = 0;
    }

    private function get w():Number
    {
        return container.width;
    }

    private function get h():Number
    {
        return container.height;
    }

    private function enterFrame():void
    {
        countFps();

        if(!container || !container.width)
            return;

        var bitmapData:BitmapData = new BitmapData(w, h, true, 0x000000);
        bitmapData.draw(bitmap);
        if(rotationCheckBox.selected)
            addRotation(bitmapData, 0.1);
        if(blurCheckBox.selected)
            addBlur(bitmapData);
        if(colorizeCheckBox.selected)
            addColorize(bitmapData, color);
        if(twirlCheckBox.selected)
        {
            var radius:Number = Math.min(w / 2, h / 2);
            addTwirl(bitmapData, 10, new Point(w / 4, h / 2), radius);
            addTwirl(bitmapData, -10, new Point(w / 4 * 3, h / 2), radius);
        }

        addAutoFill();
        bitmapData.draw(container);

        bitmap.bitmapData = bitmapData;
        initGraphics();
    }

    private function addAutoFill():void
    {
        lineX = (lineX &gt; w) ? 0 : (lineX + 15);
        container.graphics.moveTo(lineX - 15, h / 3 * 2);
        container.graphics.lineTo(lineX, h / 3 * 2);
    }

    private function addRotation(bitmapData:BitmapData, rotation:Number):void
    {
        rotationTime = new Date().time;
        ROTATION_SHADER.data.src.input = bitmapData;
        ROTATION_SHADER.data.src.width = w;
        ROTATION_SHADER.data.src.height = h;
        ROTATION_SHADER.data.rotation.value = [rotation];
        ROTATION_SHADER.data.tx.value = [w / 2];
        ROTATION_SHADER.data.ty.value = [h / 2];

        var job:ShaderJob = new ShaderJob(ROTATION_SHADER, bitmapData);
        job.start(true);
        rotationTime = new Date().time - rotationTime;
    }

    private function addBlur(bitmapData:BitmapData):void
    {
        blurTime = new Date().time;
        BLUR_SHADER.data.src.input = bitmapData;
        BLUR_SHADER.data.src.width = w;
        BLUR_SHADER.data.src.height = h;

        var job:ShaderJob = new ShaderJob(BLUR_SHADER, bitmapData);
        job.start(true);
        blurTime = new Date().time - blurTime;
    }

    private function addColorize(bitmapData:BitmapData, color:uint):void
    {
        colorizeTime = new Date().time;
        var r:Number = ((color &gt;&gt; 16) &amp; 0xFF) / 0xFF - 0.5;
        var g:Number = ((color &gt;&gt; <img src='http://blog.yoz.sk/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> &amp; 0xFF) / 0xFF - 0.5;
        var b:Number = (color &amp; 0xFF) / 0xFF - 0.5;

        COLORIZE_SHADER.data.src.input = bitmapData;
        COLORIZE_SHADER.data.src.width = w;
        COLORIZE_SHADER.data.src.height = h;
        COLORIZE_SHADER.data.color.value = [r / 40, g / 40, b / 40];

        var job:ShaderJob = new ShaderJob(COLORIZE_SHADER, bitmapData);
        job.start(true);
        colorizeTime = new Date().time - colorizeTime;
    }

    private function addTwirl(bitmapData:BitmapData, angle:Number,
        center:Point, radius:Number):void
    {
        twirlTime = new Date().time;
        TWIRL_SHADER.data.oImage.input = bitmapData;
        TWIRL_SHADER.data.oImage.width = w;
        TWIRL_SHADER.data.oImage.height = h;
        TWIRL_SHADER.data.radius.value = [radius];
        TWIRL_SHADER.data.center.value = [center.x, center.y];
        TWIRL_SHADER.data.twirlAngle.value = [angle];

        var job:ShaderJob = new ShaderJob(TWIRL_SHADER, bitmapData);
        job.start(true);
        twirlTime = new Date().time - twirlTime;
    }
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:UIComponent width=&quot;100%&quot; height=&quot;100%&quot; id=&quot;placeholder&quot; /&gt;
&lt;mx:Container id=&quot;container&quot; width=&quot;100%&quot; height=&quot;100%&quot; backgroundAlpha=&quot;0&quot;/&gt;
&lt;mx:VBox paddingLeft=&quot;10&quot; paddingTop=&quot;10&quot;&gt;
    &lt;mx:Text text=&quot;fps: {fps} / 50&quot; /&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;rotationCheckBox&quot; selected=&quot;true&quot;/&gt;
        &lt;mx:Label text=&quot;rotation {rotationTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;blurCheckBox&quot; selected=&quot;true&quot;/&gt;
        &lt;mx:Label text=&quot;blur {blurTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;colorizeCheckBox&quot; selected=&quot;true&quot;/&gt;
        &lt;mx:Label text=&quot;colorize {colorizeTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
    &lt;mx:HBox&gt;
        &lt;mx:CheckBox id=&quot;twirlCheckBox&quot; selected=&quot;false&quot;/&gt;
        &lt;mx:Label text=&quot;twirl {twirlTime} ms&quot; /&gt;
    &lt;/mx:HBox&gt;
&lt;/mx:VBox&gt;
&lt;/mx:Application&gt;</pre>
<p>Rotation pixel bender</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;

kernel RotationFilter
&lt;
	namespace : &quot;sk.yoz&quot;;
	vendor : &quot;Yoz&quot;;
	version : 1;
	description : &quot;Image rotation over transform point&quot;;
&gt;
{
	input image4 src;
	output pixel4 dst;

	parameter float tx
	&lt;
		minValue: float(0.0);
		maxValue: float(4096.0);
		defaultValue: float(0.0);
		description: &quot;The amount of movement along the x axis to the right, in pixels.&quot;;
	&gt;;

	parameter float ty
	&lt;
		minValue: float(0.0);
		maxValue: float(4096.0);
		defaultValue: float(0.0);
		description: &quot;The amount of movement down along the y axis, in pixels.&quot;;
	&gt;;

	parameter float rotation
	&lt;
		minValue: float(0.0);
		maxValue: float(4096.0);
		defaultValue: float(0.0);
		description: &quot;Rotation in radians&quot;;
	&gt;;

	void evaluatePixel()
	{
		float2 pos = outCoord();
		float rc = cos(rotation);
		float rs = sin(rotation);
		float dx = pos.x - tx;
		float dy = pos.y - ty;
		dst = sampleNearest(src, float2(
			tx + rc * dx + rs * dy,
			ty + rc * dy - rs * dx));
	}
}</pre>
<p>Blur pixel bender</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;

kernel BlurFilter
&lt;
	namespace : &quot;sk.yoz&quot;;
	vendor : &quot;Yoz&quot;;
	version : 1;
	description : &quot;Simple blur&quot;;
&gt;
{
	input image4 src;
	output pixel4 dst;

	void evaluatePixel()
	{
		float2 pos = outCoord();

		dst = 1.0 / 9.0 * (
			sampleNearest(src, pos - float2(-1.0, -1.0))
			+ sampleNearest(src, pos - float2(0.0, -1.0))
			+ sampleNearest(src, pos - float2(1.0, -1.0))
			+ sampleNearest(src, pos - float2(-1.0, 0.0))
			+ sampleNearest(src, pos - float2(0.0, 0.0))
			+ sampleNearest(src, pos - float2(1.0, 0.0))
			+ sampleNearest(src, pos - float2(-1.0, 1.0))
			+ sampleNearest(src, pos - float2(0.0, 1.0))
			+ sampleNearest(src, pos - float2(1.0, 1.0)));
	}
}</pre>
<p>Colorize pixel bender</p>
<pre class="brush: xml; title: ; notranslate">&lt;languageVersion : 1.0;&gt;

kernel ColorizeFilter
&lt;
	namespace : &quot;sk.yoz&quot;;
	vendor : &quot;Yoz&quot;;
	version : 1;
	description : &quot;Simple colorize&quot;;
&gt;
{
	input image4 src;
	output pixel4 dst;

	parameter float3 color
	&lt;
		minValue: float3(-1.0, -1.0, -1.0);
		maxValue: float3(1.0, 1.0, 1.0);
		defaultValue: float3(0.0, 0.0, 0.0);
		description: &quot;Color&quot;;
	&gt;;

	void evaluatePixel()
	{
		dst = sampleNearest(src, outCoord());
		dst.r += color.r;
		dst.g += color.g;
		dst.b += color.b;
	}
}</pre>
<p><a href="http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&#038;extid=1536021">Twirl pixel bender effect is available for download here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/02/pixel-bender-disco/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pixel Bender Explorer</title>
		<link>http://blog.yoz.sk/2010/01/pixel-bender-explorer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pixel-bender-explorer</link>
		<comments>http://blog.yoz.sk/2010/01/pixel-bender-explorer/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 17:06:50 +0000</pubDate>
		<dc:creator>Jozef Chúťka</dc:creator>
				<category><![CDATA[ActionScript]]></category>
		<category><![CDATA[Flash / Flex]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[pixel bender]]></category>
		<category><![CDATA[Shader]]></category>
		<category><![CDATA[ShaderExplorer]]></category>
		<category><![CDATA[ShaderFilter]]></category>
		<category><![CDATA[ShaderInput]]></category>
		<category><![CDATA[ShaderLoader]]></category>
		<category><![CDATA[ShaderParameter]]></category>

		<guid isPermaLink="false">http://blog.yoz.sk/?p=867</guid>
		<description><![CDATA[Pixel Bender Explorer is simple application that lets you dynamicly load .pbj files, apply it on image and edit shader values. Application uses two classes. ShaderLoader class loads external .pbj file and casts loaded binary data into Shader object. ShaderExplorer class inspects created Shader object and generates editable form based on Shader parameters. You can [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.yoz.sk/wp-content/uploads/pixelBenderExplorer-188x200.jpg" alt="" title="pixelBenderExplorer" width="188" height="200" class="alignleft size-medium wp-image-868" /></p>
<p>Pixel Bender Explorer is simple application that lets you dynamicly load .pbj files, apply it on image and edit shader values. Application uses two classes. ShaderLoader class loads external .pbj file and casts loaded binary data into Shader object. ShaderExplorer class inspects created Shader object and generates editable form based on Shader parameters. You can load your own external .pbj files (crossdomain.xml required near .pbj file) or feel free to download and use whole .swf application localy.</p>
<p>Application inspired by <a href="http://cookbooks.adobe.com/post_Enumerating_Pixel_Bender_filter_parameters_and_met-16688.html">Enumerating Pixel Bender filter parameters and metadata dynamically in Flash</a> and <a href="http://www.gotoandlearn.com/play?id=84">Introduction to Pixel Bender: Part 2</a> articles.</p>
<p><span id="more-867"></span></p>
<p style="clear:both;">Pixel Bender Explorer application</p>
<p><iframe src="http://blog.yoz.sk/examples/pixelBenderExplorer/" width="620" height="650" style="border:none;"></iframe></p>
<p><a href="http://classes.yoz.sk/sk/yoz/shader/ShaderLoader.as">sk.yoz.shader.ShaderLoader</a></p>
<pre class="brush: as3; title: ; notranslate">package sk.yoz.shader
{
    import flash.display.Shader;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.filters.ShaderFilter;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;

    public class ShaderLoader extends EventDispatcher
    {
        protected var loader:URLLoader = new URLLoader();
        protected var _filters:Array = [];
        protected var _shader:Shader;
        protected var _shaderFilter:ShaderFilter;

        public function ShaderLoader()
        {
            super();

            loader.dataFormat = URLLoaderDataFormat.BINARY;
            loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
            loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }

        [Bindable(event=&quot;filtersChanged&quot;)]
        public function get filters():Array
        {
            return _filters;
        }

        protected function set filters(value:Array):void
        {
            _filters = value;
            dispatchEvent(new Event(&quot;filtersChanged&quot;));
        }

        [Bindable(event=&quot;shaderChanged&quot;)]
        public function get shader():Shader
        {
            return _shader;
        }

        protected function set shader(value:Shader):void
        {
            _shader = value;
            dispatchEvent(new Event(&quot;shaderChanged&quot;));
        }

        [Bindable(event=&quot;shaderFilterChanged&quot;)]
        public function get shaderFilter():ShaderFilter
        {
            return _shaderFilter;
        }

        protected function set shaderFilter(value:ShaderFilter):void
        {
            _shaderFilter = value;
            dispatchEvent(new Event(&quot;shaderFilterChanged&quot;));
        }

        public function load(url:String):void
        {
            loader.load(new URLRequest(url));
        }

        protected function loadCompleteHandler(event:Event):void
        {
            try
            {
                protected::shader = new Shader(event.target.data);
                protected::shaderFilter = new ShaderFilter(public::shader);
                protected::filters = [public::shaderFilter];
            }
            catch(error:Error)
            {
                protected::shader = null;
                protected::shaderFilter = null;
                protected::filters = [];
            }
        }

        protected function ioErrorHandler(event:IOErrorEvent):void
        {
        }
    }
}</pre>
<p><a href="http://classes.yoz.sk/sk/yoz/shader/ShaderExplorer.as">sk.yoz.shader.ShaderExplorer</a></p>
<pre class="brush: as3; title: ; notranslate">package sk.yoz.shader
{
    import flash.display.Shader;
    import flash.display.ShaderInput;
    import flash.display.ShaderParameter;
    import flash.events.Event;
    import flash.filters.ShaderFilter;

    import mx.containers.VBox;
    import mx.controls.HRule;
    import mx.controls.HSlider;
    import mx.events.SliderEvent;
    import mx.controls.Spacer;
    import mx.controls.Text;

    public class ShaderExplorer extends VBox
    {
        protected var _shader:Shader;

        public function ShaderExplorer()
        {
            super();
        }

        public function get shader():Shader
        {
            return _shader;
        }

        public function set shader(value:Shader):void
        {
            _shader = value;
            createControls();
            dispatchEvent(new Event(&quot;shaderFiltersChanged&quot;));
        }

        [Bindable(event=&quot;shaderFiltersChanged&quot;)]
        public function get shaderFilters():Array
        {
            if(!shader)
                return [];
            return [new ShaderFilter(shader)];
        }

        protected function createControls():void
        {
            var spacer:Spacer;

            removeAllChildren();
            createDescriptors();
            spacer = new Spacer();
            spacer.height = 20;
            addChild(spacer);
            createInputs();
            spacer = new Spacer();
            spacer.height = 20;
            addChild(spacer);
            createParameters();
        }

        protected function createDescriptors():void
        {
            var param:String;
            for(param in shader.data)
                if(shader.data[param] is String)
                    add_text(param + &quot;: &quot; + shader.data[param]);
        }

        protected function createInputs():void
        {
            var param:String;
            for(param in shader.data)
                if(shader.data[param] is ShaderInput)
                    add_text(param + &quot;: &quot; + shader.data[param]);
        }

        protected function sliderChangeHandler(event:SliderEvent):void
        {
            if(!event.target.name)
                return;
            var name:String = String(event.target.name).replace(/_[0-9]+$/, '');
            var shaderParameter:ShaderParameter = shader.data[name];
            var values:Array = [];
            var i:uint = 0;
            while(getChildByName(name + &quot;_&quot; + i))
                values.push(HSlider(getChildByName(name + &quot;_&quot; + i++)).value);
            shaderParameter.value = values;
            dispatchEvent(new Event(&quot;shaderFiltersChanged&quot;));
        }

        protected function createParameters():void
        {
            var param:String;
            var shaderParameter:ShaderParameter;
            for(param in shader.data)
            {
                if(!(shader.data[param] is ShaderParameter))
                    continue;

                shaderParameter = shader.data[param] as ShaderParameter;
                try
                {
                    this[&quot;add_&quot; + shaderParameter.type].apply(null, [shaderParameter]);
                }
                catch(error:Error)
                {
                    add_text(&quot;unknown type (&quot; + shaderParameter.type + &quot;)&quot;);
                }
            }
        }

        protected function add_text(text:String):void
        {
            var txt:Text = new Text();
            txt.text = text;
            txt.percentWidth = 100;
            addChild(txt);
        }

        protected function add_slider(name:String, value:Number, minimum:Number,
            maximum:Number, snapInterval:Number = 0):void
        {
            var slider:HSlider = new HSlider();
            slider.name = name;
            slider.minimum = minimum;
            slider.maximum = maximum;
            slider.value = value;
            slider.snapInterval = snapInterval;
            slider.percentWidth = 100;
            slider.addEventListener(SliderEvent.CHANGE, sliderChangeHandler);
            addChild(slider);
        }

        protected function add_float(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0]);
        }

        protected function add_float2(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0]);
            add_slider(p.name + &quot;_1&quot;, p.defaultValue[1], p.minValue[1], p.maxValue[1]);
        }

        protected function add_float3(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0]);
            add_slider(p.name + &quot;_1&quot;, p.defaultValue[1], p.minValue[1], p.maxValue[1]);
            add_slider(p.name + &quot;_2&quot;, p.defaultValue[2], p.minValue[2], p.maxValue[2]);
        }

        protected function add_float4(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0]);
            add_slider(p.name + &quot;_1&quot;, p.defaultValue[1], p.minValue[1], p.maxValue[1]);
            add_slider(p.name + &quot;_2&quot;, p.defaultValue[2], p.minValue[2], p.maxValue[2]);
            add_slider(p.name + &quot;_3&quot;, p.defaultValue[3], p.minValue[3], p.maxValue[3]);
        }

        protected function add_int(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0] ,1);
        }

        protected function add_int2(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0] ,1);
            add_slider(p.name + &quot;_1&quot;, p.defaultValue[1], p.minValue[1], p.maxValue[1] ,1);
        }

        protected function add_int3(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0] ,1);
            add_slider(p.name + &quot;_1&quot;, p.defaultValue[1], p.minValue[1], p.maxValue[1] ,1);
            add_slider(p.name + &quot;_2&quot;, p.defaultValue[2], p.minValue[2], p.maxValue[2] ,1);
        }

        protected function add_int4(p:ShaderParameter):void
        {
            add_text(p.name + &quot; (&quot; + p.type + &quot;)&quot;);
            add_slider(p.name + &quot;_0&quot;, p.defaultValue[0], p.minValue[0], p.maxValue[0] ,1);
            add_slider(p.name + &quot;_1&quot;, p.defaultValue[1], p.minValue[1], p.maxValue[1] ,1);
            add_slider(p.name + &quot;_2&quot;, p.defaultValue[2], p.minValue[2], p.maxValue[2] ,1);
            add_slider(p.name + &quot;_3&quot;, p.defaultValue[3], p.minValue[3], p.maxValue[3], 1);
        }

        // TODO, matrix, matrix4x4...
    }
}</pre>
<p>Pixel Bender Explorer application:</p>
<pre class="brush: xml; title: ; notranslate">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Application xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot;
    layout=&quot;vertical&quot; xmlns:shader=&quot;sk.yoz.shader.*&quot;
    creationComplete=&quot;shadersService.send();&quot; width=&quot;620&quot; height=&quot;650&quot;
    paddingTop=&quot;10&quot; paddingRight=&quot;10&quot; paddingBottom=&quot;10&quot; paddingLeft=&quot;10&quot;
    backgroundGradientColors=&quot;{[0xffffff, 0xffffff]}&quot;&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
    import sk.yoz.shader.ShaderLoader;

    [Embed(source=&quot;../assets/img.jpg&quot;)]
    public static const IMAGE_CLASS:Class;

    [Bindable]
    private var loader:ShaderLoader = new ShaderLoader();
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:HTTPService id=&quot;shadersService&quot; url=&quot;shaders.xml&quot; /&gt;
&lt;mx:HBox width=&quot;100%&quot;&gt;
    &lt;mx:CheckBox id=&quot;useFilter&quot; selected=&quot;true&quot;/&gt;
    &lt;mx:ComboBox id=&quot;combo&quot; editable=&quot;true&quot;
        close=&quot;{loader.load(String(combo.value))}&quot;
        enter=&quot;{loader.load(String(combo.value))}&quot;
        dataProvider=&quot;{shadersService.lastResult.data.shader}&quot; width=&quot;510&quot;/&gt;
    &lt;mx:Button label=&quot;Load&quot; click=&quot;{loader.load(String(combo.value))}&quot;/&gt;
&lt;/mx:HBox&gt;
&lt;mx:HBox width=&quot;100%&quot; height=&quot;100%&quot;&gt;
    &lt;mx:Image source=&quot;{IMAGE_CLASS}&quot;
        filters=&quot;{useFilter.selected ? explorer.shaderFilters : []}&quot;/&gt;
    &lt;mx:Canvas width=&quot;100%&quot; height=&quot;100%&quot; verticalScrollPolicy=&quot;auto&quot;&gt;
        &lt;shader:ShaderExplorer id=&quot;explorer&quot; shader=&quot;{loader.shader}&quot;
            height=&quot;100%&quot; /&gt;
    &lt;/mx:Canvas&gt;
&lt;/mx:HBox&gt;
&lt;/mx:Application&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.yoz.sk/2010/01/pixel-bender-explorer/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

