<?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, 27 Dec 2011 23:36:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>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>2</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_1044662224"
			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_1044662224"
			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_602238593"
			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_602238593"
			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
           + 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_1084348011"
			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_1084348011"
			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>2</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>3</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>7</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_1070719805"
			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_1070719805"
			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_1038031863"
			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_1038031863"
			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_332488202"
			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_332488202"
			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>0</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>11</slash:comments>
		</item>
		<item>
		<title>Testing out Pixel Bender</title>
		<link>http://www.saltgames.com/2010/testing-out-pixel-bender/</link>
		<comments>http://www.saltgames.com/2010/testing-out-pixel-bender/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 18:17:27 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=191</guid>
		<description><![CDATA[Use the mouse to position the lightsource.  This demo&#8217;s normal map was made by following an excellent tutorial on producing normal maps from photographs by Ryan Clark.  The shader is of my own design but is nothing special at all, &#8230; <a href="http://www.saltgames.com/2010/testing-out-pixel-bender/">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/testing-out-pixel-bender/"><img class="aligncenter size-full wp-image-455" title="normal-mapped-coin" src="http://www.saltgames.com/wp-content/uploads/2010/01/normal-mapped-coin.jpg" alt="" width="400" height="150" /></a></p>
<p><span id="more-191"></span><br />
<object width="700" height="700" 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/03/SimpleNormalMap.swf" /><embed width="700" height="700" type="application/x-shockwave-flash" src="http://www.saltgames.com/wp-content/uploads/2010/03/SimpleNormalMap.swf" wmode="direct" /></object></p>
<p>Use the mouse to position the lightsource.  This demo&#8217;s normal map was made by following an <a href="http://zarria.net/nrmphoto/nrmphoto.html">excellent tutorial on producing normal maps from photographs</a> by Ryan Clark.  The shader is of my own design but is nothing special at all, and I think it&#8217;s <span style="text-decoration: line-through;">slightly buggy still</span> working correctly.</p>
<p>On my machine this runs at a capped 50fps, whilst trying to do the exact same pixel calculations &#8216;manually&#8217; with bitmapData methods manages 2 to 3 fps.  I would post a SWF of the manual version too but it has a decent chance of timing out the flash plugin.</p>
<p>This is all thanks to the magic and wonder of <a href="http://labs.adobe.com/technologies/pixelbender/">Pixel Bender</a>, which lets you write your own shaders/filters/blendmodes for use in a range of Adobe&#8217;s products &#8211; including Flash.  Basically it lets you write an operation that will be executed on every pixel in a given image.  The good bit is that the execution of that operation will take advantage of the parallel nature of the task and split its operation into threads, so showing a huge increase in performance from the single-thread bound Flash Player.  You may also read about how Pixel Bender pushes its calculations on to the GPU, but it actually doesn&#8217;t do that when executing in Flash.</p>
<p>Sadly a significant amount of its features are disabled for Flash, and there are still plenty of oddities and <a href="http://www.saltgames.com/?p=216">inconsistencies </a>that even in my brief testing I&#8217;ve come up against.  Despite that, I think it&#8217;s worthy of investigation simply because of the huge increase in performance it can give &#8211; it&#8217;s also free and works fine without needing to use the Flash IDE.</p>
<p>Once I&#8217;m a little more certain that I&#8217;m doing things right I&#8217;ll write up an introduction tutorial for using Pixel Bender in Flash projects.</p>
<p><strong>Edit:</strong> <a href="http://www.saltgames.com/?p=207">Here it is</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2010/testing-out-pixel-bender/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A Bitwise Method For Applying Tilemaps</title>
		<link>http://www.saltgames.com/2010/a-bitwise-method-for-applying-tilemaps/</link>
		<comments>http://www.saltgames.com/2010/a-bitwise-method-for-applying-tilemaps/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 18:57:21 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=184</guid>
		<description><![CDATA[A technique for automatically selecting the correct tile from a tilemap. I originally wrote this as a reply to a question on TIGSource and I figure it&#8217;s worthy of expanding and repeating here. The problem: We have generated a neat &#8230; <a href="http://www.saltgames.com/2010/a-bitwise-method-for-applying-tilemaps/">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/a-bitwise-method-for-applying-tilemaps/"><img class="aligncenter size-full wp-image-457" title="tile-map-preview" src="http://www.saltgames.com/wp-content/uploads/2010/01/tile-map-preview.png" alt="" width="400" height="150" /></a></p>
<p>A technique for automatically selecting the correct tile from a tilemap.<br />
<span id="more-184"></span><br />
I originally wrote this as a reply to <a href="http://forums.tigsource.com/index.php?topic=9859.0">a question on TIGSource</a> and I figure it&#8217;s worthy of expanding and repeating here.</p>
<p>The problem: We have generated a neat platformer level, and want to be able to automatically lay neighbour-sensitive tiles over it so that they fit properly.</p>
<p><strong>Neighbour Sensitive Tiles</strong></p>
<p>Super Mario&#8217;s tiles are not neighbour sensitive;  the stone block always looks the same if it&#8217;s floating alone or if it&#8217;s part of a wall.</p>
<p style="text-align: center;"><a href="http://www.saltgames.com/wp-content/uploads/2010/01/NES_Super_Mario_Bros.gif"><img class="size-full wp-image-185 aligncenter" title="Super Mario Bros" src="http://www.saltgames.com/wp-content/uploads/2010/01/NES_Super_Mario_Bros.gif" alt="Screenshot of the original NES Super Mario Brothers showing the repeated brick block." width="256" height="240" /></a></p>
<p>That&#8217;s fine for many games, but can look out of place if you&#8217;re trying to create a more organic feel in a level, or just wanting to cut down on repeated patterns.  Neighbour sensitive tiles overcome this by matching their appearance to the presence of their neighbours.</p>
<p><strong>A 1-bit Map</strong></p>
<p>Let&#8217;s imagine that with some clever techniques we have generated a level layout for a platformer game that consists of either stone or empty air at each grid location.  This can be represented as a 1-bit image &#8211; that is each pixel&#8217;s state will be determined by a single bit, so either on indicating rock or off to indicate open air.  Here&#8217;s a section of such a map, greatly enlarged and with grid lines added:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/filledGrid.png"><img class="aligncenter size-full wp-image-178" title="filledGrid" src="http://www.saltgames.com/wp-content/uploads/2009/12/filledGrid.png" alt="" width="420" height="420" /></a></p>
<p><strong>A Tileset</strong></p>
<p>A tile set is simply a collection of the graphics that may be used to fill in a map.  Mario&#8217;s tileset is quite small, consisting of just a few different types of block and scenery, whilst ours will have many graphics for the same type of tile:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/tileset.png"><img class="aligncenter size-full wp-image-181" title="tileset" src="http://www.saltgames.com/wp-content/uploads/2009/12/tileset.png" alt="" width="480" height="48" /></a></p>
<p><strong>Valuing Neighbours</strong></p>
<p>To determine which tile should go at each spot on the map, we shall examine that spot&#8217;s immediate neighbours (for now we&#8217;ll ignore diagonal neighbours.)  Rather than writing a huge if/else-if statement to handle all the possible combinations of neighbours, we will use a system that assigns values to each direction.</p>
<p><a style="text-decoration: none;" href="http://www.saltgames.com/wp-content/uploads/2009/12/edge-values.png"><img class="aligncenter size-full wp-image-177" title="edge values" src="http://www.saltgames.com/wp-content/uploads/2009/12/edge-values.png" alt="" width="184" height="184" /></a></p>
<p>A value is found for each location by looking at its neighbours and adding up the values for whichever ones have stone present.  So if the spot we&#8217;re examining has a neighbour above it that is also filled with stone then it is given the value 1.  If it has stone-filled neighbours above and below then the value is 1 + 4, so 5.</p>
<p>You may notice that the values assigned to the directions are the same as the values of the positions in a binary number and this is no surprise; both are ways of representing possible combinations of 4 units which can each be in an on or off (stone or air) state.</p>
<p>Here is the map segment with the value of each tile filled in.  You might like to manually work out the value for a couple of the tiles yourself so you&#8217;re clear on how it works.</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/numberedGrid.png"><img class="aligncenter size-full wp-image-182" title="numberedGrid" src="http://www.saltgames.com/wp-content/uploads/2009/12/numberedGrid.png" alt="" width="420" height="420" /></a></p>
<p><strong>Adding the Tiles</strong></p>
<p>The order in which the tileset is laid out above is not arbitrary; it is laid out so that each tile matches what would be expected of a tile in the map that would be assigned that value.  Once we have a value assigned for each spot on the map we just need to look up that number in the tileset and place the correct tile there:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/12/floatingIsland.png"><br />
<img class="aligncenter size-full wp-image-179" title="floatingIsland" src="http://www.saltgames.com/wp-content/uploads/2009/12/floatingIsland.png" alt="" width="420" height="420" /></a></p>
<p>Wonderful!</p>
<p><strong>Taking it Further</strong></p>
<p><strong>Part One &#8211; Removing Air</strong></p>
<p>Whilst the above works very neatly for platforms floating in air, it doesn&#8217;t yet fully handle two tile types.</p>
<p>Instead of a platformer imagine we&#8217;re working on a top-down 2D RTS with two tile types of grass and water.  In such a case we would expect every spot on the map to have a tile graphic present; there&#8217;s no open spaces like in our platformer.  This means that every spot on the map will need to have a value generated from its neighbours to determine which tile fits there.</p>
<p>We can use exactly the same neighbour valuing system as before, but we now need a way to differentiate between there being grass or water at the spot being examined itself.  This is actually very simply done &#8211; just add an extra value for the location itself, following the same 2 to the power of n pattern from the other values:</p>
<p><a style="text-decoration: none;" href="http://www.saltgames.com/wp-content/uploads/2010/01/extendedValues.png"><img class="aligncenter size-full wp-image-188" title="extendedValues" src="http://www.saltgames.com/wp-content/uploads/2010/01/extendedValues.png" alt="" width="184" height="184" /></a></p>
<p>Let&#8217;s decide that the presence of water means you do add on that position&#8217;s value, whilst the presence of grass means you do not.  So a grass tile surrounded on all sides by grass would be numbered at 0.  A grass tile with water to the top and left would be 1 + 8 = 9.  A water tile surrounded on all sides by grass would be 16.  A water tile with water on all sides would be 1 + 2 + 4 + 8 + 16 = 31</p>
<p><strong>Part Two &#8211; Greater Variety</strong></p>
<p>How do we handle adding additional types of terrain?</p>
<p>Let&#8217;s say we have three types of terrain in our top-down game: water, grass, and forest.  As well as water and grass meeting, we must now also deal with water and forest meeting as well as grass and forest meeting.</p>
<p>Previously there was two possibilities for each neighbour position (grass or water) so we used a <strong>bi</strong>nary counting system.  There&#8217;s now three possibilities so we shall use a <strong>tri</strong>nary counting system.  Our neighbour valuing system needs to be adjusted to match the new counting system:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2010/01/trinaryValues.png"><img class="aligncenter size-full wp-image-187" title="trinaryValues" src="http://www.saltgames.com/wp-content/uploads/2010/01/trinaryValues.png" alt="" width="184" height="184" /></a></p>
<p>Just as the binary counting system followed the pattern of 2 to the power of n, this follows the pattern of 3 to the power of n.</p>
<p>Using a trinary system each position has three possible states: grass, water, forest; or 0, 1, 2.  When there is grass in a given position, we ignore the value (multiply it by 0).  When there is water in the position we add on the value given (multiply it by 1).  When there is forest in the we add on twice the value (multiply it by 2.)</p>
<p>So if we had a tile that was forest with water above it, water to the right, forest below and grass to the left: 81 * 3 + 1 * 2 + 3 * 1 + 9 * 3 + 27 * 0 = 275</p>
<p>You might notice at this point that you&#8217;ll need to draw 324 tile graphics to cover all the possible combinations in a three-terrain map.  This is a lot of tiles to draw by hand.  I would strongly advise looking into at least partially automated methods of producing the multitude of tile combinations.</p>
<p>Of course the system can be extended in just the same way for greater numbers of terrain types, but the number of tile graphics you would need would be even more huge.  Instead I would recommend placing some limits on what tiles are allowed to neighbour one-another.  For instance if forest and water tiles are never allowed to directly touch then the above example will need several hundred less tile graphics.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2010/a-bitwise-method-for-applying-tilemaps/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Procedural Progression</title>
		<link>http://www.saltgames.com/2009/procedural-progression/</link>
		<comments>http://www.saltgames.com/2009/procedural-progression/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 20:19:47 +0000</pubDate>
		<dc:creator>Sam Driver</dc:creator>
				<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.saltgames.com/?p=128</guid>
		<description><![CDATA[The outline for a method to incorporate lock-and-key style progression in a generated game world. Firstly, a short explanation of what I&#8217;m trying to do:  There are plenty of examples of procedurally generated (or &#8220;randomly generated&#8221;) level content for games, &#8230; <a href="http://www.saltgames.com/2009/procedural-progression/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href=" http://www.saltgames.com/2009/procedural-progression/"><img class="aligncenter size-full wp-image-461" title="progression-graph-preview" src="http://www.saltgames.com/wp-content/uploads/2009/10/progression-graph-preview.png" alt="" width="400" height="150" /></a></p>
<p>The outline for a method to incorporate lock-and-key style progression in a generated game world.</p>
<p><span id="more-128"></span>Firstly, a short explanation of what I&#8217;m trying to do:  There are plenty of examples of procedurally generated (or &#8220;randomly generated&#8221;) level content for games, but they often lack a certain type of structure.  Generally they are used to produce very open worlds, where the player is free to explore as they like.  I am trying to make something that will create worlds with gated progression.  At its simplest this is Doom with a locked door that needs the red key which is off on a side path protected by monsters.  Less obviously lock-and-key examples would be games like Zelda and Metroid, where you need to gain certain abilities or special items to reach areas.</p>
<p>Initially I thought to generate a simple world and then develop techniques for adding on progression gates over it.  My first breakthrough came with giving up this idea. Instead I worked on generating the gating mechanisms at the same time as I generate the layout of the world.</p>
<p>The second important factor was to forget about the physical layout of the world.  What actually mattered was the connections of possible-movement between game areas.  So instead of working on a map of the world, I now work on a graph with the nodes as areas of the world and the edges as pathways between those areas that the player can move along.</p>
<p>Here&#8217;s a graph representing a very simple world:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/10/graph01.png"><img class="aligncenter size-full wp-image-129" title="graph01" src="http://www.saltgames.com/wp-content/uploads/2009/10/graph01.png" alt="graph01" width="202" height="173" /></a>The player starts in the node at the red arrow, and wants to get to the node with the chequered flag.  But the pathway is blocked with a lock, so the player must first travel to the node with the key.  Not at all complex, but now the world has some progression structure to it.  This graph&#8217;s layout was generated by a general purpose &#8220;add a goal, and lock it away&#8221; function &#8211; before that function was called, the graph consisted just of the starting node.  The neat thing is that the same function can be used to place the key, so creating:</p>
<p><a href="http://www.saltgames.com/wp-content/uploads/2009/10/graph02.png"><img class="aligncenter size-full wp-image-130" title="graph02" src="http://www.saltgames.com/wp-content/uploads/2009/10/graph02.png" alt="graph02" width="216" height="243" /></a>When choosing where to add the node containing the key, the algorithm limits itself to picking amongst those nodes that it knows are accessible to a player who can access the lock.  This means that there was no possibility for the cyan key to be locked behind the pink door, as the cyan lock is accessible to a player with no keys at all and so the cyan key must be too.  The placing of the cyan lock now means that the pink lock/key no longer satisfy these requirements, but so long as they satisfied them when they were placed, and all locks placed afterwards satisfy them, it is guaranteed that with some work the player will be able to open the pink lock.</p>
<p>Here&#8217;s where my world-graph generator is at currently.  The player starts at the red node, and wants to explore the world (there are actually multiple specific &#8216;goal&#8217; nodes in the map, but I figure it has enough confusing colours already.)  The player can freely move along the grey lines, but must have the correctly coloured key to travel along the coloured lines.  The nodes that hold keys are coloured indicating what key they contain. Unlike the above examples the generator produces dummy nodes so that not every node is a key or goal, and may join dummy nodes together if they share the same key requirements.</p>
<p><object width="600" height="600" 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="src" value="http://www.saltgames.com/wp-content/uploads/2009/10/shoot.swf" /><embed width="600" height="600" type="application/x-shockwave-flash" src="http://www.saltgames.com/wp-content/uploads/2009/10/shoot.swf" /></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.saltgames.com/2009/procedural-progression/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.979 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-20 19:35:39 -->
<!-- Compression = gzip -->
