<?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>Salt Games</title>
	<atom:link href="http://www.saltgames.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.saltgames.com</link>
	<description>Games and Experiments with Flash</description>
	<lastBuildDate>Tue, 08 Jan 2013 02:10:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Making a Median Filter for Stage3d</title>
		<link>http://www.saltgames.com/2012/making-median-filter-stage3d/</link>
		<comments>http://www.saltgames.com/2012/making-median-filter-stage3d/#comments</comments>
		<pubDate>Tue, 29 May 2012 17:44:17 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Stage3D]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=651</guid>
		<description><![CDATA[Stepping through the process of creating a realtime median filter shader for Stage3d that pushes affectionately against the platform&#8217;s limits. Goal Before setting out to make any shader, it&#8217;s a good idea to have an idea of what you&#8217;re aiming at. In &#8230; <a href="http://www.saltgames.com/2012/making-median-filter-stage3d/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.saltgames.com/2012/making-median-filter-stage3d/"><img class="aligncenter size-full wp-image-657" title="median-filter-preview" src="http://www.saltgames.com/wp-content/uploads/2012/05/median-filter-preview.png" alt="" width="400" height="150" /></a></p>
<p style="text-align: left;">Stepping through the process of creating a realtime median filter shader for Stage3d that pushes affectionately against the platform&#8217;s limits.</p>
<p style="text-align: left;"><span id="more-651"></span></p>
<h1>Goal</h1>
<p>Before setting out to make any shader, it&#8217;s a good idea to have an idea of what you&#8217;re aiming at. In this case we&#8217;re in luck as a <a href="http://en.wikipedia.org/wiki/Median_filter" target="_blank">median filter</a> is fairly well defined. It&#8217;s a convolution filter (so each pixel has its state determined by several neighbouring pixels) that calculates the median value (place all the values in order, and take the middle one) of the surrounding pixels. In our case we&#8217;ll be making a median filter with a 3&#215;3 area as we expect our noise to be mostly single pixels that have been altered. Also in our case we&#8217;ll be filtering on a per-channel basis, so finding the median red value, median green value, and median blue value rather than finding the colour value with the median brightness &#8211; or whatever other measurement you might like to use.</p>
<p>Median filters are useful in image processing for removal of small scale noise while maintaining the edges of the original image. They&#8217;re used very often in digital cameras to remove the dusting of noise that appears when shooting in low light, using a low cost sensor, or just when hit by interference.</p>
<div id="attachment_658" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.saltgames.com/wp-content/uploads/2012/05/plant-noise-filtered-comparison.png"><img class="size-medium wp-image-658 " title="Before and after comparison" src="http://www.saltgames.com/wp-content/uploads/2012/05/plant-noise-filtered-comparison-300x210.png" alt="" width="300" height="210" /></a><p class="wp-caption-text">A composite of an image afflicted by noise before and after being put through a median filter. Click for full size.</p></div>
<h1> A First Draft</h1>
<p>Let&#8217;s get straight in to designing our shader. I&#8217;ll mostly be writing code in <a title="Haxe documentation for HxSL" href="http://haxe.org/manual/hxsl" target="_blank">Haxe&#8217;s HxSL</a>, but for the very start let&#8217;s have some pseudo-code for a simple median filter.</p>
<pre>declare an array of float3, length 9, named v

for x in -1 to +1 { 
  for y in -1 to +1 {
    v[x + y*3] = sample texture at (current location + (x,y))
  }
}

sort each channel of v by value
return v[4]</pre>
<p>Two implementation issues appear when it comes to writing that as an actual shader.</p>
<p>Firstly <strong>how do we sort values in a shader?</strong> Shaders have no support for looping or conditional execution, so there can be no straight forward &#8220;if a is larger than b then &#8230;&#8221; or &#8220;repeat until in order&#8221;. It actually ends up being quite easy to do without such constructs; it just takes a little change of thinking.</p>
<p>Secondly a <strong>lack of register space</strong>. Stage3d&#8217;s shaders only have write-access to 8 temporary registers, which is notable for being one less than the 9 required to store all the values from the 3&#215;3 area sample area.</p>
<h1>Sorting in a Shader</h1>
<p>As every young computer scientist knows, bubble sort is the poor relation of the sorting family. But let&#8217;s use it in our shader anyway.</p>
<p>The advantage for us is that bubble sort is delightfully simple. Just advance through the array, compare each value to its neighbour and swap them if they&#8217;re in the wrong order. Do that enough times and you end up with the array in order. The question then is how do we perform the swapping of unordered neighbours?</p>
<p>Instead of thinking of things swapping positions, think of how you want the data to be after the operation.</p>
<pre>// after sorting, v0 should have the smaller value, v1 the larger
v0 = min(v0, v1);
v1 = max(v0, v1); // problem!
// because we just wrote to v0 it might have changed value,
// so the second line doesn't do what we expect.
// let's keep a copy of v0 safe in a temporary variable

temp = v0;
v0 = min(temp, v1);
v1 = max(temp, v1);</pre>
<p>That has placed two values in the correct order. Let&#8217;s now extend that to sort three values.</p>
<pre>var v0 = 6;
var v1 = 3;
var v2 = 1;
var temp;

temp = v0;
v0 = min(temp, v1);
v1 = max(temp, v1);

temp = v1;
v1 = min(temp, v2);
v2 = max(temp, v2);

// 1st iteration of bubble sort is complete
// we now know that v2 holds the maximum value
// but v0 and v1 might still be in the wrong order

temp = v0;
v0 = min(temp, v1);
v1 = max(temp, v1);

// 2nd iteration of bubble sort is complete
// we now know that v0, v1 and v2 hold values
// in ascending order</pre>
<p>It&#8217;s old news to our young computer scientist, but each iteration of bubble sort guarantees that the final value is correctly placed. That means we don&#8217;t need to touch it on future iterations (so future iterations are shorter), and it means that for an array of <strong>n</strong> elements every element is certain to be in its correct place after <strong>n-1 </strong>iterations. As we&#8217;re doing all this to find the median value, we actually don&#8217;t have to do the full n-1 iterations as we only need to be sure that the middle value is correctly placed in order to read off the median.</p>
<h1>Taking into Account the Three Channels</h1>
<p>At this point it&#8217;s important to remember that our shader is dealing with Float3 variables (that is, each variable has an x, y, and z component representing the three colour channels) rather than the Float variables we&#8217;ve used in the examples so far. AGAL&#8217;s <strong>min </strong>and<strong> max </strong>operations work on each channel separately, so we are performing our sort on a per channel basis. This has the result that we might end up with our &#8220;median colour&#8221; being a colour that isn&#8217;t actually present in the source image &#8211; it may be built up from the red of one colour, the green of another and blue of a third. In my brief experiments it seems that this per-channel sorting actually produces better results, but it&#8217;s worth showing how to adapt the sort so that it maintains colours.</p>
<p>If we&#8217;re not going to sort each channel separately on its value, we&#8217;ll need some other metric by which to sort. For simplicity we&#8217;ll sort on the sum of the three channels, but you could calculate the colour&#8217;s hue, saturation, value, or whatever you like that can be expressed as a single number. Stage3d&#8217;s registers all consist of four components, and our colour values are only using three, so let&#8217;s use the fourth to store the value we&#8217;ll sort them by.</p>
<pre>// put value to sort by in .w component
v0.w = v0.x + v0.y + v0.z;
v1.w = v1.x + v1.y + v1.z;
v2.w = v2.x + v2.y + v2.z;</pre>
<p>Rather than using <strong>min</strong> and <strong>max</strong> to perform the sorting, we&#8217;ll use <strong>lt</strong> (less than) and <strong>gte</strong> (greater than or equal). These operations return 1 if they are true, and 0 otherwise. Note that like most operations these are performed on all components of a variable, and as we want just a single value we give them just a single component &#8211; the one by which we want our values sorted.</p>
<pre>firstIsSmaller = lt(v0.w, v1.w);
secondIsSmaller = gte(v0.w, v1.w);</pre>
<p>As we know that these are always either 0 or 1 and that when one is 1 the other is 0, we can construct the desired new value of v0 and v1.</p>
<pre>temp = v0;
v0 = firstIsSmaller * v0 + secondIsSmaller * v1;
v1 = secondIsSmaller * v0 + firstIsSmaller * v1;</pre>
<p>Using this technique you can do all kinds of conditional-based stuff in shaders, despite the lack of an <strong>if</strong> statement.</p>
<h1>Squeezing into a Size Eight</h1>
<p>Being able to sort a set of variables isn&#8217;t much use if we can&#8217;t actually store them in the first place, and with just 8 temporary registers available to us things are looking pretty tight when we&#8217;re sampling 9 locations, and need a temporary variable to perform the sort.</p>
<blockquote><p>As I wrote this section I realised it would be possible to fit all 9 Float3s and the one temporary Float3 used during sorting in the 8 available Float4 registers. It would require several of the variables to be split between multiple registers, which would make your code joyfully unreadable but it would work. But if you&#8217;re using Float4s for each sampled location then that of course could not fit in 8 registers.</p></blockquote>
<p>Thankfully we can (I think!) arrive at the median by analysing subsets of the data. We need to find the median of 9 values, but are unable to store all 9 in memory at any one time. Instead we shall store the first 3 values, find and store their median. We do the same for the next subset of 3 values, and then the final 3. By finding the median of those three medians we should arrive at the median for the whole set.</p>
<p>I&#8217;m fairly sure that this is mathematically true so long as the subsets are all of equal size, all have an odd number of members, and there&#8217;s an odd number of subsets. It does seem to give the expected results, and should give something close to the true median if those requirements are not met.</p>
<pre>var median0:Float3;
var median1:Float3;
var median2:Float3;

var textureUV:Float2;

var v0:Float3;
var v1:Float3;
var v2:Float3;
var temp:Float3;

// sample locations (-1,-1) (0,-1) (+1,-1) into v0 v1 v2
// bubble sort on v0 v1 v2
median0 = v1;

// sample locations (-1,0) (0,0) (+1,0) into v0 v1 v2
// bubble sort on v0 v1 v2
median1 = v1;

// sample locations (-1,+1) (0,+1), (+1,+1) into v0 v1 v2
// bubble sort on v0 v1 v2
median2 = v1;

// bubble sort on median0 median1 median2
return median1;</pre>
<p>Even with that we&#8217;re flying pretty close to the register limit. Further savings can be made by reusing registers for multiple purposes. For instance median2 is only used after v0, v1 and v2 have stopped being used, so it can share a register with one of those. Similarly the variable used to locate texture sampling is never in use at the same time as the temp variable needed for bubble sorting, so they can share a register too.</p>
<h1>Implementation Details</h1>
<p>I had planned to write a section on manually converting this code into AGAL, but I think this article is long enough already. It&#8217;s a fairly robotic process anyway, just make sure you keep good notes, and keep reminding yourself to switch to <a href="http://haxe.org/" target="_blank">Haxe </a>as soon as you can.</p>
<p>Speaking of Haxe and HxSL, something I learned writing this shader is that &#8230;</p>
<pre>median0 = v1;</pre>
<p>&#8230; is not the same as &#8230;</p>
<pre>median0 = v1 + [0,0,0];</pre>
<p>If you use the first then median0 seems to change when you alter v1. Presumably this is part of an effort to save register space (after all why keep two registers that have identical contents?) but the behaviour is a little unexpected.</p>
<h1>Results</h1>
<p>My motivation for writing a median filter shader was to produce some simple realtime painterly effects. It turns out that my 3&#215;3 sample area is not enough to produce anything particularly noticeable. Which shouldn&#8217;t be surprising as the strength of the median filter in image processing is that it preserves the image while removing noise.</p>
<p>However after some simple modifications I&#8217;ve made two shaders that sample at 1&#215;9 and  9&#215;1. By applying both in turn it effectively finds the median from a 9&#215;9 cross shaped sample area. This new shader is of limited use in noise removal, but it does produce some quite pleasing results, all running very comfortably at 60fps.</p>
<div id="attachment_654" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.saltgames.com/wp-content/uploads/2012/05/after-two-passes-9x9-cross-per-channel-median.png"><img class="size-medium wp-image-654" title="Painterly effect on a photo thanks to median filtering" src="http://www.saltgames.com/wp-content/uploads/2012/05/after-two-passes-9x9-cross-per-channel-median-300x210.png" alt="" width="300" height="210" /></a><p class="wp-caption-text">Photo after passing through a larger scale cross-sample median filter. Click to enlarge.</p></div>
<p>&nbsp;</p>
<div id="attachment_662" class="wp-caption aligncenter" style="width: 224px"><a href="http://www.saltgames.com/wp-content/uploads/2012/05/game-before-and-after.png"><img class="size-medium wp-image-662" title="Painterly effect in-game from a median filter" src="http://www.saltgames.com/wp-content/uploads/2012/05/game-before-and-after-214x300.png" alt="" width="214" height="300" /></a><p class="wp-caption-text">Comparison showing the effect of the enlarged median filter on the flat-shaded landscape of a game. Click to enlarge.</p></div>
<h1> The full fragment shader for the 3&#215;3 median filter, in HxSL:</h1>
<pre>function fragment(texture:Texture, sizeOfTexel:Float2)
{
 // due to limited availability of temporary variables
 // we cannot hold samples of all pixels in a 3x3 area.
 // instead we'll sample the first row, find its median,
 // sample the second row, find its median,
 // sample the third row, find its median,
 // then find the median of those three medians

 var median0:Float3;
 var median1:Float3;

 // fill v[n] with sampled values
 var localUV:Float2;
 localUV.y = tuv.y - sizeOfTexel.y;
 localUV.x = tuv.x - sizeOfTexel.x;
 var v0:Float4 = get(texture, localUV, clamp, nearest);
 localUV.x = tuv.x + 0;
 var v1:Float4 = get(texture, localUV, clamp, nearest);
 localUV.x = tuv.x + sizeOfTexel.x;
 var v2:Float4 = get(texture, localUV, clamp, nearest);

 var t:Float3;

 t = v0.xyz + [0, 0, 0];
 v0.xyz = min(t, v1.xyz);
 v1.xyz = max(t, v1.xyz);

 t = v1.xyz + [0, 0, 0];
 v1.xyz = min(t, v2.xyz);
 v2.xyz = max(t, v2.xyz);

 // after first iteration of bubble sort v2 is certain to be the maximum value
 // but median could be either v0 or v1
 t = v0.xyz + [0, 0, 0];
 v0.xyz = min(t, v1.xyz);
 v1.xyz = max(t, v1.xyz);

 // after a second iteration of bubble sort
 // v1 is also certain to have correct value
 // so v1 contains the median for this set of three values.
 // incidentally, v0 also has the correct minimum value.
 median0 = v1.xyz + [0, 0, 0];

 // -- now do all of that again to find median of second row --
 localUV.x = tuv.x - sizeOfTexel.x;
 v0 = get(texture, localUV, clamp, nearest);
 localUV.x = tuv.x + 0;
 v1 = get(texture, localUV, clamp, nearest);
 localUV.x = tuv.x + sizeOfTexel.x;
 v2 = get(texture, localUV, clamp, nearest);

 t = v0.xyz + [0, 0, 0];
 v0.xyz = min(t, v1.xyz);
 v1.xyz = max(t, v1.xyz);

 t = v1.xyz + [0, 0, 0];
 v1.xyz = min(t, v2.xyz);
 v2.xyz = max(t, v2.xyz);

 t = v0.xyz + [0, 0, 0];
 v0.xyz = min(t, v1.xyz);
 v1.xyz = max(t, v1.xyz);

 median1 = v1.xyz + [0, 0, 0];

 // -- and again for third row --
 localUV.x = tuv.x - sizeOfTexel.x;
 v0 = get(texture, localUV, clamp, nearest);
 localUV.x = tuv.x + 0;
 v1 = get(texture, localUV, clamp, nearest);
 localUV.x = tuv.x + sizeOfTexel.x;
 v2 = get(texture, localUV, clamp, nearest);

 t = v0.xyz + [0, 0, 0];
 v0.xyz = min(t, v1.xyz);
 v1.xyz = max(t, v1.xyz);

 t = v1.xyz + [0, 0, 0];
 v1.xyz = min(t, v2.xyz);
 v2.xyz = max(t, v2.xyz);

 t = v0.xyz + [0, 0, 0];
 v0.xyz = min(t, v1.xyz);
 v1.xyz = max(t, v1.xyz);

 //median2 = v1.xyz + [0, 0, 0];
 // just directly use v1 instead of median2

 // we now have a median for each row
 // bubble sort on them to find the median of medians
 t = median0.xyz + [0, 0, 0];
 median0 = min(t, median1.xyz);
 median1 = max(t, median1.xyz);

 t = median1.xyz + [0, 0, 0];
 median1 = min(t, v1.xyz);
 v2.xyz = max(t, v1.xyz);

 t = median0.xyz + [0, 0, 0];
 median0 = min(t, median1);
 median1 = max(t, median1);

 out = [median1.x, median1.y, median1.z, 1];
}</pre>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2012/making-median-filter-stage3d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stage3D Resource Links</title>
		<link>http://www.saltgames.com/2012/stage3d-resource-links/</link>
		<comments>http://www.saltgames.com/2012/stage3d-resource-links/#comments</comments>
		<pubDate>Fri, 16 Mar 2012 19:42:24 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Stage3D]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=637</guid>
		<description><![CDATA[A collection of the most useful Stage3D links I&#8217;ve come across. This link will give you all the posts on my site about Stage3D. Getting the inevitable self-advertising out the way. How Stage3D works Working with 3D cameras What is &#8230; <a href="http://www.saltgames.com/2012/stage3d-resource-links/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.saltgames.com/2012/stage3d-resource-links/stage3d-links/" rel="attachment wp-att-638"><img class="aligncenter size-full wp-image-638" title="stage3d-links" src="http://www.saltgames.com/wp-content/uploads/2012/03/stage3d-links.jpg" alt="" width="400" height="150" /></a></p>
<p>A collection of the most useful Stage3D links I&#8217;ve come across.</p>
<p><span id="more-637"></span></p>
<p><a href="http://www.saltgames.com/category/stage3d/">This link will give you all the posts on my site about Stage3D.</a><br />
Getting the inevitable self-advertising out the way.</p>
<p><a href="http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html">How Stage3D works</a><br />
<a href="http://www.adobe.com/devnet/flashplayer/articles/3d-cameras.html">Working with 3D cameras</a><br />
<a href="http://www.adobe.com/devnet/flashplayer/articles/what-is-agal.html">What is AGAL</a><br />
<a href="http://www.adobe.com/devnet/flashplayer/articles/vertex-fragment-shaders.html">Vertex and Fragment Shaders</a><a href="http://www.adobe.com/devnet/flashplayer/articles/hello-triangle.html"><br />
Hello Triangle</a><br />
<a href="http://www.adobe.com/devnet/flashplayer/articles/perspective-projection.html">Perspective Projection</a><br />
A series of quality and thorough tutorials on the fundamentals of working with Stage3D from Macro Scabia. I dropped my plans to write some very similar tutorials when I found these as they cover everything I had planned to.</p>
<p><a href="http://www.bytearray.org/">Byte Array</a><br />
The blog of Thibault Imbert, a product manager for the Adobe Flash Runtime. A good source of information on the most recent developments, which has mostly been Stage3D related of late. Browse through and you&#8217;ll quickly find important and practical details about the Stage3D technology.</p>
<p><a href="http://blog.bwhiting.co.uk/">Flashing in Public</a><br />
Ben Whiting&#8217;s blog on Flash development, with a healthy emphasis on Stage3D. Really rather nice examples of the technology.</p>
<p><a href="http://www.mcfunkypants.com/category/molehill/">McFunkyPants</a><br />
The blog of Chris Kaitila, who has written a [the?] <a href="http://www.mcfunkypants.com/books/">book on Stage3D</a>, which follows through a practical example of creating a 3D game from scratch.</p>
<p><a href="http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/flash/display3D/Context3D.html">Official Documentation</a><br />
Don&#8217;t forget there actually is documentation for Stage3D! For some reason most the contents of the standard documentation for Stage3D features is currently blanked out, but this link will take you to the beta version which is intact.</p>
<p>Finally a note that back when Stage3D was younger it was known as Molehill, so you may see references to that in some resources. Very little has changed with regards how everything works since then so you should be safe following older tutorials. The only difference in the API I know of is that Molehill used slightly different syntax for setting up the size of a Context3d&#8217;s back buffer. Switching to the new version is no work at all, but it does mean older examples you find might simply fail to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2012/stage3d-resource-links/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Particles Redux</title>
		<link>http://www.saltgames.com/2012/particles-redux/</link>
		<comments>http://www.saltgames.com/2012/particles-redux/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 15:52:33 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Stage3D]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=624</guid>
		<description><![CDATA[In the far distant past of last October I showed a little Stage3D accelerated particle system. Displaying a fantastic rate of progress I&#8217;ve made the same thing again, but this time it&#8217;s better, and uses HaXe. 
<p>Select a number of particles to create (50,000 or 100,000 is liable to take a while to load up and might even exhaust Flash&#8217;s available memory on lower spec machines). Once the particles have been generated you can drag with the left mouse button to change your view.</p>
<p>In terms of feature difference to the old version all that&#8217;s new is that any number of particles can be created (oh, also this version is in 3D). As there are limits to how many vertices and indices you can load into Stage3D for a single draw call, the larger particle counts make use of a simple batching system I&#8217;ve been building to spread themselves between multiple draw calls. My batch manager is still a little slow, and this example rather foolishly adds new particles one at a time, so you have to wait a little while it constructs the batches at the start.</p>
<blockquote><p><strong>15th April Update:<br />
</strong>I&#8217;ve since rewritten how I handle memory in my nascent 3D framework to use the soon to be a &#8220;premium&#8221; feature of direct memory access. End result is that time to generate 100,000 particles went from 30 seconds to 5. To celebrate I added an option to generate 500,000 particles.</p>
<p>&nbsp;</p>
<p>I should probably also mention that if you really did want huge numbers of particles active at once in a game you can save substantial memory use by creating just one batch&#8217;s worth of vertex data and drawing it several times each frame with varied vertex constants. In this example I&#8217;m quite deliberately wasting memory to test out my framework.</p>
<p>&nbsp;</p></blockquote>
<p>From a development point of view the big difference is that this is built using HaXe rather than AS3. Explaining <a href="http://haxe.org">HaXe </a>is outside the scope of this little post, but it&#8217;s really pretty great and you should check it out. Its major feature is the ability to compile to a variety of languages, but for now I&#8217;m just using it as a straight up replacement for AS3 in Flash development as I enjoy the additional features of the language.</p>
<p>For shader work HaXe really stands out thanks to <a href="http://haxe.org/manual/hxsl?lang=en">HxSL</a>, which is a quite simple but very effective high level shader language, similar to GLSL for OpenGL or HLSL for DirectX. This means that I can write Stage3D shaders without directly using AGAL.</p>
<p>My HxSL shaders are still converted into AGAL-equivalent bytecode when the project is compiled so I&#8217;m still limited by the same restrictions as AGAL itself is: no loops (although HxSL can &#8216;unwind&#8217; for loops between constant values) and a limit of 200 commands per shader being the main ones. But writing and especially maintaining the shader is vastly easier.</p>
<div id="attachment_628" class="wp-caption aligncenter" style="width: 280px"><a href="http://www.saltgames.com/wp-content/uploads/2012/03/agal-shader-code.png"><img class="size-medium wp-image-628" title="AGAL Shader Code" src="http://www.saltgames.com/wp-content/uploads/2012/03/agal-shader-code-270x300.png" alt="" width="270" height="300" /></a><p class="wp-caption-text">The AGAL code for the original bouncing particles shader. Click to enlarge.</p></div>
<p>&nbsp;</p>
<div id="attachment_629" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.saltgames.com/wp-content/uploads/2012/03/hxsl-shader-code.png"><img class="size-medium wp-image-629" title="HxSL Code" src="http://www.saltgames.com/wp-content/uploads/2012/03/hxsl-shader-code-300x159.png" alt="" width="300" height="159" /></a><p class="wp-caption-text">The HxSL code for the new bouncing particles shader. Click to enlarge.</p></div>
<p>The HxSL version actually does slightly more, as it applies a simple billboarding effect to the particles so that they&#8217;re always facing the camera. Notice how the HxSL version is at least as readable as the AGAL even without any comments at all and how the comments for the AGAL dwarf the actual code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2012/particles-redux/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Dealing With AGAL Registers</title>
		<link>http://www.saltgames.com/2011/agal-registers/</link>
		<comments>http://www.saltgames.com/2011/agal-registers/#comments</comments>
		<pubDate>Wed, 12 Oct 2011 14:23:02 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Stage3D]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=529</guid>
		<description><![CDATA[A thorough tutorial on the use of registers for AGAL shaders. How to go about setting their values and accessing them in the shader. This tutorial is weighted towards theory rather than the practical writing of code. You might find &#8230; <a href="http://www.saltgames.com/2011/agal-registers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.saltgames.com/2011/agal-registers/"><img class="size-full wp-image-591 aligncenter" title="stage3d-illustrations-preview" src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-illustrations-preview.png" alt="" width="400" height="150" /></a></p>
<p>A thorough tutorial on the use of registers for AGAL shaders. How to go about setting their values and accessing them in the shader.</p>
<p><span id="more-529"></span></p>
<p>This tutorial is weighted towards theory rather than the practical writing of code. You might find it beneficial to refer to my<a title="Simple Annotated Example of Stage3D" href="http://www.saltgames.com/2011/simple-annotated-stage3d/"> simple rendering example</a> to see how this all gets applied.</p>
<h1>Registers:</h1>
<p>Each register consists of four components, which are floating point values. A particular component is accessed by the notation [registerName].[componentLetter], where componentLetter is x, y, z, or w. For example <strong>va0.x</strong> is the first component of the first vertex attribute register. For a listing of the available registers, please see my <a title="Stage3D Shader Cheatsheet" href="http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/">AGAL reference page.</a></p>
<h1><span class="Apple-style-span" style="color: #000000;">Vertex Buffer:</span></h1>
<p>The vertex buffer is how you pass per-vertex data into your vertex shader, where it will appear in the <strong>va</strong> (vertex attribute) registers. Usually this will include the position of that vertex in the world and some data used to colour it &#8211; either by passing in a colour for the vertex, uv coordinates for texture mapping, or something more complex. Keep in mind that the vertex buffer is just a series of floating point numbers which you can use for anything you like in your shader.</p>
<p>To deal with the vertex buffer you first create a VertexBuffer3D object by using the function <em>context3D.createVertexBuffer</em> (you cannot just instantiate it yourself with<em> new VertexBuffer3D()</em>.)  This object will store the values until you&#8217;re ready to upload them into registers and have a shader use them.</p>
<p>Imagine the VertexBuffer3D object as a table. When you create it with <em>context3D.createVertexBuffer </em>you specify the number of vertices (the number of rows in the table) and the number of data32 per vertex (the number of columns in the table). In this illustration I&#8217;ve labelled each column with what I plan to use the values for, but remember they&#8217;re just a series of meaningless numbers as far as Flash is concerned.</p>
<p><img class="aligncenter size-full wp-image-584" title="VertexBuffer3D as a table" src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-illustration-1.png" alt="" width="649" height="610" /></p>
<p>You upload data into the VertexBuffer3D table using <em>vertex3D.uploadFromVector</em>, where you supply:</p>
<ul>
<li><em>data</em> - A Vector.&lt;Number&gt; of the values you&#8217;re going to upload. Must be a whole number of rows&#8217; worth of data.</li>
<li><em>startVertex</em> - The row in the vertex3D table at which to start writing.</li>
<li><em>numVertices</em> - The number of rows of data to copy.</li>
</ul>
<p>In this illustration see how the startVertex determines where in the VertexBuffer3D object our Vector of numbers will be placed. If numVertices was set to 1 then only one row of the table would have been filled.</p>
<p><img class="aligncenter size-full wp-image-585" title="Uploading a vector of numbers into a VertexBuffer3D object" src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-illustration-2.png" alt="" width="1186" height="625" /></p>
<p>You set the <strong>va</strong> registers using <em>context3D.setVertexBufferAt</em>. When doing so you specify:</p>
<ul>
<li><em>index</em> - Which <strong>va</strong> register you want to upload into, e.g. 0 for <strong>va0</strong>.</li>
<li><em>buffer</em> - The vertexBuffer3D object to use.</li>
<li><em>bufferOffset</em> - Which column in the vertexBuffer3D table to start from when reading in data</li>
<li><em>format</em> - How many columns of the table to read in, from FLOAT_1 for one to FLOAT_4 for four. Alternatively read in a single column but interpret it as four individual bytes instead of a single float.</li>
</ul>
<p>As seen here, bufferOffset (0 in this case) and format (FLOAT_2) determine which columns of the VertexBuffer3D object to copy. Index (0 for the <strong>va0 </strong>register) determine which register those values should be placed in.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-586" title="Setting vertex attribute register va0 from a VertexBuffer3D object" src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-illustration-3.png" alt="" width="790" height="586" /></p>
<p style="text-align: left;">In this second example bufferOffset is 2, format is FLOAT_4, and index is 1. This results in copying the four columns shown from the VertexBuffer3D and using them to fill the <strong>va1</strong> register.</p>
<p style="text-align: center;"><img class="size-full wp-image-587" title="Setting vertex attribute register va1 from a VertexBuffer3D object" src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-illustration-4.png" alt="" width="951" height="587" /></p>
<p>Keep in mind that when performing the setVertexBufferAt operation you are setting the registers for as many vertices as you have rows in the vertexBuffer3D object you&#8217;re using.</p>
<p><strong>Note!</strong> Rendering will fail if you have set values for registers that are then not used by your shader. Similarly it will fail if your shader tries to access a <strong>va</strong> register that hasn&#8217;t had data uploaded to it. Make sure you have <em>context3D.enableErrorChecking</em> set to true so you receive these error messages.</p>
<h1><span class="Apple-style-span" style="color: #000000;">Vertex and Fragment Constants:</span></h1>
<p>The other way to get numbers into a shader is through the vertex constant and fragment constant registers. These are accessed in the shader at <strong>vc0</strong> to <strong>vc127</strong> and <strong>fc0</strong> to <strong>fc27</strong>. Keep in mind that only the vertex shader can access <strong>vc</strong> registers and only the fragment shader can access <strong>fc</strong> registers. Unlike the <strong>va</strong> and <strong>v</strong> (see below for details on these Varying registers) registers, the contents of <strong>vc</strong> and <strong>fc</strong> are the same for all vertices and all fragments.</p>
<p>To set values in the constant registers you use the <em>context.setProgramConstantsFromVector</em> or <em>context.setProgramConstantsFromMatrix </em>functions.</p>
<p>When using <em>.setProgramConstantsFromVector</em> you supply:</p>
<ul>
<li><em>programType</em> &#8211; Must be either Context3DProgramType.FRAGMENT or Context3DProgramType.VERTEX, use this to indicate if you want to set a <strong>fc</strong> or a <strong>vc</strong><strong> register.</strong></li>
<li><em>firstRegister</em> - Which register to set, or if you supply enough data for multiple registers which is the first you&#8217;d like to set. For example use 0 to set <strong>fc0</strong> or <strong>vc0</strong>.</li>
<li><em>data</em> - The Vector.&lt;Number&gt; of values you want to upload. This must contain a multiple of 4 values so as to fill the x, y, z and w components of however many registers you&#8217;re writing to. Even if you only actually need to upload a single number, you are not allowed to have only some components of a constant register set.</li>
<li><em>numRegisters</em> - Optional. If your <em>data</em> has enough for 3 registers but you only want to upload into 1 then you can do that here.</li>
</ul>
<p>When using .<em>setProgramConstantsFromMatrix</em> you supply:</p>
<ul>
<li><em>programType</em> - Must be either Context3DProgramType.FRAGMENT or Context3DProgramType.VERTEX, use this to indicate if you want to set  <strong>fc</strong> or  <strong>vc </strong>registers.</li>
<li><em>firstRegister</em> - The first register to set with the data from your matrix.</li>
<li><em>matrix</em> - The Matrix3D object you want to upload into constant registers. Matrix3Ds are always 4&#215;4 matrices so <strong>four</strong> registers are needed to store their contents.<br />
If you specify the <em>firstRegister</em> as 2 and <em>programType</em> as Context3DProgramType.FRAGMENT, then <strong>fc2 fc3 fc4</strong> and <strong>fc5</strong> will be written to.</li>
<li><em>transposedMatrix</em> - If set to false the matrix is written into the registers with the first register being the first <em>row</em> of the matrix. If set to true the matrix is written in transposed order, meaning the first register stores the first <em>column</em> of the matrix.</li>
</ul>
<p>Unlike vertex attributes, setting a constant and then not using it seems to pass without error. Obviously a shader trying to access a constant that you haven&#8217;t set will fail.</p>
<h1>Varying Registers</h1>
<p>Varying registers (<strong>v0 </strong>to <strong>v7</strong>) allow per-vertex data to be indirectly used in your fragment shader. To access a varying register within a fragment shader your vertex shader must be feeding it values by including an operation that writes data to one of the <strong>v</strong> registers.</p>
<p>Each triangle that is drawn will of course have three vertices, each of which provide a value to a particular <strong>v</strong> register. Every fragment contained within that triangle will have <strong>its</strong> corresponding <strong>v</strong> register contain a value that has been interpolated between that of the three vertices in that triangle.</p>
<p>In this illustration we look at a single register component as it is interpolated between the three vertices of a triangle. The image is shaded to indicate what value <strong>v0.x</strong> has at each point on the triangle. The value increases at positions closer to the vertex which has it set to 1.</p>
<p><img class="aligncenter size-full wp-image-588" title="A fragment's Varying register value being derived from the values in the Varying registers of the vertices making up its host triangle." src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-illustration-5.png" alt="" width="373" height="240" /></p>
<h1>Using Registers Within a Shader</h1>
<p>Now that we have assigned values to the various registers we can deal with actually using them in a shader. To do anything in a shader you must use operations, which you can find outlined on my<a title="Stage3D Shader Cheatsheet" href="http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/"> quick reference page</a>.</p>
<p>Here we will deal with how to use registers in general rather than how to use specific operations. This mainly comes down to understanding how the components which make up each register work.</p>
<p>Recall that every register consists of four values, which are accessed through the a dot-suffix notation. For instance <strong>fc3.x</strong> is the first component of the register &#8220;fragment constant 3&#8243;. The components are referred to as <strong>.x .y .z</strong> and<strong> .w</strong>, you can also refer to them as<strong> .r .g .b</strong> and <strong>.a</strong>. Keep in mind that <strong>fc3.x</strong> is exactly the same thing as <strong>fc3.r</strong>; for this reason I prefer to stick with using the xyzw notation throughout my shaders even when I&#8217;m dealing with colours.</p>
<p>AGAL operations almost all act in a &#8220;component-wise&#8221; fashion, meaning we can supply them with more than a single component and they will apply the operation to all components at once. Some operations require multiple components be given, namely those meant to operate on vectors. To specify multiple components from a register simply use multiple component letters after the register name, for instance <strong>fc3.xyz</strong> gives the first three components of the &#8220;fragment constant 3&#8243; register.</p>
<p><strong>Note!</strong> If you specify just a register name then AGAL assumes you want to use all four components. So <strong>fc3.xyzw</strong> is exactly the same as <strong>fc3</strong>.</p>
<h1>How Component-wise Operations Work<strong><br />
</strong></h1>
<p><strong>add vt0 va0 va1<br />
</strong>or<strong><br />
add vt0.xyzw va0.xyzw va1.xyzw</strong></p>
<p><em>before:<br />
</em> <strong>vt0</strong>: ? ? ? ?<br />
<strong>va0</strong>: 2 7 4 2<br />
<strong>va1</strong>: 1 4 9 0</p>
<p><em>after:<br />
</em> <strong>vt0</strong>: 3 11 13 2<br />
<strong>va0</strong> and <strong>va1</strong> unchanged</p>
<p>Each component of <strong>va0 </strong>is put through the addition operation with the matching component of <strong>va1</strong> and the result is put in the matching component of <strong>vt0</strong>.</p>
<p>In the above example:<br />
<strong>vt0.x</strong> =<strong> va0.x</strong> +<strong> va0.x</strong><br />
<strong>vt0.y </strong>=<strong> va0.y</strong> +<strong> va0.y</strong><br />
<strong>vt0.z</strong> =<strong> va0.z</strong> +<strong> va0.z</strong><br />
<strong>vt0.w</strong> =<strong> va0.w</strong> +<strong> va0.w</strong></p>
<p><strong></strong><em><strong>Warning! </strong>I&#8217;ve encountered some situations where component-wise multiplication doesn&#8217;t work as I would expect. Specifically the operation:<br />
</em><strong>mul vt0.xy va0.xy vc0.xy</strong></p>
<p><em>Gives a result which is different from that of performing these two operations:<br />
</em><strong>mul vt0.x va0.x vc0.x</strong><br />
<strong>mul vt0.y va0.y vc0.y</strong></p>
<p><em>I&#8217;ve yet to work out exactly what&#8217;s going on. Expect this section to be edited.</em></p>
<h1>Limited Component Operations</h1>
<p><strong>add vt0.xy va0.xy va1.xy</strong><br />
<em></em></p>
<p><em>before:<br />
</em> <strong>vt0</strong>: ? ? ? ?<br />
<strong>va0</strong>: 2 7 4 2<br />
<strong>va1</strong>: 1 4 9 0</p>
<p><em>after:<br />
</em> <strong>vt0</strong>: 3 11 ? ?<br />
<strong>va0</strong> and <strong>va1</strong> unchanged</p>
<p>Does as you&#8217;d expect by adding the values on a component-by component basis. As the <strong>.zw</strong> components of <strong>vt0</strong> are not included in the target they are left untouched by the operation.</p>
<h1>Mismatched Component Counts</h1>
<p><strong>add vt0 va0.xy va1.xy</strong></p>
<p><strong></strong>Here we&#8217;re assigning the result of a two-component operation to a four-component target (remember that <strong>vt0</strong> is the same as saying <strong>vt0.xyzw</strong>). In this case I believe it will put the result of the addition in <strong>vt0.xy</strong>, but your code isn&#8217;t clear so it is much better to specify where you want the result to go.</p>
<h1>Swizzled Components</h1>
<p><strong>mov vt0.xy va0.zw</strong></p>
<p><em>before:<br />
</em><strong>vt0</strong>: ? ? ? ?<br />
<strong>va1</strong>: 1 2 3 4</p>
<p><em>after:<br />
</em> <strong>vt0</strong>: 3 4 ? ?<br />
<strong>va1</strong>: 1 2 3 4</p>
<p>The fact that the source and destination components are not the same doesn&#8217;t matter. So far as AGAL is concerned it&#8217;s just a group of numbers. You can also use the same components but in a different order such as:</p>
<p><strong>mov vt0.xyz va0.zyx</strong></p>
<p><em>before:<br />
</em><strong>vt0</strong>: ? ? ? ?<br />
<strong>va1</strong>: 1 2 3 4</p>
<p><em>after:<br />
</em> <strong>vt0</strong>: 3 2 1 ?<br />
<strong>va1</strong>: 1 2 3 4</p>
<p>Finally, you can even use the same component multiple times.</p>
<p><strong>mov vt0.xyz va0.xxx</strong></p>
<p><em>before:<br />
</em><strong>vt0</strong>: ? ? ? ?<br />
<strong>va1</strong>: 1 2 3 4</p>
<p><em>after:<br />
</em> <strong>vt0</strong>: 1 1 1 ?<br />
<strong>va1</strong>: 1 2 3 4</p>
<h1>Next Time</h1>
<p>That&#8217;s quite enough theory. Next tutorial will definitely be something more direct and practical. Probably stepping through the process of creating a shader, from initial idea to final code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2011/agal-registers/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Accelerated Particle Effects</title>
		<link>http://www.saltgames.com/2011/accelerated-particle-effects/</link>
		<comments>http://www.saltgames.com/2011/accelerated-particle-effects/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 18:13:28 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Stage3D]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=563</guid>
		<description><![CDATA[Not (yet) a tutorial this time, just the demonstration of a GPU-based particle system and a glimpse at the advantages of hardware acceleration. The power of being given access to GPU acceleration for graphics isn&#8217;t just in getting images to &#8230; <a href="http://www.saltgames.com/2011/accelerated-particle-effects/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: left;"><a href="http://www.saltgames.com/2011/accelerated-particle-effects/"><img class="size-full wp-image-564 aligncenter" title="accelerated-particles-preview" src="http://www.saltgames.com/wp-content/uploads/2011/10/accelerated-particles-preview.png" alt="" width="400" height="150" /></a>Not (yet) a tutorial this time, just the demonstration of a GPU-based particle system and a glimpse at the advantages of hardware acceleration.</p>
<p style="text-align: left;"><span id="more-563"></span>The power of being given access to GPU acceleration for graphics isn&#8217;t just in getting images to be drawn really fast. If we use vertex shaders to make things move around the world then we can offload a significant amount of per-frame calculations over to the graphics card, which frees up the CPU for more interesting tasks like AI and physics.</p>
<p style="text-align: left;">As an example of the CPU time saved by using graphics hardware, here is virtually the same program embedded twice. The first version attempts to use your graphics hardware while the second is forced to use the fall-back software implementation. If you&#8217;re viewing this on a device that isn&#8217;t currently supported by Flash&#8217;s hardware acceleration then both versions will be using software rendering. You will of course need Flash Player 11 to see the demo.</p>
<p style="text-align: center;">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_bouncing-agal-particles_820049321"
			class="flashmovie"
			width="600"
			height="500">
	<param name="movie" value="http://www.saltgames.com/wp-content/uploads/2011/10/bouncing-agal-particles.swf" />
	<param name="menu" value="false" />
	<param name="wmode" value="direct" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.saltgames.com/wp-content/uploads/2011/10/bouncing-agal-particles.swf"
			name="fm_bouncing-agal-particles_820049321"
			width="600"
			height="500">
		<param name="menu" value="false" />
		<param name="wmode" value="direct" />
	<!--<![endif]-->
		
<p style="text-align: center;"><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
<p style="text-align: center;">
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p style="text-align: center;">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_bouncing-agal-particles-software_1915976643"
			class="flashmovie"
			width="600"
			height="500">
	<param name="movie" value="http://www.saltgames.com/wp-content/uploads/2011/10/bouncing-agal-particles-software.swf" />
	<param name="menu" value="false" />
	<param name="wmode" value="direct" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.saltgames.com/wp-content/uploads/2011/10/bouncing-agal-particles-software.swf"
			name="fm_bouncing-agal-particles-software_1915976643"
			width="600"
			height="500">
		<param name="menu" value="false" />
		<param name="wmode" value="direct" />
	<!--<![endif]-->
		
<p style="text-align: center;"><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
<p style="text-align: center;">
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p style="text-align: left;">If your results are anything like mine then the difference in performance even with this relatively small scale example will be dramatic. That said I&#8217;ve got to take a moment to say how impressed I am by the performance of the software implementation. It multi-threads and spreads itself across my CPU cores beautifully, and most importantly produces output which is so far as I can tell completely identical to that coming out of the graphics hardware version.</p>
<p style="text-align: left;">Perhaps more interesting than the raw increase in speed is the difference in CPU use. For me the hardware accelerated version&#8217;s main loop is measured at taking 0ms, and as you would expect the software version&#8217;s is much higher at around 20ms. Not only is the hardware accelerated version pumping out frames faster but it&#8217;s barely touching the CPU, which is left free for running the rest of the game.</p>
<h1 style="text-align: left;">Implementation</h1>
<p>Writing the shader for these particles was good fun. If stripped of comments the final code is 54 lines (of a maximum 200 allowed) of virtually indecipherable opcodes and registers, but the process it represents is simple enough.</p>
<p>The classic way to handle moving objects in game programming is to adjust their position each update cycle by adding on a value representing their velocity. This technique doesn&#8217;t work for objects that are to be handled entirely through AGAL shaders as there is simply no place where their position could be updated by the shader and stored between frames.</p>
<p>Instead the shader needs to be able to produce the particle&#8217;s position when provided with the current time. So the process of writing the shader starts with finding an equation in terms of <strong>time</strong> that gives <strong>position</strong> (or rotation, colour, scale, or any other property of your particles that you want to have change). If the particles are moving at a constant velocity this is simple enough:</p>
<pre>position = startPosition + startVelocity * time</pre>
<p>The variables like <strong>startPosition</strong> and <strong>startVelocity</strong> will be passed into the shader through the vertex buffer (as they will be different for each particle), while <strong>time</strong> will be passed in through the shader constants as it is the same for all particles being drawn that frame. If you want the particles to undergo acceleration (such as due to gravity) then you can just add on a new term to account for that.</p>
<pre>position = startPosition + startVelocity * time
           + 0.5 * constantAcceleration * time^2</pre>
<p>Effects like the particles bouncing once when reaching a certain y-value are a little more complex but it still all comes down to making an equation that gives the position of the particle in terms of time.</p>
<h1>Bonus Content!</h1>
<p>Not particularly related to particle systems, but I decided to reproduce <a title="Testing out Pixel Bender" href="http://www.saltgames.com/2010/testing-out-pixel-bender/">an old example</a> of normal mapping I made back when Pixel Bender was the closest to hardware acceleration Flash had available. This version is of course running entirely on the GPU.</p>
<p style="text-align: center;">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_NormalMappingMolehill_1932842964"
			class="flashmovie"
			width="512"
			height="512">
	<param name="movie" value="http://www.saltgames.com/wp-content/uploads/2011/10/NormalMappingMolehill.swf" />
	<param name="menu" value="false" />
	<param name="wmode" value="direct" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.saltgames.com/wp-content/uploads/2011/10/NormalMappingMolehill.swf"
			name="fm_NormalMappingMolehill_1932842964"
			width="512"
			height="512">
		<param name="menu" value="false" />
		<param name="wmode" value="direct" />
	<!--<![endif]-->
		
<p style="text-align: center;"><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
<p style="text-align: center;">
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2011/accelerated-particle-effects/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Simple Annotated Example of Stage3D</title>
		<link>http://www.saltgames.com/2011/simple-annotated-stage3d/</link>
		<comments>http://www.saltgames.com/2011/simple-annotated-stage3d/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 17:08:03 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Stage3D]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=539</guid>
		<description><![CDATA[The first step is often the hardest. Here I provide a very simple example of rendering using Stage3D, complete with extensive comments. All this does is draw a single multicoloured triangle on the screen. Not much, but it&#8217;s a good &#8230; <a href="http://www.saltgames.com/2011/simple-annotated-stage3d/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: left;"><a href="http://www.saltgames.com/2011/simple-annotated-stage3d/"><img class="size-full wp-image-540 aligncenter" title="stage3d-1-preview" src="http://www.saltgames.com/wp-content/uploads/2011/10/stage3d-1-preview.png" alt="" width="400" height="150" /></a>The first step is often the hardest. Here I provide a very simple example of rendering using Stage3D, complete with extensive comments.</p>
<p style="text-align: left;"><span id="more-539"></span></p>
<p style="text-align: left;">All this does is draw a single multicoloured triangle on the screen. Not much, but it&#8217;s a good simple place to start.</p>
<p style="text-align: left;">This example makes use of the MiniAGALAssembler, which is a neat little class allowing the creation of AGAL shader code from within our Actionscript. It is available<a href="http://www.bytearray.org/wp-content/projects/agalassembler/com.zip"> from the original source</a> (bundled with a couple of other things), or <a href="http://www.saltgames.com/wp-content/uploads/2011/10/AGALMiniAssembler.zip">mirrored on this site</a>.</p>
<p style="text-align: left;">My apologises for the slightly ugly way the code gets displayed on this page. If you prefer it is also available as a <a title="Example of very basic rendering using Stage3D" href="http://www.saltgames.com/wp-content/uploads/2011/10/MolehillTutorial-1.zip">FlashDevelop project</a>, with the included Actionscript files of course readable in any text editor.</p>
<p style="text-align: left;"><strong>Main.as</strong></p>
<pre>package
{
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.Program3D;
import flash.events.Event;
import flash.geom.Matrix3D;

/**
* @author Salt
* www.saltgames.com
*/
public class Main extends Sprite
{
  private const renderAreaWidth:int = 600;
  private const renderAreaHeight:int = 400;

  private var myContext3D:Context3D;
  private var myStage3D:Stage3D;

  private var aListOfBundlesToRender:Vector.&lt;BundleToRender&gt;;

  public function Main():void
  {
   if (stage) init();
   else addEventListener(Event.ADDED_TO_STAGE, init);
  }

  private function init(e:Event = null):void
  {
   removeEventListener(Event.ADDED_TO_STAGE, init);

   // Start here &lt;&lt;

   // to do any rendering a Context3D is needed, and they can only be made by a Stage3D object
   // fortunately the Stage already has a list of Stage3D objects ready for us to use

   myStage3D = stage.stage3Ds[0];
   // creating a Context3D is not instant so we have to wait for an event telling us when it is ready
   myStage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreated);
   myStage3D.requestContext3D();
  }

  private function context3DCreated(e:Event):void
  {
   // as the CONTEXT3D_CREATE event has triggered, we know that myStage3D has finished creating its Context3D
   myContext3D = myStage3D.context3D;

   // set up the back buffer of this Context3D, this is the 'canvas' which will be displayed.
   var antiAliasLevel:int = 0;	// valid values are 0, 2, 4, 8, 16
   var enableDepthAndStencilBuffers:Boolean = true;
   myContext3D.configureBackBuffer(renderAreaWidth, renderAreaHeight, antiAliasLevel, enableDepthAndStencilBuffers);

   // if you want the rendered area to be offset from the top-left corner, the position of myStage3D can be changed
   myStage3D.x = 0;
   myStage3D.y = 0;

   // myContext3D is now ready for rendering to take place on it
   addEventListener(Event.ENTER_FRAME, perFrame);

   // create a test item to render
   aListOfBundlesToRender = new Vector.&lt;BundleToRender&gt;;
   aListOfBundlesToRender.push(createTestBundleOfTrianglesToRender());
  }

  private function perFrame(e:Event):void
  {
   performRender();
  }

  private function performRender():void
  {
   // the back buffer must be cleared before we start trying to draw new stuff on it
   // here you can specify what it should be cleared to - including the depth and stencil buffers
   myContext3D.clear();

   // if you want your view of the world to be changed, simply translate the cameraMatrix
   var cameraMatrix:Matrix3D = new Matrix3D();

   // the cameraMatrix and orthographicProjectionMatrix are combined to give a complete transformation matrix
   // this matrix describes how each vertex in the world should be transformed (moved) to appear in the correct place on the screen
   var completeProjectionMatrix:Matrix3D = new Matrix3D();
   completeProjectionMatrix.append(cameraMatrix);
   completeProjectionMatrix.append(createOrthographicProjectionMatrix(renderAreaWidth, renderAreaHeight, 0, 1));

   // now that the transformation matrix has been created, it is loaded into the vertex constant register vc0,
   // ready to be accessed by our vertex shader program.
   myContext3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, completeProjectionMatrix, true);

   for each (var bundleToRender:BundleToRender in aListOfBundlesToRender)
   {
    // set the shader program
    var shaderProgram:Program3D = myContext3D.createProgram();
    shaderProgram.upload(bundleToRender.vertexShaderAssembler.agalcode, bundleToRender.fragmentShaderAssembler.agalcode);
    myContext3D.setProgram(shaderProgram);

    // load vertex position into the vertex registers
    myContext3D.setVertexBufferAt(0, bundleToRender.vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
    //                                                                                            ^ load a pair of values for each vertex - x and y position
    //                            ^ load into the va0 (vertex attribute zero) register

    // load vertex colour into the vertex registers
    myContext3D.setVertexBufferAt(1, bundleToRender.vertexBuffer, 2, Context3DVertexBufferFormat.FLOAT_3);
    //                                                                                            ^ load three values for each vertex - r,g,b to define a colour
    //                                                            ^ skip over the first two values for each vertex (those two values are the x and y coordinates)
    //                            ^ load into the va1 (vertex attribute one) register

    // actually perform the rendering operation
    myContext3D.drawTriangles(bundleToRender.indexBuffer, 0, bundleToRender.numberOfTriangles);
   }

   // once all the rendering is complete, present the back buffer so that the user actually sees it
   myContext3D.present();
  }

  private function createOrthographicProjectionMatrix(viewWidth:Number, viewHeight:Number, near:Number, far:Number):Matrix3D
  {
   // this is a projection matrix that gives us an orthographic view of the world (meaning there's no perspective effect)
   // the view is defined with (0,0) being in the middle,
   //	(-viewWidth / 2, -viewHeight / 2) at the top left,
   // 	(viewWidth / 2, viewHeight / 2) at the bottom right,
   //	and 'near' and 'far' giving limits to the range of z values for objects to appear.
   return new Matrix3D(Vector.&lt;Number&gt;
   ([
    2/viewWidth, 0, 0, 0,
    0, -2/viewHeight, 0, 0,
    0, 0, 1/(far-near), -near/(far-near),
    0, 0, 0, 1
   ]));
  }

  private function createTestBundleOfTrianglesToRender():BundleToRender
  {
   var testBundle:BundleToRender = new BundleToRender();

   // generate the vertex and index buffers for a single triangle
   // in this case the vertex buffer will include both the position and colour data
   // if we were to be using texturing, uv coordinates would be loaded in the vertex buffer too

   // first prepare the vertex buffer, specifying its dimensions
   var verticesForATriangle:int = 3;
   var numberOfTriangles:int = 1;
   var dataCountForEachVertex:int = 5; // for x, y, red, green, blue
   testBundle.vertexBuffer = myContext3D.createVertexBuffer(verticesForATriangle * numberOfTriangles, dataCountForEachVertex);

   // similarly prepare the index buffer
   var numberOfIndicesForATriangle:int = 3;
   testBundle.indexBuffer = myContext3D.createIndexBuffer(numberOfIndicesForATriangle * numberOfTriangles);

   // create the vertex data that will be loaded into the buffer
   var vertexData:Vector.&lt;Number&gt; = new Vector.&lt;Number&gt;();
   //                x     y   r  g  b
   vertexData.push(   0, -100, 1, 0, 0);
   vertexData.push(-150,  150, 0, 1, 0);
   vertexData.push( 200,   50, 0, 0, 1);

   // load the vertex data to the buffer
   testBundle.vertexBuffer.uploadFromVector(vertexData, 0, verticesForATriangle * numberOfTriangles);

   // create the index data to be loaded in
   var indexData:Vector.&lt;uint&gt; = new Vector.&lt;uint&gt;();
   indexData.push(0, 1, 2);

   testBundle.numberOfTriangles = numberOfTriangles;

   // load the index data to the buffer
   testBundle.indexBuffer.uploadFromVector(indexData, 0, numberOfIndicesForATriangle * numberOfTriangles);

   // create both the vertex and fragment shader programs to be used when rendering this bundle of triangles
   // the vertex data created above will be available to these shaders through registers:
   // the first 2 values for each vertex (the x and y position) will appear in va0
   //	the remaining 3 values for each vertex (r, g, b for colour) will appear in va1
   testBundle.setVertexShaderCode(
    "m44 op, va0, vc0 \n" + // apply the matrix transform to va0 (vertex position), putting result in op (the position output)
    "mov v0, va1"           // move va1 (vertex colour) to v0 where the fragment shader will be able to access it
    );

   testBundle.setFragmentShaderCode(
    "mov oc, v0"				// simply put the vertex colour directly into oc (the colour output)
    );

   return testBundle;
  }
}
}</pre>
<p><strong>BundleToRender.as</strong></p>
<pre>package
{
import flash.display3D.Context3DProgramType;
import flash.display3D.IndexBuffer3D;
import flash.display3D.VertexBuffer3D;
/**
* @author Salt
* www.saltgames.com
*/
public class BundleToRender
{
  // I use the not entirely technical term of "bundle" for a group of triangles being rendered all in one batch.

  public var vertexShaderAssembler:AGALMiniAssembler;
  public var fragmentShaderAssembler:AGALMiniAssembler;

  // the vertexBuffer stores all the per-vertex data
  public var vertexBuffer:VertexBuffer3D;

  // the indexBuffer is used to determine how the vertices should be connected to form triangles
  public var indexBuffer:IndexBuffer3D;

  // the number of triangles for which we have data, and we want to draw.
  public var numberOfTriangles:int;

  public function BundleToRender()
  {

  }

  public function setVertexShaderCode(vertexCode:String):void
  {
   vertexShaderAssembler = new AGALMiniAssembler();
   vertexShaderAssembler.assemble(Context3DProgramType.VERTEX, vertexCode);
  }

  public function setFragmentShaderCode(fragmentCode:String):void
  {
   fragmentShaderAssembler = new AGALMiniAssembler();
   fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT, fragmentCode);
  }
}
}</pre>
<p>&nbsp;</p>
<p style="text-align: center;">
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2011/simple-annotated-stage3d/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Stage3D Shader Cheatsheet</title>
		<link>http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/</link>
		<comments>http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 15:08:44 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Stage3D]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=523</guid>
		<description><![CDATA[A quick reference for working with AGAL, the new shader language for use with Stage3D introduced with Flash Player 11. I&#8217;ve been working on a series of tutorials for Stage3D which aren&#8217;t yet ready, but with the recent release of &#8230; <a href="http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/"><img class="size-full wp-image-530 aligncenter" title="agal-cheatsheet-preview" src="http://www.saltgames.com/wp-content/uploads/2011/10/agal-cheatsheet-preview.jpg" alt="" width="400" height="150" /></a></p>
<p>A quick reference for working with AGAL, the new shader language for use with Stage3D introduced with Flash Player 11.</p>
<p><span id="more-523"></span>I&#8217;ve been working on a series of tutorials for Stage3D which aren&#8217;t yet ready, but with the recent release of Flash Player 11 now seems a good time to get at least some information out. If you&#8217;re new to Stage3D then this may not make much sense until you&#8217;ve read some other resources, but I hope it serves as a useful reference as you experiment and learn.</p>
<p><strong>Registers:<br />
</strong>Each register consists of four components, which are floating point values. These components are accessed by<em> registerName.x, registerName.y, registerName.z, registerName.w. </em>They&#8217;re named for dealing with 3D positions &#8211; with the &#8216;w&#8217; for rotation in the style of quaternions &#8211; but they can just as well be used to hold a colour (in fact you can also access the components with .r .g. b. a) or any other values you want to use.</p>
<p>There are several registers of each type available. For instance you might have <strong>va0</strong> giving the 3D position of a vertex in space, and <strong>va1</strong> giving the uv mapping coordinate for that vertex. The nice thing about having registers made up of components is you can do things like perform a basic addition operation <strong>va0</strong> and <strong>vc0</strong>, and the addition will be performed correctly on each component.</p>
<p><strong>Registers for Vertex Shaders</strong></p>
<ul>
<li><strong>va[0 to 7]</strong> Vertex Attribute. The contents of the vertex buffer, as set with <em>context3D.setVertexBufferAt</em>. Each vertex has its own space in the vertex buffer which only it can access.</li>
<li><strong>vc[0 to 127] </strong>Vertex Constant. Passed into the shader with <em>context3D.setProgramConstantsFromVector</em> or <em>context3D.setProgramConstantsFromMatrix</em>. These registers can be read by all vertices, but cannot be written to by the shader.</li>
<li><strong>vt[0 to 7]</strong> Vertex Temporary. A handy temporary register where you can put values during a calculation.</li>
<li><strong>op </strong>Vertex Output or &#8220;Output Position&#8221;. The output: <strong>op.x </strong>and<strong> op.y</strong> is where in the 2D space of the screen this vertex will be drawn. The <strong>op.z</strong> value is used for depth checking and writing to the depth buffer if you have those enabled. So far as I know the <strong>op.w</strong> value is not actually used.</li>
</ul>
<ul>
<li><strong>v[0 to 7]</strong> Varying. A magical (not actually magical) register that allows you to pass values from the vertex shader to the fragment shader. The value that arrives in the fragment shader will be interpolated between the value of the three <strong>v</strong> registers of the vertices which make up the triangle in which the fragment falls.<br />
<strong>Note!</strong>  The fragment shader cannot directly access the vertex buffer, so anything it needs from there has to be passed through the <strong>v</strong> registers. For instance if you&#8217;re using texture mapping this register will need to pass the uv coordinates to the fragment shader.</li>
</ul>
<p><strong>Registers for Fragment Shaders</strong></p>
<ul>
<li><strong>fc[0 to 27]</strong> Fragment Constant. Much like <strong>vc</strong> for the vertex shader, this register is set by <em>context.setProgramConstantsFromVector</em> or <em>context.setProgramConstantsFromMatrix, </em>can be read by each fragment, and not written to by the shader.</li>
<li><strong>ft[0 to 7]</strong> Fragment Temporary. Again just like <strong>vt</strong> for the vertex shader, this is a temporary store useful for performing calculations.</li>
<li><strong>fs[0 to 7]</strong> Texture Sampler. This is where the fragment shader is able to access whatever texture(s) were bound using <em>context3D.setTextureAt</em>.</li>
<li><strong>oc</strong> Fragment Output or &#8220;Output Colour&#8221;. The output: <strong>oc.x oc.y oc.z oc.w</strong> are the red, green, blue and alpha values respectively for the fragment to be drawn.</li>
</ul>
<p><strong>Operations:<br />
</strong>Shaders are made up of a series of operations, with one operation on each line. First the operation to perform is identified by a three letter opcode such as &#8220;add&#8221;, then the parameters for that operation are given. The parameters are (almost) always specified as registers. If you want to use a number in your shader, it should be supplied through the <strong>vc</strong> or <strong>fc</strong> registers.</p>
<p>In the parameters the target register is always specified first. The target register is where the result of the operation is placed. No change is made to a register other than the target register. Some operations require two further parameters, others just one. The <strong>tex</strong> operation used for texture sampling is a special case that has six parameters, three of which are given as strings rather than registers. <strong>tex</strong> is a pretty wild guy.</p>
<p>At first look the mess of opcodes and registers names that make up the AGAL code for a shader can look intimidating but they&#8217;re actually quite simple. Just remember that each operation does exactly one thing, and writes to exactly one register. AGAL doesn&#8217;t allow for conditional statements like <strong>if then</strong> or any form of looping, so following along with what a shader is doing is extremely easy: it always just proceeds to the next operation.</p>
<p>With that said, AGAL code is not nearly as intuitive to glance at and understand what it does as (well written) AS3 code is. Taking a minute to type out some comments for the AGAL code you write is a very good idea.</p>
<p>You are limited to 200 operations in a single AGAL shader.</p>
<div><strong>Operations available to shaders:</strong></div>
<div>
<ul>
<li><strong>mov t a </strong>- Copy the contents of <strong>a</strong> into<strong> t</strong>.</li>
<li><strong>add t a b</strong> - Add <strong>a</strong> and <strong>b</strong>, put result in<strong> t</strong>.</li>
<li><strong>sub t a b</strong> &#8211; Subtract<strong> b</strong> from <strong>a</strong>, put result in <strong>t</strong>.</li>
<li><strong>mul t a b</strong> &#8211; Multiple <strong>a</strong> and<strong> b</strong>, put result in<strong> t</strong>.<br />
When working component-wise this operation doesn&#8217;t always do as I&#8217;d expect. Specifically performing the operation:<br />
<em>mul vt0.xy va0.xy vc0.xy</em><br />
Gives a different result from performing the two operations:<br />
<em>mul vt0.x va0.x vc0.x</em><br />
<em>mul vt0.y va0.y vc0.y</em><br />
Whereas they would give the same result if it were an <strong>add</strong> operation in both instances instead of <strong>mul</strong>. I&#8217;ve yet to work out exactly what the <strong>mul</strong> operation does with multiple components.</li>
<li><strong>div t a b</strong> &#8211; Divide <strong>a</strong> by <strong>b</strong>, put result in <strong>t</strong>.<br />
The same behaviour as outlined above for the <strong>mul</strong> operation applies to <strong>div</strong> too.</li>
<li><strong>rcp t a</strong> &#8211; Divide 1 by <strong>a</strong>, put result in<strong> t</strong>.</li>
<li><strong>min t a b</strong> &#8211; Copy whichever of <strong>a</strong> or <strong>b</strong> is smaller into <strong>t</strong>.</li>
<li><strong>max t a b</strong> &#8211; Copy whichever of <strong>a</strong> or <strong>b</strong> is larger into <strong>t</strong>.</li>
<li><strong>frc t a</strong> &#8211; Copy just the fractional part of <strong>a</strong> into<strong> t</strong>.<br />
e.g. if <strong>a</strong> has the value 5.86 then 0.86 is placed in <strong>t</strong>.</li>
<li><strong>sqt t a </strong>- Find the square root of <strong>a</strong>, put result in <strong>t</strong>.</li>
<li><strong>rsq t a</strong> &#8211; Find 1 divided by the square root of <strong>a</strong>, put result in<strong> t</strong>.</li>
<li><strong>pow t a b</strong> &#8211; Raise <strong>a</strong> to the power of <strong>b</strong>, put result in<strong> t</strong>.</li>
<li><strong>log t a</strong> &#8211; Find the <a href="http://en.wikipedia.org/wiki/Binary_logarithm" target="_blank">binary logarithm</a> of <strong>a</strong>, put result in <strong>t</strong>.</li>
<li><strong>exp t a</strong> &#8211; Raise 2 to the power of <strong>a</strong>, put result in <strong>t</strong>.</li>
<li><strong>nrm t a</strong> &#8211; <a href="http://en.wikipedia.org/wiki/Normalized_vector" target="_blank">Normalise </a>the vector given in <strong>a</strong> (keep same direction, but make it length 1), put result in<strong> t</strong>.</li>
<li><strong>sin t a</strong> &#8211; Find the <a href="http://en.wikipedia.org/wiki/Sine" target="_blank">sine </a>of <strong>a</strong>, put result in <strong>t</strong>.</li>
<li><strong>cos t a</strong> &#8211; Find the cosine of <strong>a</strong>, put result in <strong>t</strong>.</li>
<li><strong>crs t a b</strong> &#8211; Find the <a href="http://en.wikipedia.org/wiki/Cross_product" target="_blank">cross product</a> of the vectors <strong>a</strong> and <strong>b</strong>, put result in<strong> t</strong>.</li>
<li><strong>dp3 t a b</strong> &#8211; Find the <a href="http://en.wikipedia.org/wiki/Dot_product" target="_blank">dot product</a> of the three-dimensional vectors <strong>a</strong> and <strong>b</strong>, put result in<strong> t</strong>.</li>
<li><strong>dp4 t a b</strong> &#8211; Find the<a href="http://en.wikipedia.org/wiki/Dot_product" target="_blank"> dot product </a>of the four-dimensional vectors<strong> a</strong> and <strong>b</strong>, put result in <strong>t</strong>.</li>
<li><strong>abs t a</strong> &#8211; Find the <a href="http://en.wikipedia.org/wiki/Absolute_value" target="_blank">absolute value</a> of a, put result in <strong>t</strong>.</li>
<li><strong>neg t a</strong> &#8211; Multiply a by -1, put result in <strong>t</strong>.</li>
<li><strong>sat t a</strong> &#8211; Clamp <strong>a</strong> between 1 and 0, put result in<strong> t</strong>.<br />
e.g. if <strong>a</strong> is -4.6, 0 will be placed in <strong>t</strong>.<br />
If <strong>a</strong> is 0.6, 0.6 will be placed in <strong>t</strong>.<br />
If <strong>a</strong> is 8.2, 1 will be placed in <strong>t</strong>.</li>
<li><strong>m33 t a b</strong> &#8211; Perform a 3&#215;3 matrix multiply on <strong>a</strong> and <strong>b</strong>, put result in <strong>t</strong>.</li>
<li><strong>m44 t a b</strong> &#8211; Perform a 4&#215;4 matrix multiply on <strong>a</strong> and <strong>b</strong>, put result in<strong> t</strong>.</li>
<li><strong>m34 t a b</strong> &#8211; Perform a 3&#215;4 matrix multiply on <strong>a</strong> and <strong>b</strong>, put result in<strong> t</strong>.</li>
<li><strong>m43 t a b</strong> &#8211; Perform a 4&#215;3 matrix multiply on <strong>a</strong> and<strong> b</strong>, put result in<strong> t</strong>.<br />
<em>I need to write a decent explanation of what matrix operations do.<br />
</em>In all of these, <strong>b</strong> is the first register that makes up a matrix. For instance if you perform <strong>m44</strong> with <strong>b</strong> as<strong> vc0</strong> then the contents of registers <strong>vc0 vc1 vc2 vc3</strong> will be used. <strong>a</strong> is a single register that gets multiplied through by the matrix specified in <strong>b</strong>.</li>
<li><strong>sge t a b</strong> - If <strong>a</strong> is greater or equal to <strong>b</strong> put 1 in<strong> t</strong>, otherwise put 0 in <strong>t</strong>.</li>
<li><strong>slt t a b</strong> &#8211; If <strong>a</strong> is less than<strong> b</strong> put 1 in<strong> t</strong>, otherwise put 0 in <strong>t</strong>.<br />
<strong>sge</strong> and <strong>slt</strong> are the closest we have to conditional flow control in AGAL so look out for ways to use multiplication of their 1 or 0 result in place of traditional conditionals.</li>
</ul>
<div><strong>Operations only available to fragment shaders:</strong></div>
<ul>
<li><strong><strong>kil a</strong></strong> - <strong>a</strong> must be a single scalar value rather than a vector, for instance: <strong>ft0.x</strong>. If the value given is less than zero then execution on this fragment is halted and it is not drawn.<em><br />
</em></li>
<li><strong><strong>tex t a b &lt;type, wrap, filter&gt;</strong></strong> - Samples the texture in <strong>b</strong> (which should be one of the <strong>fs</strong> registers) at the coordinates in <strong>a</strong>, putting the resulting colour in <strong>t</strong>.</li>
<ul>
<li><strong>type</strong> determines what kind of texture you&#8217;re sampling from, and should be either: &#8220;2d&#8221; for standard texturing or &#8220;cube&#8221; for using a <a href="http://en.wikipedia.org/wiki/Cubemap">cubemap</a>.</li>
<li><strong>wrap</strong> determines how to deal with sampling beyond the bounds of the texture, either: &#8220;clamp&#8221; or &#8220;repeat&#8221;.</li>
<li><strong>filter</strong> determines how to interpolate between texels, either &#8220;mipnearest&#8221;, &#8220;miplinear&#8221; (both of those require mipmaps to have been uploaded for the texture), &#8220;nearest&#8221;, or &#8220;linear&#8221;. Use nearest if you want your texture to have crisp pixel edges, use linear if you want them smoothed out.</li>
</ul>
</ul>
<p><strong>Examples:<br />
</strong>First a simple vertex shader. This simply performs a 4&#215;4 matrix multiply on the vertex position and a projection matrix. It assumes <strong>va0</strong> holds the x, y, z position of the vertex,  while <strong>vc0-vc3</strong> store a projection matrix set up to transform that point from world space to display space. It also copies <strong>va1</strong> into the shared <strong>v0</strong> register so that it may be used by the following fragment shader as UV coordinates for texture mapping.</p>
<pre>m44 op, va0, vc0
mov v0, va1</pre>
<p>Now a single-line fragment shader. Taking the interpolated value it finds in <strong>v0</strong> as UV coordinates this samples the texture loaded into <strong>fs0</strong> and outputs that sample as the colour for this fragment.</p>
<pre>tex oc, v0, fs0 &lt;2d,clamp,linear&gt;</pre>
<p>&nbsp;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2011/stage-3d-shader-cheatsheet/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Normal Mapped Lighting in a Game</title>
		<link>http://www.saltgames.com/2011/normal-mapped-lighting-game/</link>
		<comments>http://www.saltgames.com/2011/normal-mapped-lighting-game/#comments</comments>
		<pubDate>Sun, 24 Jul 2011 13:48:50 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=449</guid>
		<description><![CDATA[A practical test of Pixel Bender powered normal mapped lighting in a game setting, in contrast to a less practical but more pretty example. W, A, S and D to move the player ship, mouse to shoot. Press Q to &#8230; <a href="http://www.saltgames.com/2011/normal-mapped-lighting-game/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.saltgames.com/2011/normal-mapped-lighting-game/"><img class="size-full wp-image-450 aligncenter" title="normal-mapped-game-preview" src="http://www.saltgames.com/wp-content/uploads/2011/07/normal-mapped-game-preview.jpg" alt="" width="400" height="150" /></a><span id="more-449"></span></p>
<p><object width="640" height="480" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="wmode" value="direct" /><param name="src" value="http://www.saltgames.com/wp-content/uploads/2011/07/Perlin05.swf" /><embed width="640" height="480" type="application/x-shockwave-flash" src="http://www.saltgames.com/wp-content/uploads/2011/07/Perlin05.swf" wmode="direct" /></object></p>
<p>A practical test of Pixel Bender powered normal mapped lighting in a game setting, in contrast to a <a href="http://www.saltgames.com/?p=191">less practical but more pretty example</a>.</p>
<p>W, A, S and D to move the player ship, mouse to shoot. Press Q to spawn a group of enemies.  Be aware &#8211; there is sound in this example!</p>
<p>A single light source follow&#8217;s the player, and additional light sources are created for each enemy destroyed. All light sources illuminate a generated layer of textured and bump mapped rock.</p>
<p>To attempt to match the various performance requirements of a finished game, there is a simple particle animation system, enemy AI and parallax background. A circular distortion effect also powered by Pixel Bender can be seen if an enemy collides with the player, or the player detonates a bomb using Spacebar.</p>
<p>The lighting effect can be disabled from the menu accessible by right-clicking while the game is running.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2011/normal-mapped-lighting-game/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2D Shadow Effects</title>
		<link>http://www.saltgames.com/2011/2d-shadow-effects/</link>
		<comments>http://www.saltgames.com/2011/2d-shadow-effects/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 13:12:59 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=441</guid>
		<description><![CDATA[
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_shadowTutorial_1008898317"
			class="flashmovie"
			width="300"
			height="300">
	<param name="movie" value="http://www.saltgames.com/wp-content/uploads/2009/10/shadowTutorial.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.saltgames.com/wp-content/uploads/2009/10/shadowTutorial.swf"
			name="fm_shadowTutorial_1008898317"
			width="300"
			height="300">
	<!--<![endif]-->
		 
	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object> The source code for this simple example is available here. Although be aware it uses the Box2D physics library for handling the shapes, so some of the source may be confusing if you&#8217;re &#8230; <a href="http://www.saltgames.com/2011/2d-shadow-effects/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.saltgames.com/2011/2d-shadow-effects/"><img class="aligncenter size-full wp-image-443" title="2d-shadows-preview" src="http://www.saltgames.com/wp-content/uploads/2011/07/2d-shadows-preview.png" alt="" width="400" height="150" /></a></p>
<p><span id="more-441"></span></p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_shadowTutorial_1634589960"
			class="flashmovie"
			width="300"
			height="300">
	<param name="movie" value="http://www.saltgames.com/wp-content/uploads/2009/10/shadowTutorial.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.saltgames.com/wp-content/uploads/2009/10/shadowTutorial.swf"
			name="fm_shadowTutorial_1634589960"
			width="300"
			height="300">
	<!--<![endif]-->
		
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>The source code for this <a href="http://www.saltgames.com/wp-content/uploads/2011/12/ShadowTutorial.zip">simple example is available here</a>. Although be aware it uses the <a href="http://www.box2dflash.org/">Box2D physics library</a> for handling the shapes, so some of the source may be confusing if you&#8217;re not familiar with that library.</p>
<p>&nbsp;</p>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
			id="fm_rogueLikeShadows_1290708999"
			class="flashmovie"
			width="400"
			height="400">
	<param name="movie" value="http://www.saltgames.com/wp-content/uploads/2009/11/rogueLikeShadows.swf" />
	<!--[if !IE]>-->
	<object	type="application/x-shockwave-flash"
			data="http://www.saltgames.com/wp-content/uploads/2009/11/rogueLikeShadows.swf"
			name="fm_rogueLikeShadows_1290708999"
			width="400"
			height="400">
	<!--<![endif]-->
		
<p><a href="http://adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

	<!--[if !IE]>-->
	</object>
	<!--<![endif]-->
</object>
<p>A demonstration of the 2D shadow effects that I discuss in <a href="http://forums.tigsource.com/index.php?topic=8803.0" target="_blank">a tutorial on the TIGSource forums</a> that I wrote a while ago.  Just a series of rooms that you can walk through. No source code for this one because frankly it&#8217;s a bit of a mess. It&#8217;s the same technique as used in the first example, just applied to a more overtly game-like setting.</p>
<p>W, A, S and D to move, space bar to toggle the light on your faerie companion.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2011/2d-shadow-effects/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introduction to Pixel Bender in Flash</title>
		<link>http://www.saltgames.com/2010/introduction-to-pixel-bender-in-flash/</link>
		<comments>http://www.saltgames.com/2010/introduction-to-pixel-bender-in-flash/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 20:05:58 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=207</guid>
		<description><![CDATA[A quite detailed tutorial on creating custom shaders in Pixel Bender and using them in your Flash projects. This is quite a lengthy tutorial.  It includes a brief introduction to pixel shaders in general; a tour of the most important &#8230; <a href="http://www.saltgames.com/2010/introduction-to-pixel-bender-in-flash/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://www.saltgames.com/2010/introduction-to-pixel-bender-in-flash"><img class="aligncenter size-full wp-image-480" title="pixel-bender-preview" src="http://www.saltgames.com/wp-content/uploads/2010/02/pixel-bender-preview.png" alt="" width="400" height="150" /></a></p>
<p>A quite detailed tutorial on creating custom shaders in Pixel Bender and using them in your Flash projects.</p>
<p><span id="more-207"></span><strong> </strong></p>
<p>This is quite a lengthy tutorial.  It includes a brief introduction to pixel shaders in general; a tour of the most important aspects of Pixel Bender for use creating shaders specifically for Flash, directions for integrating the custom shader you create into a Flash project, and example source code for two simple examples.</p>
<p><strong>Some Introductions</strong></p>
<p><em>Shaders, specifically pixel shaders.</em></p>
<p><em> </em> These are programs that operate on an image on a per-pixel basis.  Per-pixel means the program operates on each pixel individually, without reference to operations carried out on other pixels.  Because shaders operate in this per-pixel manner they very well suited to parallel processing: Having many instances of the shader operating at the same time, each on their own pixel.  Operating per-pixel means that there are certain tasks that are well suited to being performed by a shader as well as many tasks that are completely unsuitable.</p>
<p><em>Filters, Effects, Blendmodes, Kernels.</em></p>
<p>There&#8217;s a lot of terminology floating around depending on where you read about stuff.  I&#8217;m going to call everything a Shader, because that&#8217;s the name of the class I end up using in Flash for everything (not the best method for naming things, but still.) To give a very rough idea to help you follow other documents: Filters and Effects are applied to just one image; Blendmodes are applied to two (or more, in theory?) images; a Kernel is the thing you make when you type code into Pixel Bender.</p>
<p><em>Pixel Bender</em>.</p>
<p>The Pixel Bender Toolkit, to give it its full name, is a neat program made by Adobe to produce custom filters and effects for use in a variety of their applications.  You should be aware when reading other sources for information on Pixel Bender that many of its functions will just not function in Flash.  Pixel Bender is available for free <a href="http://www.adobe.com/devnet/pixelbender/">from Adobe</a>, look to the right of that page.  Pixel Bender was known as Hydra when it was earlier in development, so you may see that name crop up around the place too.</p>
<p><strong>Here be monsters</strong></p>
<p>Using Pixel Bender to make shaders for Flash is &#8211; to put it politely &#8211; prone to inconsistencies.  The Pixel Bender Toolkit lets you run your shader within it to test it.  What you see in the preview will quite often not match what comes out in Flash.  I&#8217;m attempting to build up a <a href="http://www.saltgames.com/?p=216">record of ways</a> in which the two do not match but it&#8217;s far from complete.  Just be aware that you should test primarily in Flash and not rely on the inbuilt preview.  Since I first wrote this tutorial the Pixel Bender Toolkit now includes an option to simulate running a shader in Flash which is helpful, but I suspect still doesn&#8217;t catch everything.  Also be sure to regularly check for an updated version from Adobe &#8211; I&#8217;ve found myself stuck trying to work around some bug which has actually already been fixed if I&#8217;d just updated.</p>
<p><strong>What&#8217;s the point</strong></p>
<p>So Pixel Bender can make buggy programs that are limited to operating on images in a per-pixel basis.  Why am I bothering learning this?</p>
<p>Because it&#8217;s <em>fast!</em></p>
<p><em><span style="font-style: normal;">You might like to look at a <a href="http://www.saltgames.com/?p=191">normal mapping example</a> I put together recently.</span></em></p>
<p>Flash programs are pretty slow generally, and are limited to executing in a single thread.  Consider if you want to tint an image red in Flash.  If you&#8217;re charmingly naïve you might write something like:</p>
<pre>for (var x:int = 0; x &lt; image.width; x++)
{
   for (var y:int = 0; y &lt; image.height; y++)
   {
      var colour:uint = image.getPixel(x, y);
      colour = (colour | 0xff0000); //set the red channel to 255
      image.setPixel(x, y, colour);
   }
}</pre>
<p>This will be slow.  It&#8217;ll be slow because of the <strong>BitmapData.getPixel</strong> and <strong>BitmapData.setPixel</strong> operations being called huge numbers of times, but on a more general level it&#8217;s slow because you&#8217;re visiting each pixel in turn when you could be performing that operation on all the pixels at once.  This is effectively what a custom shader from Pixel Bender does.</p>
<p>Your shader will not <em>actually</em> operate on all the pixels at once, as it&#8217;s limited by the number of threads it can execute on the machine its on.  But thinking of it as operating on every pixel at once is a useful mental model.</p>
<p>Pixel Bender was designed to run on GPUs, which are especially well suited to performing many parallel tasks.  When running in Flash it is actually limited to using the CPU.  This means it&#8217;s not nearly as fast as it <em>could</em> be, but it still has the potential to be many times faster than plain old actionscript.</p>
<p><strong>To the Pixel Bender!</strong></p>
<p>Let&#8217;s get right in and actually make a shader and get it working in Flash.</p>
<p><a href="http://www.adobe.com/devnet/pixelbender/">Download</a> and install Pixel Bender.</p>
<p>Set a couple of options within Pixel Bender (<strong>Edit </strong>menu, <strong>Preferences&#8230;</strong>) to tell it you&#8217;ll be exporting to Flash:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2010/02/preferences.jpg"><img class="aligncenter size-full wp-image-218" title="preferences" src="http://www.saltgames.com/wp-content/uploads/2010/02/preferences.jpg" alt="" width="444" height="314" /></a></p>
<p>Select <strong>New Kernel</strong> from the <strong>File </strong>menu.</p>
<p>You&#8217;ll now have the code for a shader that does nothing.  Excellent!</p>
<pre>&lt;languageVersion : 1.0;&gt;
kernel NewFilter
&lt;  namespace : "Your Namespace";
   vendor : "Your Vendor";
   version : 1;
   description : "your description";
&gt;
{
   input image4 src;
   output pixel4 dst;
   void
   evaluatePixel()
   {
      dst = sampleNearest(src,outCoord());
   }
}</pre>
<p>Oh no, this isn&#8217;t Actionscript!  Time to learn a new language.  Good news is it&#8217;s easy, and you can ignore most of it.</p>
<p>So what actually matters here?</p>
<pre>input image4 src;</pre>
<p>This declares a variable of the type <strong>image4</strong> named <strong>src</strong>, and says that this variable will hold the input that our shader is given.  Later we&#8217;ll see how a shader can have multiple input images.</p>
<p>The type <strong>image4</strong> just means that it&#8217;s an image with 4 colour channels: Red, green, blue and alpha.  There is also <strong>image3</strong> if you want to ignore the alpha channel.</p>
<pre>output pixel4 dst;</pre>
<p>This declares a variable of the type <strong>pixel4</strong> named <strong>dst</strong>, and says that whatever value we put in this variable will be the output of the shader.  <strong>pixel4</strong> is a single pixel with 4 colour channels.</p>
<p>But wait!  We&#8217;re taking a whole image as input, and only giving a single pixel as output?  Shouldn&#8217;t this be producing a whole image?</p>
<p>I was just getting to that.</p>
<p>The <strong>evaulatePixel()</strong> function is the heart of our shader.  It is executed once for <em>each pixel</em> of the source image.  It produces just a single pixel &#8211; our output variable named <strong>dst</strong> &#8211; which is then built up to form the finished image.</p>
<pre>void
evaluatePixel()
{
   dst = sampleNearest(src,outCoord());
}</pre>
<p>Here&#8217;s the <strong>evaluatePixel </strong>function in full.  The only bit you ever need change is between the curly braces.  In this case it takes the result of the built-in function <strong>sampleNearest</strong> and assigns that to dst.  Note that unlike actionscript functions where you use &#8216;return&#8217; to have a function produce a value, evaluatePixel just sets the value of the variable that we&#8217;ve previously defined as the shader&#8217;s output.</p>
<p>What does <strong>sampleNearest</strong> do?  Press F1 in Pixel Bender to get the documentation.  The majority of the documentation doesn&#8217;t apply to us (most sections end with &#8220;Flash player note: X is not supported in Flash Player.&#8221;)  But it has lists of built-in functions and data types, most of which are supported.  <strong>sampleNearest </strong>gives us the value of a single pixel from the image passed as the first parameter, which in this case is <strong>src</strong>.  Which pixel to return is determined by the second parameter, which in this case is the result of another built-in function: <strong>outCoord<span style="font-weight: normal;">. This function returns a </span>float2<span style="font-weight: normal;"> value giving the position of the pixel that in this instance </span>evaluatePixel</strong> was called on.</p>
<p><strong>Vector data types</strong></p>
<p>Unlike actionscript, Pixel Bender uses something called vector data types.  These store several values within one variable.  For instance a position in two-dimensional space can be specified by a <strong>float2</strong> value, which is just two floating point values (basically the same as <strong>number</strong> in actionscript) joined together.  You can access the individual values, or operate on them as a whole.  Let&#8217;s take an example:</p>
<pre>void
evaluatePixel()
{
   pixel4 myPixelVariable;
   myPixelVariable = sampleNearest(src, outCoord());
   dst = myPixelVariable * 2.0;
}</pre>
<p>First new thing:</p>
<pre>pixel4 myPixelVariable;</pre>
<p>Simply declares a variable named <strong>myPixelVariable</strong> which is of type <strong>pixel4</strong>.</p>
<pre>myPixelVariable = sampleNearest(src, outCoord());</pre>
<p>As you&#8217;d expect we can assign a value to it.</p>
<pre>dst = myPixelVariable * 2.0;</pre>
<p>Then we can multiply the whole thing by 2, and assign that to our output variable.</p>
<p>This is exactly the same as performing:</p>
<pre>dst.r = myPixelVariable.r * 2.0;
dst.g = myPixelVariable.g * 2.0;
dst.b = myPixelVariable.b * 2.0;
dst.a = myPixelVariable.a * 2.0;</pre>
<p>Isn&#8217;t that neat.</p>
<p><strong>myPixelVariable.r</strong> is accessing one of the four elements that make up the variable.  The elements can also be accessed by:</p>
<p>myPixelVariable[0], myPixelVariable[1], myPixelVariable[2], myPixelVariable[3]</p>
<p>myPixelVariable.x, myPixelVariable.y, myPixelVariable.z, myPixelVariable.w</p>
<p>myPixelVariable.s, myPixelVariable.t, myPixelVariable.u, myPixelVariable.v</p>
<p>The suffixes <strong>[0]</strong>, <strong>.r</strong>, <strong>.x</strong> and <strong>.s</strong> are all equivalent.</p>
<p>You can access several elements of a vector-type variable at once.</p>
<pre>myPixelVariable.rg *= 2.0;</pre>
<p>Will multiply just the red and green channels by two.</p>
<p>You can also assign values between elements of a vector-type:</p>
<pre>myPixelVariable.rgb = myPixelVariable.brg;</pre>
<p>This assigns the blue value of the pixel to be the red value, the red to the green and the green to the blue.</p>
<p>You can specify each element of a vector-type like so:</p>
<pre>myPixelVariable.rgb = float3(0.5, 0.2, 0.8);</pre>
<p><strong>Fussy about types</strong></p>
<p>Notice that in the examples above we multiply by <strong>2.0</strong> rather than just <strong>2</strong>.  This is because unlike actionscript, Pixel Bender doesn&#8217;t do implicit conversion.  What that means is that it will interpret <strong>2</strong> as an integer, and not know how to multiply that by the <strong>float</strong> values of a <strong>pixel4 </strong>variable.  Writing the value as <strong>2.0</strong> makes it clear that you want it treated as a <strong>float</strong>. You could also use <strong>float(2)</strong> to explicitly convert the <strong>integer </strong>into a <strong>float</strong>.</p>
<p>Slightly weirdly there seems to be little difference between <strong>pixel4 </strong>and <strong>float4</strong>.  I think there&#8217;s a difference in how accurately the values are stored, but they are largely interchangeable.</p>
<p><strong>A working shader</strong></p>
<p>Let&#8217;s pull that together into a simple working shader so we can move on to implementing it in Flash:</p>
<pre>kernel NewFilter
&lt;    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
&gt;
{
    input image4 src;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        dst = sampleNearest(src,outCoord());
        dst.r *= 2.0;
    }
}</pre>
<p>This will just take each pixel from an image and double the red channel.</p>
<p>We can give this a quick test within Pixel Bender.  Just <strong>Load Image 1&#8230;</strong> from the <strong>File</strong> menu and select any old photo you have laying around. Then hit the <strong>Run</strong> button (or <strong>F5</strong>) and the photo will be displayed with a red tint.</p>
<p>Now choose <strong>Export Filter for Flash Player&#8230;</strong> from the <strong>File</strong> menu.  This will create a <strong>.pbj</strong> file containing Pixel Bender byte code which Flash will be able to understand.  Whenever you change a shader you&#8217;re working on, remember you&#8217;ll need to re-export it to have those changes show up in Flash.</p>
<p><strong>And in to Flash</strong></p>
<p>Once you know how, getting the shader in to your Flash program is actually quite simple.  The basic technique is very similar to embedding an image, font or sound:</p>
<pre>[Embed(source = 'TestShader.pbj', mimeType = 'application/octet-stream')]
private var TestShader:Class;</pre>
<p>And that&#8217;s it embedded! To create an instance of the shader:</p>
<pre>var myShader:Shader = new Shader(new TestShader() as ByteArray);</pre>
<p>The shader we&#8217;ve created requires an input image, so we need to point <strong>myShader</strong> at an image to use as its input.</p>
<pre>myShader.data.src.input = myBitmapData;</pre>
<p>This assumes we already have an image loaded and named <strong>myBitmapData</strong>. Note that the <strong>src</strong> corresponds to the name we gave the input variable in Pixel Bender.</p>
<p>To actually run the shader, we make use of a <strong>ShaderJob</strong>.</p>
<pre>myJob:ShaderJob = new ShaderJob(myShader, outputBitmapData);
myJob.start(true);</pre>
<p>Again this assumes we already have a <strong>bitmapData</strong> object named <strong>outputBitmapData</strong> which is ready to receive the finished image (it should be created as the same size as the input image.)  The <strong>true</strong> value passed when calling <strong>start </strong>on <strong>myJob</strong> tells Flash you want to wait until the job is complete before continuing.  It&#8217;s possible to pass <strong>false</strong> instead and have the shader execute asynchronously, but that brings up a whole lot of other issues and <a href="http://www.saltgames.com/?p=200">a pretty major bug</a>.</p>
<p>Putting this all together into a program that&#8217;ll actually work:</p>
<pre>package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shader;
	import flash.display.ShaderJob;
	import flash.display.Sprite;
	import flash.utils.ByteArray;

	public class PrettyShader extends Sprite
	{
		//embed the shader
		[Embed(source = 'TestShader.pbj', mimeType = 'application/octet-stream')]
		private var TestShader:Class;

		//embed an image to test it on
		[Embed(source = 'SomeImage.jpg')]
		private var SomeImage:Class;

		public function PrettyShader()
		{
			//set up the input and output BitmapDatas
			var myBitmapData:BitmapData = (new SomeImage() as Bitmap).bitmapData;
			var outputBitmapData:BitmapData = new BitmapData(myBitmapData.width, myBitmapData.height);

			//set up the Shader
			var myShader:Shader = new Shader(new TestShader() as ByteArray);
			myShader.data.src.input = myBitmapData;

			//create the ShaderJob
			var myJob:ShaderJob = new ShaderJob(myShader, outputBitmapData);

			//and run it!
			myJob.start(true);

			//display the input and output.
			var before:Bitmap = new Bitmap(myBitmapData);
			addChild(before);
			var after:Bitmap = new Bitmap(outputBitmapData);
			after.x = before.width;
			addChild(after);
		}
	}
}</pre>
<p>Remember to set your compiler to target Flash Player 10, and you should end up with something rather like this:</p>
<p><object width="800" height="300" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="wmode" value="direct" /><param name="src" value="http://www.saltgames.com/wp-content/uploads/2010/02/PrettyShader.swf" /><embed width="800" height="300" type="application/x-shockwave-flash" src="http://www.saltgames.com/wp-content/uploads/2010/02/PrettyShader.swf" wmode="direct" /></object></p>
<p>We&#8217;re actually almost done now!  There are two more things to cover:  multiple image inputs, and parameters.</p>
<p><strong>Multiple images as inputs</strong></p>
<p>The example above just takes one image and fiddles with the colour a little.  You can do much more powerful things if you work with more than one image.</p>
<p>In Pixel Bender all we need to do is add an extra <strong>input</strong> statement for each image we want to sample from.  For example:</p>
<pre>kernel NewFilter
&lt;    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
&gt;
{
    input image4 srcOne;
    input image4 srcTwo;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        float2 positionHere = outCoord();
        pixel4 fromOne = sampleNearest(srcOne, positionHere);
        pixel4 fromTwo = sampleNearest(srcTwo, positionHere);
        float crossfade = positionHere.x / 400.0;
        dst = fromOne * crossfade + fromTwo * (1.0 - crossfade);
    }
}</pre>
<p>This will sample from both images, and mix them together depending on the horizontal position of the pixel in question. You might notice that I create a <strong>float2 </strong>variable named <strong>positionHere</strong> to store the result of <strong>outCoord()</strong>, this is simply to save calling the function multiple times when I know it&#8217;ll give the same result.  Unnecessary premature optimisation or just being tidy?  You decide!</p>
<p>The changes in Flash are just as simple.  Simply assign another <strong>BitmapData</strong> as the shader&#8217;s second input:</p>
<pre>myShader.data.srcOne.input = myBitmapData;
myShader.data.srcTwo.input = myOtherBitmapData;</pre>
<p><strong>Parameters</strong><br />
Parameters are simply variables that are used within the shader and can be set from within Flash.  Like input images and the <strong><span style="font-weight: normal;">output</span> </strong>pixel, <strong><span style="font-weight: normal;">parameters</span> </strong>are defined outside of the <strong>evaluatePixel</strong> function.  As well as specifying the data type that the parameter should be you give minimum, maximum and default values.</p>
<p>Here is the above shader amended with two parameters:</p>
<pre>kernel NewFilter
&lt;    namespace : "Your Namespace";
     vendor : "Your Vendor";
     version : 1;
     description : "your description";
&gt;
{
    input image4 srcOne;
    input image4 srcTwo;
    output pixel4 dst;

    parameter float middleOfFade
    &lt;
         minValue: -1.0;
         maxValue: 1.0;
         defaultValue: 0.0;
    &gt;;

    parameter int widthOfImage
    &lt;
         minValue: 0;
         maxValue: 5000;
         defaultValue: 400;
    &gt;;

    void
    evaluatePixel()
    {
        float2 positionHere = outCoord();
        pixel4 fromOne = sampleNearest(srcOne, positionHere);
        pixel4 fromTwo = sampleNearest(srcTwo, positionHere);
        float crossfade = middleOfFade + (positionHere.x / float(widthOfImage));
        if (crossfade &gt; 1.0) crossfade = 1.0;
        if (crossfade &lt; 0.0) crossfade = 0.0;
        dst = fromOne * crossfade + fromTwo * (1.0 - crossfade);
    }
}</pre>
<p>In this case we use two parameters, for two quite different purposes.<strong> </strong>You might have noticed that the previous versions relied on a constant value of 400.0 in the calculation of <strong>crossfade.</strong> This was the width of the image in use, but of course our shader should be ready to accept other sized images too so the parameter <strong>widthOfImage</strong> was added.  Secondly the parameter <strong>middleOfFade</strong> is added to allow interactive changes to how the two source images are mixed.</p>
<p>As a side note, Pixel Bender actually includes some built-in functions for determining the size of input images, but they are not available when exporting for the Flash player.</p>
<p>If you test this shader in Pixel Bender it will display some sliders that let you alter your parameters on the fly and see what effect they have.</p>
<p>Passing values to your shader from Flash is again fairly simple, although slightly obscure.</p>
<pre>myShader.data.middleOfFade.value = [0.2];</pre>
<p>Notice that you use <strong>.value</strong> when setting a parameter, but <strong>.input</strong> when setting an input image.  You also have to put your value inside an array first.  It makes more sense if you need to pass values into a <strong>float3</strong> variable:</p>
<pre>myShader.data.someFloat3Variable.value = [0.1, 0.6, 0.3];</pre>
<p><strong>All together now</strong><br />
A working Flash program that uses a shader with two image inputs and parameters.</p>
<pre>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.utils.ByteArray;

	public class PrettyShader extends Sprite
	{
		//embed the shader
		[Embed(source = 'TestShader.pbj', mimeType = 'application/octet-stream')]
		private var TestShader:Class;

		//embed the images to test it with
		[Embed(source = 'SomeImage.jpg')]
		private var SomeImage:Class;
		[Embed(source = 'SecondImage.jpg')]
		private var OtherImage:Class;

		private var myShader:Shader;
		private var outputImage:BitmapData;

		private var count:Number = 0;
		private const twoPi:Number = Math.PI * 2;

		public function PrettyShader()
		{
			//set up the input and output BitmapDatas
			var firstImage:BitmapData = (new SomeImage() as Bitmap).bitmapData;
			var secondImage:BitmapData = (new OtherImage() as Bitmap).bitmapData;
			outputImage = new BitmapData(firstImage.width, firstImage.height);

			//set up the Shader
			myShader = new Shader(new TestShader() as ByteArray);
			myShader.data.srcOne.input = firstImage;
			myShader.data.srcTwo.input = secondImage;

			//set parameters
			myShader.data.widthOfImage.value = [firstImage.width];
			myShader.data.middleOfFade.value = [0.0];

			//display the output.
			addChild(new Bitmap(outputImage));

                        //update every frame
			addEventListener(Event.ENTER_FRAME, perFrame);
		}

		private function perFrame(e:Event = null):void
		{
			//update realtime parameter
			count += 0.05;
			if (count &gt; twoPi) count -= twoPi;
			myShader.data.middleOfFade.value = [Math.sin(count)];

			//create the ShaderJob
			var myJob:ShaderJob = new ShaderJob(myShader, outputImage);

			//and run it!
			myJob.start(true);
		}
	}
}</pre>
<p>Here it is running:<br />
<object width="400" height="300" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="wmode" value="direct" /><param name="src" value="http://www.saltgames.com/wp-content/uploads/2010/02/TwoImagesShader.swf" /><embed width="400" height="300" type="application/x-shockwave-flash" src="http://www.saltgames.com/wp-content/uploads/2010/02/TwoImagesShader.swf" wmode="direct" /></object></p>
<p>I think that is about all for now.  There is plenty more to learn about both Pixel Bender and using shaders in Flash, but this should give you everything you need to get some cool stuff working.</p>
<p>Of course making those awesome shaders is another topic altogether.</p>
<p>As a final note, keep in mind that it is possible to use custom shaders as <strong>BlendModes</strong> or <strong>Filters</strong> directly in Flash.  I have found that doing so ended up being more complex (or at least confusing), didn&#8217;t allow for the creation of anything that couldn&#8217;t be achieved through the use of <strong>Shader</strong> and <strong>ShaderJob</strong>, and may even run slightly slower.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2010/introduction-to-pixel-bender-in-flash/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.949 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-05-09 01:03:24 -->

<!-- Compression = gzip -->