<?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>GLOW Interactive &#124; BLOG &#187; Jan Kalis</title>
	<atom:link href="http://blog.glowinteractive.com/author/jan/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.glowinteractive.com</link>
	<description>codify, media, gaming, industry ramblings, finance</description>
	<lastBuildDate>Thu, 02 Feb 2012 19:05:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Porting cURL to Android as Static Library</title>
		<link>http://blog.glowinteractive.com/2011/11/porting-curl-to-android-as-static-library/</link>
		<comments>http://blog.glowinteractive.com/2011/11/porting-curl-to-android-as-static-library/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 22:34:54 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[libcurl]]></category>
		<category><![CDATA[ndk]]></category>
		<category><![CDATA[static-library]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=1237</guid>
		<description><![CDATA[For a few months now we have been working on a new game for the iPhone. Although the main target iOS, I have been frequently making sure that the game works correctly on the Android, too, using the Android NDK. There was only one component that was missing for a long time &#8211; cURL on [...]]]></description>
			<content:encoded><![CDATA[<p>For a few months now we have been working on a new game for the iPhone. Although the main target iOS, I have been frequently making sure that the game works correctly on the Android, too, using the <a href="http://developer.android.com/sdk/ndk/index.html">Android NDK</a>. There was only one component that was missing for a long time &#8211; <a href="http://curl.haxx.se/">cURL</a> on the Android side.</p>
<p>A <a href="http://curl.haxx.se/mail/lib-2009-12/0071.html">lot</a> <a href="http://stackoverflow.com/questions/4952169/using-curl-in-android">has</a> <a href="http://stackoverflow.com/questions/4779243/porting-of-http-client-curl-library-on-android">been</a> <a href="http://thesoftwarerogue.blogspot.com/2010/05/porting-of-libcurl-to-android-os-using.html">written</a> about this topic. Following advice from the last link, I eventually managed to build the library. To save you troubles going through all the steps, <a href="http://blog.glowinteractive.com/wp-content/uploads/2011/11/libcurl.zip">here it is</a> for armeabi and armeabi-v7a.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2011/11/porting-curl-to-android-as-static-library/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Path Tracing in Flash</title>
		<link>http://blog.glowinteractive.com/2011/11/path-tracing-in-flash/</link>
		<comments>http://blog.glowinteractive.com/2011/11/path-tracing-in-flash/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 20:08:30 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[global-illumination]]></category>
		<category><![CDATA[path-tracing]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[smallpt]]></category>
		<category><![CDATA[Source-Code]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=1206</guid>
		<description><![CDATA[I recently discovered a very simple global illumination rendering technique called Path Tracing. It only takes a couple of lines of code and produces great images. When optimized, you can achieve almost real time performance, see WebGL implementation or just search YouTube for &#8220;real time path tracing&#8221;. You can check out my self-contained ActionScript 3 version put [...]]]></description>
			<content:encoded><![CDATA[<p>I recently discovered a very simple <a href="http://en.wikipedia.org/wiki/Global_illumination">global illumination</a> rendering technique called <a href="http://en.wikipedia.org/wiki/Path_tracing">Path Tracing</a>. It only takes <a href="http://kevinbeason.com/smallpt/">a couple of lines of code</a> and produces great images. When optimized, you can achieve almost real time performance, see <a href="http://madebyevan.com/webgl-path-tracing/">WebGL implementation</a> or just search YouTube for &#8220;real time path tracing&#8221;.</p>
<p>You can check out my self-contained ActionScript 3 version put together using the links above. A couple of images it generated before the full source code.</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/pathtracing/" target="_blank"><img class="alignnone size-full wp-image-1209" title="pathtracing00" src="http://blog.glowinteractive.com/wp-content/uploads/2011/11/pathtracing00.png" alt="" width="320" height="240" /></a><br />
<a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/pathtracing/" target="_blank"><img class="alignnone size-full wp-image-1210" title="pathtracing01" src="http://blog.glowinteractive.com/wp-content/uploads/2011/11/pathtracing01.png" alt="" width="320" height="240" /></a><br />
<a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/pathtracing/" target="_blank"><img class="alignnone size-full wp-image-1211" title="pathtracing02" src="http://blog.glowinteractive.com/wp-content/uploads/2011/11/pathtracing02.png" alt="" width="320" height="240" /></a></p>
<pre class="brush: as3; title: ;">
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;

	[SWF(backgroundColor=&quot;#000000&quot;, frameRate=&quot;60&quot;, width=&quot;800&quot;, height=&quot;600&quot;)]
	public class PathTracing extends Sprite
	{
		public static const AA:int = 1; // antialiasing
		public static const WIDTH:int = 320 * AA;
		public static const HEIGHT:int = 240 * AA;

		public static const CAM_NEAR:Number = 2;
		public static const CAM_FOV:Number = Math.PI * 0.3;		

		public static const MAX_DEPTH:int = 5;

		private var scene_:Array;

		private var bmd_:BitmapData;
		private var buffer_:Vector.&lt;Vec3&gt;;
		private var counts_:Vector.&lt;int&gt;;

		/**
		 *
		 *
		 */
		public function PathTracing()
		{
			var i:int;

			const camera:Vec3 = new Vec3(0, 0, 2);
			scene_ = Scenes.scene00;

			// add random spheres
			for (i = 0; i &lt; 2; ++i)
			{
				scene_.push(new Sphere(0.1 + 0.5 * Math.random(), new Vec3(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1), new Vec3(Math.random(), Math.random(), Math.random()), new Vec3()));
			}

			// transform scene to camera space
			for (i = 0; i &lt; scene_.length; ++i)
			{
				var sphere:Sphere = scene_[i];
				sphere.center.x -= camera.x;
				sphere.center.y -= camera.y;
				sphere.center.z -= camera.z;
			}

			// display
			bmd_ = new BitmapData(WIDTH, HEIGHT, false, 0);
			// holds accumulated color
			buffer_ = new Vector.&lt;Vec3&gt;(WIDTH * HEIGHT);
			// holds number of samples of that pixel
			counts_ = new Vector.&lt;int&gt;(WIDTH * HEIGHT);

			for (i = 0; i &lt; WIDTH * HEIGHT; ++i)
			{
				buffer_[i] = new Vec3();
				counts_[i] = 0;
			}

			// upside down (we're using OpenGl style coordinate system)
			var b:Bitmap = new Bitmap(bmd_);
			b.smoothing = true;
			b.scaleY = -1;
			b.y = b.height;
			b.scaleX *= 1 / AA;
			b.scaleY *= 1 / AA;
			addChild(b);

			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		/**
		 *
		 * @param event
		 *
		 */
		private function onEnterFrame(event:Event):void
		{
			var x:int, y:int;
			var c:int = 2000;

			while (c--)
			{
				shootRay(Math.random() * WIDTH, Math.random() * HEIGHT);
			}

			bmd_.lock();

			for (y = 0; y &lt; HEIGHT; ++y)
			{
				for (x = 0; x &lt; WIDTH; ++x)
				{
					const i:int = y * WIDTH + x;

					if (counts_[i])
					{
						var color:Vec3 = buffer_[i];

						const r:int = Utils.clampi(color.x * 255 / counts_[i], 0, 0xff);
						const g:int = Utils.clampi(color.y * 255 / counts_[i], 0, 0xff);
						const b:int = Utils.clampi(color.z * 255 / counts_[i], 0, 0xff);

						bmd_.setPixel(x, y, (r &lt;&lt; 16) | (g &lt;&lt; 8) | b);
					}
				}
			}

			bmd_.unlock();
		}

		/**
		 *
		 * @param x
		 * @param y
		 *
		 */
		private function shootRay(x:Number, y:Number):void
		{
			var ray:Ray = new Ray();

			ray.o.x = 0;
			ray.o.y = 0;
			ray.o.z = 0;

			const nx:Number = (2 * (x / WIDTH) - 1) * WIDTH / HEIGHT;
			const ny:Number = 2 * (y / HEIGHT) - 1;

			ray.d.x = CAM_NEAR * Math.tan(CAM_FOV * 0.5) * nx;
			ray.d.y = CAM_NEAR * Math.tan(CAM_FOV * 0.5) * ny;
			ray.d.z = -CAM_NEAR; 

			ray.d = Utils.norm(ray.d);

			const i:int = int(y) * WIDTH + int(x);

			var c:Vec3 = radiance(ray, 0);

			buffer_[i].x += c.x;
			buffer_[i].y += c.y;
			buffer_[i].z += c.z;

			counts_[i]++;
		}

		/**
		 *
		 * @param ray
		 * @param depth
		 * @return
		 *
		 */
		private function radiance(ray:Ray, depth:int):Vec3
		{
			var i:int;
			var sphere:Sphere;
			var t:Number;

			if (depth &gt; MAX_DEPTH)
				return new Vec3();

			var nearest:Number = Infinity;
			var collider:Sphere = null;

			for (i = 0; i &lt; scene_.length; ++i)
			{
				sphere = scene_[i];

				t = sphere.intersect(ray);

				if (t &gt; 0 &amp;&amp; t &lt; nearest)
				{
					nearest = t;
					collider = sphere;
				}
			}

			if (collider == null)
				return new Vec3();

			// compute new ray
			var out:Ray = new Ray();

			out.o.x = ray.o.x + nearest * ray.d.x;
			out.o.y = ray.o.y + nearest * ray.d.y;
			out.o.z = ray.o.z + nearest * ray.d.z;

			var normal:Vec3 = new Vec3();
			normal.x = out.o.x - collider.center.x;
			normal.y = out.o.y - collider.center.y;
			normal.z = out.o.z - collider.center.z;
			normal = Utils.norm(normal);

			var tangent:Vec3 = new Vec3();

			if (Math.abs(normal.x) &lt; Utils.EPSILON)
			{
				tangent.x = 0;
				tangent.y = -normal.z;
				tangent.z = normal.y;
			}
			else
			{
				tangent.x = normal.y;
				tangent.y = -normal.x;
				tangent.z = 0;
			}

			tangent = Utils.norm(tangent);

			const bitangent:Vec3 = normal.cross(tangent);

			// random ray shooting from the normal hemisphere
			const angle:Number = Math.random() * Math.PI * 2;
			const radius2:Number = Math.random();
			const radius:Number = Math.sqrt(radius2);

			const cos:Number = Math.cos(angle) * radius;
			const sin:Number = Math.sin(angle) * radius;
			const sqrt:Number = Math.sqrt(1 - radius2);

			out.d.x = tangent.x * cos + bitangent.x * sin + normal.x * sqrt;
			out.d.y = tangent.y * cos + bitangent.y * sin + normal.y * sqrt;
			out.d.z = tangent.z * cos + bitangent.z * sin + normal.z * sqrt;

			out.d = Utils.norm(out.d);

			// compute new color
			var color:Vec3 = radiance(out, depth + 1);

			color.x *= collider.color.x;
			color.y *= collider.color.y;
			color.z *= collider.color.z;

			color.x += collider.emission.x;
			color.y += collider.emission.y;
			color.z += collider.emission.z;

			return color;
		}
	}
}

class Vec3
{
	public var x:Number;
	public var y:Number;
	public var z:Number;

	public function Vec3(x:Number = 0, y:Number = 0, z:Number = 0)
	{
		this.x = x;
		this.y = y;
		this.z = z;
	}

	public function cross(v:Vec3):Vec3
	{
		var o:Vec3 = new Vec3();

		o.x = y * v.z - z * v.y;
		o.y = z * v.x - x * v.z;
		o.z = x * v.y - y * v.x;

		return o;
	}
}

class Ray
{
	public var o:Vec3 = new Vec3();
	public var d:Vec3 = new Vec3();
}

class Sphere
{
	public var radius:Number;
	public var center:Vec3;
	public var color:Vec3;
	public var emission:Vec3;

	public function Sphere(radius:Number, center:Vec3, color:Vec3, emission:Vec3)
	{
		this.radius = radius;
		this.center = center;
		this.color = color;
		this.emission = emission;
	}

	/**
	 *
	 * @param ray
	 * @return
	 *
	 */
	public function intersect(ray:Ray):Number
	{
		const px:Number = ray.o.x - center.x;
		const py:Number = ray.o.y - center.y;
		const pz:Number = ray.o.z - center.z;

		const pp:Number = px * px + py * py + pz * pz;
		const pd:Number = px * ray.d.x + py * ray.d.y + pz * ray.d.z;

		const A:Number = 1;
		const B:Number = 2 * pd;
		const C:Number = pp - radius * radius;

		const det:Number = B * B - 4 * A * C;

		if (det &lt; 0)
			return -1;

		const det2:Number = Math.sqrt(det);

		const sol:Number = (-B - det2) / (2 * A);

		if (sol &lt; 0)
			return -1;

		return sol;
	}
}

class Utils
{
	public static const EPSILON:Number = 0.0001;

	public static function clamp(v:Number, min:Number, max:Number):Number
	{
		return Math.max(Math.min(v, max), min);
	}

	public static function clampi(v:int, min:int, max:int):int
	{
		return Math.max(Math.min(v, max), min);
	}

	public static function norm(v:Vec3):Vec3
	{
		var o:Vec3 = new Vec3(v.x, v.y, v.z);

		const dd:Number = v.x * v.x + v.y * v.y + v.z * v.z;
		if (dd == 0) return o;

		const invd:Number = 1 / Math.sqrt(dd);
		o.x *= invd;
		o.y *= invd;
		o.z *= invd;		

		return o;
	}
}

class Scenes
{
	public static const R:Number = 1e5;
	public static const G:Number = 0.5;

	public static const scene00:Array =
		[
			new Sphere(R, new Vec3(-R-1, 0, 0), new Vec3(G, G, G), new Vec3()),//left
			new Sphere(R, new Vec3(R+1, 0, 0), new Vec3(G, G, G), new Vec3()),//right
			new Sphere(R, new Vec3(0, 0, R+1), new Vec3(G, G, G), new Vec3()),//front
			new Sphere(R, new Vec3(0, 0, -R-1), new Vec3(G, G, G), new Vec3()),//back
			new Sphere(R, new Vec3(0, R+1, 0), new Vec3(G, G, G), new Vec3()),//top
			new Sphere(R, new Vec3(0, -R-1, 0), new Vec3(G, G, G), new Vec3()),//bottom
			new Sphere(0.5, new Vec3(0, 1+0.25, 0), new Vec3(), new Vec3(12,12,12))//light
		];
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2011/11/path-tracing-in-flash/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Vinyl Scratch Emulation On iPhone (updated)</title>
		<link>http://blog.glowinteractive.com/2011/01/vinyl-scratch-emulation-on-iphone/</link>
		<comments>http://blog.glowinteractive.com/2011/01/vinyl-scratch-emulation-on-iphone/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 16:17:55 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[Bass]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[DJ]]></category>
		<category><![CDATA[Fmod]]></category>
		<category><![CDATA[Interpolation]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Scratching]]></category>
		<category><![CDATA[smoothing]]></category>
		<category><![CDATA[Source-Code]]></category>
		<category><![CDATA[Vinyl]]></category>
		<category><![CDATA[Vinyl-Scratching-Emulation]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=887</guid>
		<description><![CDATA[Currently, we are working on an iPhone game that will fundamentally feature an audio track scratching. We are using the BASS audio library (it seems that we should be able to use FMOD, too, since both libraries have almost identical functions) and a combination of Objective-C and C++.]]></description>
			<content:encoded><![CDATA[<p>Currently, we are working on an iPhone game that will fundamentally feature an audio track <a href="http://en.wikipedia.org/wiki/Scratching">scratching</a>. We are using the <a href="http://www.un4seen.com/">BASS audio library</a> (it seems that we should be able to use <a href="http://www.fmod.org/">FMOD</a>, too, since both libraries have almost identical functions) and a combination of Objective-C and C++.</p>
<p>Without looking at the shoulders of giants, I implemented a simple scratching demo. Basically, whenever the scratching is initiated, I pause the source stream and start playing a stream which has a &#8220;fill-audio-buffer&#8221; callback attached to it. That is, the audio is generated dynamically by filling a small playback buffer in the callback function. In the callback, a simple linear interpolation between the previous position in the scratch buffer and the current position is performed.</p>
<pre class="brush: cpp; title: ;">
for (int i = 0; i &lt; buffer_length; ++i) output[i] = input[F(i)];
</pre>
<p>where F is a <a href="http://en.wikipedia.org/wiki/Piecewise_linear_function">piecewise linear function</a> interpolating between <span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;">[prev_sample_index,Â C * prev_pos_screen] <span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;">and </span>[curr_sample_index,Â C * curr_pos_screen]. </span>The C multiplier corresponds to a relationship between a finger position (whether it&#8217;s a translational or a rotational motion) and the position in the source buffer. It turns out that the sound this method produces is too &#8220;digital&#8221;. It is far from a smooth vinyl scratching emulation. Consulting with our audio (and graphics) designer revealed that it is caused by abrupt changes in the playback frequency (= dF/dt). Thus started a few days of figuring out/tweaking parameters of various interpolation methods that would ensure smooth frequency slides during scratching.</p>
<p>At that point I started looking for other people trying to do the same. It turns out that although <a href="http://sites.google.com/site/gorgull/home2">a</a> <a href="http://lab.andre-michelle.com/scratching">lot</a> <a href="http://www.devmaster.net/forums/showthread.php?t=14388">of</a> <a href="http://www.analogx.com/contents/download/Audio/scratch/Freeware.htm">people</a> claim/show they know how to achieve the effect, only a <a href="http://www.un4seen.com/forum/?topic=9754.0">few</a> <a href="http://www.mixxx.org/">share</a> some code. Since my result seems to be satisfactory to our team, let me describe my approach and <a href="http://blog.glowinteractive.com/wp-content/uploads/2010/11/AudioScratchDemo.zip">share the full source code</a>.</p>
<p>There are two basic problems to deal with. The first one is how to interpolate the source wave to find intermediate values when F is a general function. The other one is to have smooth frequency changes.</p>
<h3>1. Sound wave interpolation</h3>
<p>This was the easier problem. A quick search revealed a <a href="http://stackoverflow.com/questions/1125666/how-do-you-do-bicubic-or-other-non-linear-interpolation-of-re-sampled-audio-dat">Stack Overflow discussion</a> and a <a href="http://www.student.oulu.fi/~oniemita/dsp/deip.pdf">useful article by OlliÂ Niemitalo</a>. Using the &#8220;6-point, 5th-order optimal 32x z-form implementation&#8221; interpolator seemed to have done the trick (maybe even a simpler interpolator would suffice).</p>
<h3>2. Frequency interpolation</h3>
<p>I was mainly looking at two features of the interpolation function (see <a href="http://en.wikipedia.org/wiki/Curve_fitting">curve fitting</a>, <a href="http://en.wikipedia.org/wiki/Smoothing">smoothing</a>) which seem to be on the opposite sides of a balance scale. One is smoothness of the function, the other one is fitness, that is, how close the function is to the recorded (interpolated) values.</p>
<p>Our approach is to get a nice smooth function without trying to achieve precision first and then apply tricks to push it closer to the recorded values. We discovered that a simple <a href="http://en.wikipedia.org/wiki/Moving_average">moving average</a> of the scratching velocity (averaged over 3000 audio samples) and integrating the result works well. As expected, it quickly drifts away from the target position C * curr_pos_screen. To remedy this problem we chose to adjust the velocity to point in the direction towards the target position. And the further the target is (that is, the bigger the error), the larger the adjustment is. (Note: another approach would be to base the adjustment magnitude on the current scratching speed or acceleration rather than error.)</p>
<p><a href="http://blog.glowinteractive.com/wp-content/uploads/2010/11/AudioScratchDemo.zip">Feel free to look at the source code</a>, use your own music, play around with the interpolation functions or change the input method.</p>
<p>[UPDATE]</p>
<p>Now using <a href="https://devforums.apple.com/message/49215#49215">mmap</a> to allow for scratching the whole length of the track. Download the <a href="http://blog.glowinteractive.com/wp-content/uploads/2011/01/AudioScratchDemo2.zip">source code</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2011/01/vinyl-scratch-emulation-on-iphone/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Z-Buffer Implementation In Flash Alchemy</title>
		<link>http://blog.glowinteractive.com/2010/04/z-buffer-implementation-in-flash-alchemy/</link>
		<comments>http://blog.glowinteractive.com/2010/04/z-buffer-implementation-in-flash-alchemy/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 01:41:08 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Alchemy]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[perspectively-correct-texture-mapping]]></category>
		<category><![CDATA[Texture-Mapping]]></category>
		<category><![CDATA[Z-Buffer]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=802</guid>
		<description><![CDATA[One way to perform a perspective correct texture map is via an actual calculation of the z-value at every pixel of the triangle to be rendered. That made me wonder if someone has implemented a simultaneous texture mapping and z-buffer in Flash using Alchemy.]]></description>
			<content:encoded><![CDATA[<p>One way to perform a <a href="http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness">perspective correct texture map</a> is via an <a href="http://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf">actual calculation of the z-value at every pixel</a> of the triangle to be rendered. That made me wonder if someone has implemented a simultaneous texture mapping and z-buffer in Flash using <a href="http://labs.adobe.com/technologies/alchemy/">Alchemy</a>. It seems that no one has done that yet so I decided to put together a demo (to code it as fast as possible I used <a href="http://www.lysator.liu.se/~mikaelk/doc/perspectivetexture/">PTPOLY1.CPP</a> for the triangle rendering).</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/gigl/gigl001/GiglTest.html"><img class="alignnone size-full wp-image-803" title="codify_post_gigl_001" src="http://blog.glowinteractive.com/wp-content/uploads/2010/04/codify_post_gigl_001.jpg" alt="" width="670" height="320" /></a></p>
<p>The demo shows 100 random (intersecting) triangles textured with a Lena image and is rendering at about 30FPS on my Windows 7/Intel Xeon 5160.</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/gigl/gigl001/gigl.zip">Grab the source code!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2010/04/z-buffer-implementation-in-flash-alchemy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bresenham&#8217;s Line Algorithm in Flash Alchemy</title>
		<link>http://blog.glowinteractive.com/2010/04/bresenhams-line-algorithm-in-flash-alchemy/</link>
		<comments>http://blog.glowinteractive.com/2010/04/bresenhams-line-algorithm-in-flash-alchemy/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 03:45:14 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[Bresenham-Line-Algorithm]]></category>
		<category><![CDATA[Flash-Alchemy]]></category>
		<category><![CDATA[Grass-Effect]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=782</guid>
		<description><![CDATA[We are currently working on a platform game that will feature an occasional gravity flip. In some levels the effect will be accompanied by flipping the entire screen but in others it may be too distracting. For those levels we have to come up with other ways to convey that the gravity switched direction.]]></description>
			<content:encoded><![CDATA[<p>We are currently working on a platform game that will feature an occasional gravity flip. In some levels the effect will be accompanied by flipping the entire screen but in others it may be too distracting. For those levels we have to come up with other ways to convey that the gravity switched direction. My idea is to have some kind of grass or hair on platforms that will be influenced by the direction of the gravity force.</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/bresenham_alchemy/Bresenham.html"><img class="alignnone size-full wp-image-783" title="codify_post_bresenham_alchemy" src="http://blog.glowinteractive.com/wp-content/uploads/2010/04/codify_post_bresenham_alchemy.jpg" alt="" width="400" height="300" /></a></p>
<p>A quick demo showed that I would need a lot of line segments. It turned out that <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Graphics.html">Graphics</a>&#8216; moveTo and lineTo is too slow for that amount of lines. So I started looking for an <a href="http://labs.adobe.com/technologies/alchemy/">Alchemy</a> implementation of a line drawing algorithm, specifically <a href="http://en.wikipedia.org/wiki/Bresenham's_line_algorithm">Bresenham&#8217;s line algorithm</a>. The search was not successful so I rolled up my sleeves and started coding it myself &#8211; with help of existing Alchemy demos and a <a href="http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/FOURTH_EDITION/PROGRAMS/bresenham.c">C implementation of the algorithm</a>. <a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/bresenham_alchemy/Bresenham.html">Here&#8217;s the result.</a> Click it to switch between Alchemy rendering and Graphics rendering.</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/bresenham_alchemy/bresenham.zip">Source code here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2010/04/bresenhams-line-algorithm-in-flash-alchemy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Motion Blur of a Spinning Sphere in iPhone OpenGL ES</title>
		<link>http://blog.glowinteractive.com/2010/02/motion-blur-of-a-spinning-sphere-in-iphone-opengl-es/</link>
		<comments>http://blog.glowinteractive.com/2010/02/motion-blur-of-a-spinning-sphere-in-iphone-opengl-es/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 19:15:49 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Motion-Blur]]></category>
		<category><![CDATA[OpenGL-ES]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=655</guid>
		<description><![CDATA[The task is simple: how to go about a motion blur of a fast-spinning OpenGL ES sphere on the iPhone? That is, how to achieve the following effect...]]></description>
			<content:encoded><![CDATA[<p>The task is simple: how to go about a motion blur of a fast-spinning OpenGL ES sphere on the iPhone? That is, how to achieve the following effect.</p>
<p><img class="size-full wp-image-724 alignnone" title="iphone_codify_blur_globe" src="http://blog.glowinteractive.com/wp-content/uploads/2010/02/iphone_codify_blur_globe.jpg" alt="openGL ES Blur" width="670" height="500" /></p>
<p><strong> </strong></p>
<p><strong>Attempt #1 &#8211; drawing on top of previous frames &#8211; rejected</strong></p>
<p>Very simple but occasionally powerful effect of blending with the previous frame (looks like what&#8217;s going on when you get hit in Call of Duty 4). It works for slow motion, but as soon as the globe starts spinning quickly, you can see the individual frames.</p>
<p><strong>Attempt #2 &#8211; accumulation buffer using FBO -  rejected</strong></p>
<p>Also simple to implement. Basically it&#8217;s simulating the accumulation buffer (which is not available on the iPhone). I wasn&#8217;t able to find a sweet spot between a nice-looking motion blur and maintaining high fps (even if the rendering is performed at a much lower resolution).</p>
<p><strong>Attempt #3 &#8211; screen space blurring &#8211; rejected</strong></p>
<p>Originally sounded like a good idea &#8211; thought no one would be able to tell that it&#8217;s only a 2d blur. Not true. Rejected.</p>
<p><strong>Attempt #4 &#8211; pre-blurred texture maps &#8211; used</strong></p>
<p>Main idea: if the globe is spinning along its &#8220;main&#8221; axis (south pole to north pole), the motion blur can be simulated by just blurring the texture horizontally. How about generating a couple of pre-blurred texture maps corresponding to different rotations axes.</p>
<p><img class="alignnone size-full wp-image-775" title="iphone_codify_blur_globe_2" src="http://blog.glowinteractive.com/wp-content/uploads/2010/02/iphone_codify_blur_globe_2.jpg" alt="Globe Blur" width="670" height="320" /></p>
<p>Before I get into details I must say that it works really well. I only use 32 different versions (making the amount of rotation axes 64) and it&#8217;s really hard to tell that it&#8217;s blurred along an axis that&#8217;s slightly off (in the actual iPhone application that this was developed for I am actually snapping to the correct axis which is impossible to notice).</p>
<p>The next disadvantage is also obvious: I only have a limited amount of blur values. In the application I work around that by accelerating and decelerating rapidly.</p>
<p><em>Step 1</em></p>
<p>How to find the best distribution of 32 points on a sphere (actually 64, but the other 32 are just opposite versions of the first 32)? I wrote a <a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/blurred_globe/points_distribution.swf">Flash application</a> that does it for me. It runs a simulation of the following algorithm. Thirty two points are randomly positioned in space, each has a positive charge and is restricted to the unit sphere. The purpose of the positive charge is that the points are repulsed from each other, eventually ending up in an even distribution.</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/blurred_globe/points_distribution.swf" target="_blank"><img class="alignnone size-full wp-image-776" title="iphone_codify_globe_distributed_points" src="http://blog.glowinteractive.com/wp-content/uploads/2010/02/iphone_codify_globe_distributed_points.jpg" alt="Distributed Points" width="670" height="320" /></a></p>
<p><em>Step 2</em></p>
<p>Blurring the original texture by a general axis is just a matter of writing down a couple of equations and hoping that you haven&#8217;t made a typo.</p>
<p><em>Step 3</em></p>
<p>Using the pre-blurred textures is now a piece of cake. Just find the nearest axis and use the corresponding texture.</p>
<p><strong>Attempt #5 &#8211; am I missing something obvious here?</strong></p>
<p>Let me know if I am.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2010/02/motion-blur-of-a-spinning-sphere-in-iphone-opengl-es/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Teaching Worms to Crawl Using Genetic Algorithms</title>
		<link>http://blog.glowinteractive.com/2010/02/teaching-worms-to-crawl-using-genetic-algorithms/</link>
		<comments>http://blog.glowinteractive.com/2010/02/teaching-worms-to-crawl-using-genetic-algorithms/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 13:27:28 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[Crawling-Creatures]]></category>
		<category><![CDATA[Emergent-Behavior]]></category>
		<category><![CDATA[Evolution]]></category>
		<category><![CDATA[Genetic-Algorithms]]></category>
		<category><![CDATA[Neural-Networks]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=688</guid>
		<description><![CDATA[This is a follow-up to the first article about training creatures to walk using neural networks and genetic algorithms. The next creature I decided to train is a worm. Here's the result (generation ~200).]]></description>
			<content:encoded><![CDATA[<p>This is a follow-up to <a href="http://blog.glowinteractive.com/index.php/2010/02/on-using-genetic-algorithm-to-train-neural-network-driven-creatues-to-walk-in-flash/">the first article</a> about training creatures to walk using neural networks and genetic algorithms. The next creature I decided to train is a worm. Here&#8217;s the result (generation ~200).</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/worms.swf" target="_blank"><img class="alignnone size-full wp-image-773" title="codify_genetic_algorithms_worms" src="http://blog.glowinteractive.com/wp-content/uploads/2010/02/codify_genetic_algorithms_worms.jpg" alt="Genetic Algorithms - Worms" width="670" height="320" /></a></p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/creatures.zip">Get the source code</a> (contains the walking creatures, too).</p>
<p>PS: Again, if you happen to evolve an interesting locomotion, send me your code/swf and I&#8217;ll post it here.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2010/02/teaching-worms-to-crawl-using-genetic-algorithms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>On Using Genetic Algorithms to Train Neural Network Driven Creatures to Walk in Flash</title>
		<link>http://blog.glowinteractive.com/2010/02/on-using-genetic-algorithm-to-train-neural-network-driven-creatues-to-walk-in-flash/</link>
		<comments>http://blog.glowinteractive.com/2010/02/on-using-genetic-algorithm-to-train-neural-network-driven-creatues-to-walk-in-flash/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 04:32:26 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[Emergent-Behavior]]></category>
		<category><![CDATA[Evolution]]></category>
		<category><![CDATA[Genetic-Algorithms]]></category>
		<category><![CDATA[Neural-Networks]]></category>
		<category><![CDATA[Walking-Creatures]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=595</guid>
		<description><![CDATA[I remember seeing Karl Sims' video Evolved Virtual Creatures a long time ago. I was completely stunned but unfortunately forgot about it for many years. I was reminded of it again last year when reading about training neural networks using genetic algorithms and decided to evolve my own creatures.]]></description>
			<content:encoded><![CDATA[<p>I remember seeing <a href="Evolved Virtual Creatures?phpMyAdmin=ON7xtWcaZ2dG5aY8FuKOMbfOZk5">Karl Sims&#8217; video Evolved Virtual Creatures</a> a long time ago. I was completely stunned but unfortunately forgot about it for many years. I was reminded of it again last year when reading about training <a href="http://en.wikipedia.org/wiki/Neural_network">neural networks</a> using <a href="http://en.wikipedia.org/wiki/Genetic_algorithm">genetic algorithms</a> (Tom Mitchell&#8217;s <a href="http://www.cs.cmu.edu/~tom/mlbook.html">Machine Learning</a> is highly recommended) and decided to evolve my own creatures.</p>
<p><strong>Preparation</strong></p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/ants.swf">Here is the first demo.</a></p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/ants.swf" target="_blank"><img class="alignnone size-full wp-image-770" title="codify_genetic_algorithms_ants" src="http://blog.glowinteractive.com/wp-content/uploads/2010/02/codify_genetic_algorithms_ants.jpg" alt="Genetic Algorithms - Ants" width="670" height="320" /></a></p>
<p>The task is to teach an ant to get to the end of the L-shaped corridor as fast as possible. All an ant is allowed to do (every frame) is rotate freely and turn on its forward thrust (acceleration). Ant&#8217;s behavior is encoded in its DNA consisting of several genes. Every gene prescribes what an ant does in the frame that corresponds to the index of the gene in the DNA. Specifically, each gene is a 3-bit number encoding the ant&#8217;s possible behavior:</p>
<pre class="brush: as3; title: ;">
var gene:int = dna[simulationStep];
var acceleration:Boolean = gene &amp; 1;
var turnPositive:Boolean = gene &amp; 2;
var turnNegative:Boolean = gene &amp; 4;
</pre>
<p>The <a href="http://en.wikipedia.org/wiki/Genetic_operator">genetic operators</a> used are not tuned for this particular application. What you see on the screen is one population of 100 individuals. It takes time but if you let them learn you&#8217;ll see that in the end they achieve the goal in the most optimal way.</p>
<p><strong>Evolution</strong></p>
<p>Encouraged by the result (also, it only took about 2 hours to code) I wanted more. Without further ado I present the <strong><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/walking_gen0300.swf">walking creatures</a><span style="font-weight: normal;"> (after 300 generations)</span></strong>.</p>
<p><a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/walking_gen0300.swf" target="_blank"><img class="alignnone size-full wp-image-771" title="codify_genetic_algorithms_walking" src="http://blog.glowinteractive.com/wp-content/uploads/2010/02/codify_genetic_algorithms_walking.jpg" alt="Genetic Algorithms - Walking" width="670" height="320" /></a></p>
<p>The task here is to give physics-based (thank you, <a href="http://box2dflash.sourceforge.net/">Box2D</a>!) ragdoll figures brains to be able to move a certain distance. Following Ngo and Marks&#8217; paper <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.42.2303">Spacetime Constrains Revisited</a> I set out to make my own creatures in Flash. In short, I am using a genetic algorithm to train a neural network that controls motors in the creature&#8217;s joints. The <a href="http://en.wikipedia.org/wiki/Fitness_function">fitness function</a> is plainly how far a creature can get within a certain amount of time. The neural network used is very simple &#8211; it&#8217;s a single layer <a href="http://en.wikipedia.org/wiki/Feedforward_neural_network">feed-forward</a> neural network with the inputs being the angles at every joint, vertical velocity and horizontal distance traveled and the outputs the speed of the motor and the target angle of every joint.</p>
<p><strong>Results</strong></p>
<p>I was really happy to see results only after about 300 generations (it took a night though): a frog. Excited, I ran it again and again and interestingly, I only got frogs. I tried to change the fitness function a bit so that the creatures that touch the ground are penalized but didn&#8217;t get anything interesting. Also tried to make the torso a bit heavier and an inchworm-like creature evolved. If you like, you can try to evolve your own creatures, <a href="http://blog.glowinteractive.com/wp-content/themes/glow/flash/jan/genetic/walking_gen0000.swf">here&#8217;s the link to first generation</a> (with a little bit of creativistic randomization to start with). At the end of every generation, the best DNA is <a href="http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary808.html">traced </a> so if you happen to get some interesting locomotion, please send it to me and I&#8217;ll post it here. (Source code to follow after a brief clean-up.)</p>
<p><strong><span style="color: #ff0000;">Edit:</span></strong><strong> </strong>Get the source code in the <a href="http://blog.glowinteractive.com/index.php/2010/02/teaching-worms-to-crawl-using-genetic-algorithms/">next GA post</a>.</p>
<p><strong>What&#8217;s Next</strong></p>
<p>My plan is to try what behaviors will emerge with different shapes, physics set up, fitness functions or selection algorithms.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2010/02/on-using-genetic-algorithm-to-train-neural-network-driven-creatues-to-walk-in-flash/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Quake in Flash 9</title>
		<link>http://blog.glowinteractive.com/2010/01/quake-in-flash-9/</link>
		<comments>http://blog.glowinteractive.com/2010/01/quake-in-flash-9/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 03:28:32 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[AS3]]></category>
		<category><![CDATA[Backface-Culling]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Frustum-Clipping]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Texturing]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=266</guid>
		<description><![CDATA[About a year ago, our company decided to come up with a game that would utilize a highly stylized 3D city neighborhood  as the main "menu" for the game. In a nutshell, just a couple of semitransparent 3D boxes. I figured, rather than looking into an existing Flash 3D engine, I can code it myself.]]></description>
			<content:encoded><![CDATA[<p>About a year ago, our company decided to come up with a game that would utilize a highly stylized 3D city neighborhood as the main &#8220;menu&#8221; for the game. In a nutshell, just a couple of semitransparent 3D boxes. I figured, rather than looking into an existing Flash 3D engine, I can code it myself. There would be no problems with visibility ordering, backface culling, texturing, frustum clipping, etc. It turned out that it really wasn&#8217;t a big deal and in a couple of days I had a very simple and efficient engine running. We didn&#8217;t make the game eventually, but I had a really light-weight base of a 3D engine.</p>
<p>I decided to work on a little bit more, but as it turned out really soon, I needed some open format model files that would serve as demos. As a fan of the original <a href="http://www.idsoftware.com/games/quake/quake/">Quake</a>, and <a href="http://www.bluesnews.com/abrash/">everything</a> <a href="http://www.beyond3d.com/content/articles/8/">around</a> it, and having a feeling that the original levels could run easily on present hardware minus Flash, I started working on a Quake <a href="http://www.gamers.org/dEngine/quake/spec/quake-spec34/qkspec_4.htm">BSP</a> parser. <a href="http://glowinteractive.com/staging/jan/blog/quake/quake.html" target="_blank">See the result for yourself.</a> Use mouse (with left button down) for mouselook, ASDW to move horizontally, RF to move up/down.Â  (It&#8217;s intentionally running fullscreen, just maximize your window.)</p>
<p><a href="http://glowinteractive.com/staging/jan/blog/quake/quake.html" target="_blank"><img class="alignleft size-full wp-image-462" title="codify_post_quake" src="http://blog.glowinteractive.com/wp-content/uploads/2010/01/codify_post_quake.jpg" alt="Quake in Flash 9" width="670" height="320" /></a></p>
<p>I would like to point out that it is Flash 9, i.e. no Alchemy involved!</p>
<p>Conclusion: the demo is running just fine to create a true 3D environment for a Flash game!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2010/01/quake-in-flash-9/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>True Phong Shading in Flash 9</title>
		<link>http://blog.glowinteractive.com/2009/11/true-phong-shading-in-flash-9/</link>
		<comments>http://blog.glowinteractive.com/2009/11/true-phong-shading-in-flash-9/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 22:56:38 +0000</pubDate>
		<dc:creator>Jan Kalis</dc:creator>
				<category><![CDATA[Codify]]></category>
		<category><![CDATA[Light-Bloom]]></category>
		<category><![CDATA[Palette-Remapping]]></category>
		<category><![CDATA[Phong-Shading]]></category>

		<guid isPermaLink="false">http://blog.glowinteractive.com/?p=275</guid>
		<description><![CDATA[Most Flash 3D engines use a clever technique called normal mapping to compensate for the lack of mesh detail. How could a normal map be used for Phong shading? We already have all the normals we need, the only problem left is the shininess exponent, that would have to be computed per pixel. My solution follows.]]></description>
			<content:encoded><![CDATA[<p>Most (Flash) 3D engines use a clever technique called <a href="http://en.wikipedia.org/wiki/Normal_mapping">normal mapping</a> to compensate for the lack of mesh detail. How could a normal map be used for <a href="http://en.wikipedia.org/wiki/Phong_shading">Phong shading</a> (specifically highlights)? The formula for highlights is (L . N) ^ s, where L is the vector towards the light, N is the normal and s is the shininess exponent. We can easily calculate L .N using ColorMatrixFilter. But what do we do about the exponent? My solution follows:</p>
<p>I recently noticed <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#paletteMap%28%29">this little function</a> in the <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html">BitmapData </a>class.</p>
<pre class="brush: as3; title: ;">
public function paletteMap (sourceBitmapData:BitmapData, sourceRect:Rectangle, destPoint:Point, redArray:Array = null, greenArray:Array = null, blueArray:Array = null, alphaArray:Array = null):void
</pre>
<div>What if I just remapped a linear gradient to an &#8220;exponential&#8221; gradient and use normal mapping with this new palette? That is:</div>
<pre class="brush: as3; title: ;">
var shininess:Number = 50;

for (var j:int = 0; j &lt; 256; j++)
{
	var alpha:Number = j / 255;
	newPalette[j] = Math.floor(Math.pow(alpha, shininess) * 255);
}
</pre>
<div><a href="http://glowinteractive.com/staging/jan/blog/cherry/cherry.html" target="_blank">Here&#8217;s the result</a> (use mouse to rotate the cherry).  It&#8217;s using a combination of <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html#threshold%28%29">threshold</a> and <a href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/filters/GlowFilter.html">GlowFilter</a> to simulate <a href="http://en.wikipedia.org/wiki/Bloom_%28shader_effect%29">light bloom</a>.</div>
<div>
<p><a href="http://glowinteractive.com/staging/jan/blog/cherry/cherry.html" target="_blank"><img class="alignleft size-full wp-image-465" title="codify_post_true_phong_shading" src="http://blog.glowinteractive.com/wp-content/uploads/2009/11/codify_post_true_phong_shading.jpg" alt="True Phong Shading in Flash 9" width="670" height="320" /></a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.glowinteractive.com/2009/11/true-phong-shading-in-flash-9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

