<?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>much ado about something &#187; Search Results  &#187;  reflection</title>
	<atom:link href="http://www.rictus.com/muchado/search/reflection/feed/rss2/" rel="self" type="application/rss+xml" />
	<link>http://www.rictus.com/muchado</link>
	<description>nj on design and development</description>
	<lastBuildDate>Thu, 14 Apr 2011 19:54:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Demystifying Molehill, part 1</title>
		<link>http://www.rictus.com/muchado/2011/02/28/demystifying-molehill-part-1/</link>
		<comments>http://www.rictus.com/muchado/2011/02/28/demystifying-molehill-part-1/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 23:15:27 +0000</pubDate>
		<dc:creator>nj</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[Gaming]]></category>
		<category><![CDATA[Molehill]]></category>

		<guid isPermaLink="false">http://www.rictus.com/muchado/?p=137</guid>
		<description><![CDATA[Another year, another new project. Flex Mobile is well underway, and I&#8217;ve transitioned over to a group within Adobe working on gaming technologies. Of course, Adobe products, and Flash in particular, are heavily used in game development, and we&#8217;ve started to increase our focus on gaming over the past year. One of the first key [...]]]></description>
			<content:encoded><![CDATA[<p>Another year, another new project. <a href="http://labs.adobe.com/technologies/flex/mobile/">Flex Mobile</a> is well underway, and I&#8217;ve transitioned over to a group within Adobe working on gaming technologies. Of course, Adobe products, and Flash in particular, are heavily used in game development, and we&#8217;ve started to increase our focus on gaming over the past year. One of the first key technologies we&#8217;re delivering is a GPU-accelerated 3D API in the Flash Player codenamed &#8220;Molehill&#8221;, which enables incredibly beautiful and incredibly performant 3D content to be built using Flash. And just last weekend, we&#8217;ve put up our <a href="http://labs.adobe.com/technologies/flashplatformruntimes/incubator/">first public pre-release of Molehill</a> as part of the Flash Player Incubator program on Adobe Labs.</p>
<p>Now, if you&#8217;re a hardcore 3D programmer, you&#8217;ll know exactly what to do with Molehill, and Thibault Imbert has a <a href="http://www.bytearray.org/?p=2555">great introduction to the API for you</a>. But if you&#8217;re anything like me, and your development experience has been in the world of 2D graphics or UI, you might find even this introductory material pretty head-scratching. Vertex and fragment shaders? Index buffers? Assembly language? LOLWUT?</p>
<p>I&#8217;ve just recently been learning more about GPU-based 3D programming myself, so I thought I&#8217;d try to make a molehill out of the 3D development mountain, and write an introduction to what this stuff is all about for those of us who are coming from the 2D world. In this first post, I&#8217;ll generally describe how modern GPUs work. I&#8217;m planning to write a follow-up post with more detail on how you actually work with the GPU for 3D graphics, and then another follow-up on how you can leverage the GPU for incredibly fast 2D graphics as well.</p>
<p>One caveat—I may say a few things that aren&#8217;t strictly true, mostly because I might be deliberately oversimplifying, but also because I might just be ignorant. Overall, I don&#8217;t think this picture of the world is too misleading, but please feel free to correct me in the comments.</p>
<p><strong>Update</strong>: One fundamental point I meant to make when I originally wrote this post, but forgot to add, is that Molehill rendering is completely separate from display list rendering. All of the drawing that Molehill does basically ends up in a single layer that essentially draws into the background behind all of your display list content—the two don&#8217;t interact at all. I&#8217;ll discuss how you can leverage Molehill for 2D in a future post.</p>
<h2><span id="more-137"></span>GPUs are scary and complicated!</h2>
<p>That was certainly what I assumed before I started reading up on them. It&#8217;s true that developing high-quality performant 3D renderers using a GPU requires a lot of cleverness and math. But it turns out that you can describe what modern (programmable) GPUs do very simply:</p>
<ol>
<li><strong>GPUs draw triangles really, really fast.</strong></li>
<li><strong>GPUs do basic matrix and vector arithmetic really, really fast.</strong></li>
<li><strong>It&#8217;s up to you to tell the GPU exactly what to do with those capabilities.</strong></li>
</ol>
<p>That&#8217;s pretty much it. At the end of the day, modern GPUs are basically just really fast at drawing triangles and doing certain kinds of math. So fast that, unlike the Flash-style rendering you&#8217;re used to, you don&#8217;t program it like a display list, with minimal updates when things change. Since even a tiny change in your camera location or viewing angle means that all of the objects in your world are in slightly different places on the screen and with slightly different perspective relative to your view, you generally just tell the GPU to redraw the whole screen every frame. (Of course, there&#8217;s lots of optimizations you should do to make this work faster&#8230;but fundamentally you&#8217;re redrawing a lot more stuff than you would normally think of doing in the CPU-based 2D world.)</p>
<h2>So what&#8217;s the big deal? I can draw a triangle really fast too.</h2>
<p>The real power of the GPU is in how you tell it to draw those triangles and what math you tell it to do. Conceptually, the model (for programmable GPUs, which is what Molehill supports) is actually pretty simple, which is why the Molehill API only has a couple of dozen methods. It&#8217;s using the model effectively that gets complicated, as we&#8217;ll see later.</p>
<p>Here&#8217;s the basic way you work with a programmable GPU for a standard 3D rendering scenario. In each frame:</p>
<ol>
<li><strong>Triangles. </strong>Send the GPU a bunch of triangles, expressed in terms of their vertices, as well as other associated data like texture coordinates (which map vertices to locations in a texture bitmap).</li>
<li><strong>Textures.</strong> Send the GPU a bunch of bitmaps to be used for textures that will be mapped onto triangles in step 4 below.</li>
<li><strong>Vertex shader.</strong> Upload a &#8220;vertex shader&#8221; program, which does some math on each vertex from step 1 in order to produce a final vertex position, as well as other optional outputs that are up to you.</li>
<li><strong>Fragment shader.</strong> Upload a &#8220;fragment (or pixel) shader&#8221; program. The GPU does built-in math to interpolate between the vertices on each triangle so it can call your pixel shader on each pixel in each triangle. Your shader does some math on each pixel, accessing textures from step 2 as necessary, in order to figure out what color that pixel should be.</li>
<li><strong>Z-buffer. </strong>The GPU has a &#8220;Z-buffer&#8221; that stores the depth of each pixel it draws on the screen. If a pixel from a new triangle would be behind the last pixel that was written to the same screen location, it doesn&#8217;t redraw the pixel.</li>
<li><strong>Lather, rinse, repeat.</strong> Repeat the above steps one or more times per frame.</li>
<li><strong>Present.</strong> Once you&#8217;re done with all your drawing for the frame, you swap the buffer the GPU has been drawing to out to the screen, and it&#8217;s presented to the user. Now you&#8217;re ready to clear the buffer and start all over again for the next frame.</li>
</ol>
<p>And that&#8217;s it. Simple, right?</p>
<h2>Wait a minute. What about colors, curved surfaces, lights, reflections, cameras, perspective projection, and so on?</h2>
<p>The GPU doesn&#8217;t know anything about any of that. This is the fundamental difference between older, &#8220;fixed-function&#8221; GPUs and modern programmable GPUs: the GPU makes very few assumptions about the actual meaning of all the data it&#8217;s processing. It knows about vertices, triangles, and pixels (or &#8220;fragments&#8221;, which are so-called because the edges of the triangle divide the pixels they cross into fragments). It also knows how to sample locations from texture bitmaps. Everything else—all the computation that actually decides which triangles to display, where the triangles should end up relative to the camera, or what colors the pixels should be given the current lights and textures—is either done by your application code on the CPU before you start uploading stuff to the GPU, or by the vertex and fragment shader programs that you upload to the GPU.</p>
<p>This means that you have complete power over how the GPU processes your geometry and textures. But with great power comes great responsibility—and a lot of coding, both in your application and in the shader programs you have to write to get anything to display.</p>
<p>Fortunately, you won&#8217;t have to write all that code yourself. Many members of the Flash community have written 3D frameworks and are now porting them to the Molehill API—including Alternativa, Away3D, Flare3D, Minko, Sophie3D, Yogurt3D, and more. In these frameworks, you don&#8217;t deal directly with the GPU, shaders, etc. at all. Instead, you typically interact with a &#8220;scene graph&#8221;, which is analogous to the Flash display list. It&#8217;s a persistent tree of objects that you can add and remove and set properties on. You just specify what geometry you want, how it should look, and where it should go in the world, and the framework takes care of sending it to the GPU and providing the appropriate shaders.</p>
<p>If the world of GPU programming doesn&#8217;t look like it&#8217;s for you, stop reading right now and go check out all those great frameworks. If you feel like digging in at a lower level, though, check out my next blog post, which will get into more details that bridge the gap between the high-level GPU description I gave above and <a href="http://www.bytearray.org/?p=2555">Thibault&#8217;s API introduction</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rictus.com/muchado/2011/02/28/demystifying-molehill-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Updated Reflection component</title>
		<link>http://www.rictus.com/muchado/2008/02/21/updated-reflection-component/</link>
		<comments>http://www.rictus.com/muchado/2008/02/21/updated-reflection-component/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 21:02:15 +0000</pubDate>
		<dc:creator>nj</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.rictus.com/muchado/2008/02/21/updated-reflection-component/</guid>
		<description><![CDATA[A number of people have written me over the past few months to mention that they&#8217;ve had trouble getting the Reflection component to work in various cases. I haven&#8217;t had time to look at each of the problems, but I do have an updated version of Reflector.as that may work better. If you&#8217;ve been having [...]]]></description>
			<content:encoded><![CDATA[<p>A number of people have written me over the past few months to mention that they&#8217;ve had trouble getting the <a href="http://www.rictus.com/muchado/2006/07/05/live-reflection-component/">Reflection component</a> to work in various cases. I haven&#8217;t had time to look at each of the problems, but I do have an <a href="http://www.rictus.com/muchado/wp-content/uploads/2008/02/reflector.as" title="Reflector.as">updated version of Reflector.as</a> that may work better. If you&#8217;ve been having trouble with the original Reflector code, try this one out and let me know if it fixes your problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rictus.com/muchado/2008/02/21/updated-reflection-component/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Reflection with blur</title>
		<link>http://www.rictus.com/muchado/2006/07/09/reflection-with-blur/</link>
		<comments>http://www.rictus.com/muchado/2006/07/09/reflection-with-blur/#comments</comments>
		<pubDate>Sun, 09 Jul 2006 00:32:52 +0000</pubDate>
		<dc:creator>nj</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.rictus.com/muchado/2006/07/09/reflection-with-blur/</guid>
		<description><![CDATA[Jason Langdon took my reflection component and made a new version that adds blur, which actually makes it look a good deal more realistic (higher levels of blur make it look like it&#8217;s on a less polished &#8220;table&#8221;). Very cool.]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.wrench.com.au/">Jason Langdon</a> took my <a href="http://www.rictus.com/muchado/2006/07/05/live-reflection-component/">reflection component</a> and made a <a href="http://blog.wrench.com.au/2006/07/08/live-reflection-component-with-a-twist/">new version</a> that adds blur, which actually makes it look a good deal more realistic (higher levels of blur make it look like it&#8217;s on a less polished &#8220;table&#8221;).  Very cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rictus.com/muchado/2006/07/09/reflection-with-blur/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Live &#8220;reflection&#8221; component</title>
		<link>http://www.rictus.com/muchado/2006/07/05/live-reflection-component/</link>
		<comments>http://www.rictus.com/muchado/2006/07/05/live-reflection-component/#comments</comments>
		<pubDate>Wed, 05 Jul 2006 07:27:23 +0000</pubDate>
		<dc:creator>nj</dc:creator>
				<category><![CDATA[design]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.rictus.com/muchado/2006/07/05/live-reflection-component/</guid>
		<description><![CDATA[UPDATE 2/21/2008: See this post for the latest version of Reflector.as. I&#8217;ll reintegrate it into the source code linked to from this post eventually, but for now you&#8217;ll need to download the code from this post, then replace Reflector.as with the version from the newer post. Okay, enough highfalutin&#8217; chatter. This entry actually has (arguably) [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE 2/21/2008: See <a href="http://www.rictus.com/muchado/2008/02/21/updated-reflection-component/">this post</a> for the latest version of Reflector.as. I&#8217;ll reintegrate it into the source code linked to from this post eventually, but for now you&#8217;ll need to download the code from this post, then replace Reflector.as with the version from <a href="http://www.rictus.com/muchado/2008/02/21/updated-reflection-component/">the newer post</a>.</strong></p>
<p>Okay, enough highfalutin&#8217; chatter.  This entry actually has (arguably) useful code in it.</p>
<p>The <a href="http://cow.neondragon.net/stuff/reflection/" target="_blank">reflection</a> effect is destined to become one of those gratuitous UI clichés, like brushed metal and gleaming highlights.  But hey, the kids seem to like it, so I figured I&#8217;d try to make a similar component in Flex.</p>
<p>Before jumping into the explanation, here&#8217;s the demo:</p>
<ul>
<li><a href="http://www.rictus.com/flex/LiveReflection/LiveReflection.html" target="_blank">View the demo</a></li>
<li><a href="http://www.rictus.com/flex/LiveReflection/srcview/index.html" target="_blank">View the source</a></li>
<li><a href="http://www.rictus.com/flex/LiveReflection/srcview/LiveReflection.zip">Download the source (ZIP, 12K)</a></li>
</ul>
<p>You can drag the panel around to watch the reflection follow it, and play with the sliders to tweak the look of the reflection.</p>
<p>I&#8217;m not the first to attempt this: Trey Long created a <a href="http://www.drisgill.com/index.cfm/2006/2/10/Flex-Reflection-Effect" target="_blank">reflection effect</a> in an early beta of Flex 2 (the demo pointed to from that link no longer works with the shipping version of Flash Player 9).  However, his version created static reflections—so, for example, you could see the reflection of a Button, but if you moused over or clicked on it, the reflection wouldn&#8217;t update to reflect (no pun intended) the visual changes to the Button.</p>
<p>I decided to make the reflection &#8220;live&#8221;—as you interact with the components being reflected, the reflection actually updates in (near) real-time.  I also componentized the reflector itself, so you can just target it at a component and it automatically positions itself appropriately.  I used code very similar to Trey&#8217;s reflection filter to render the reflection bitmap, though the way I actually draw it to the screen is a little different.</p>
<p>Read on for an explanation of the code: <span id="more-6"></span></p>
<p>The reflection component is called <code>Reflector</code>, in the <code>com.rictus.reflector</code> package. If you take a look at the demo application, <a href="http://www.rictus.com/flex/LiveReflection/srcview/source/LiveReflection.mxml.html" target="_blank">LiveReflection.mxml</a>,<br />
you&#8217;ll see that the invocation of the <code>Reflector</code> component is quite simple:</p>
<p><code>&lt;reflector:Reflector target="{panel}" alpha="{alphaSlider.value}" falloff="{falloffSlider.value}"/&gt;</code></p>
<p><code>Reflector</code> is a <code>UIComponent</code>, so you can stick it anywhere a <code>UIComponent</code> goes.  It defines two properties:</p>
<ul>
<li><strong><code>target</code></strong>: the component you want to reflect.  The reflector automatically tries to position itself below this component, so the target component should live inside an absolutely-positioned container (like a Canvas or a Panel with <code>layout="absolute"</code>), and the reflector should be inside the same container.</li>
<li><strong><code>falloff</code></strong>: a value between 0 and 1 that represents how much of the target component to reflect.  0 means to reflect none of the component, 1 means to reflect all of it, and values in between essentially set the ratio of the height of the component that will be reflected. In the demo, this defaults to 0.6.</li>
</ul>
<p>In addition, you&#8217;ll also want to set the <code>alpha</code> value to a low number (it defaults to 0.3 in the demo). Play around with the sliders in the demo to get a feel for how these values affect the look of the reflection.</p>
<p>To see how it works, look at the <a href="http://www.rictus.com/flex/LiveReflection/srcview/source/com/rictus/reflector/Reflector.as.html" target="_blank">source code</a> for <code>Reflector</code>.  <code>Reflector</code> listens for <code>updateComplete</code> events on its target, which fire every time the target&#8217;s <code>updateDisplayList()</code> method is called.  The <code>Reflector</code> then updates its own display list to draw the reflection.</p>
<p>Here are some notes on the various methods involved.</p>
<p><strong><code>set target()</code></strong>: This is where we register our listeners for events on the target. Note that when we register for the <code>updateComplete</code> event, we pass <code>true</code> for the <code>useCapture</code> argument to <code>addEventListener()</code>. This is necessary because <code>updateComplete</code> isn&#8217;t a &#8220;bubbling&#8221; event—it doesn&#8217;t automatically pass up to listeners that are set on ancestors of the updated item.  For example, in the demo, if we didn&#8217;t get update events from descendants, you wouldn&#8217;t see the reflection update when you twiddle one of the sliders; you would only see it update if the outer Panel itself changed.</p>
<p>We can get around this by attaching a &#8220;capture&#8221; listener for the event; because of the way the Flash event mechanism works, this lets us see update events for all descendants of the target component, not just the component itself. I&#8217;ll have more to say about capture in a future entry.</p>
<p><strong><code>handleTargetUpdate()</code>, <code>handleTargetMove()</code>, <code>handleTargetResize()</code></strong>: When the target is updated, we call <code>invalidateDisplayList()</code>, which tells Flex to redraw us (by calling <code>updateDisplayList()</code>) at the next available opportunity.  If the target is moved or resized, we update our own position and size to match.</p>
<p><strong><code>createBitmaps()</code></strong>: In order to avoid allocating and reallocating bitmaps every time we redraw, we allocate the bitmap storage once in <code>createBitmaps()</code>.  We throw away these cached bitmaps whenever the target or the size of the target changes, but otherwise we can just keep redrawing into them.  We also create the alpha gradient in <code>createBitmaps()</code>, since that gradient doesn&#8217;t need to change unless the target or its size changes:</p>
<p><strong><code>updateDisplayList()</code></strong>: This is where we do the actual drawing of the reflection.  The algorithm is pretty close to Trey&#8217;s original code:</p>
<ol>
<li>Draw the target component into <code>_targetBitmap</code>.</li>
<li>Combine the target bitmap with the pre-calculated alpha gradient and blit the result into <code>_resultBitmap</code>.</li>
<li>Create a matrix transform to flip the image upside down.</li>
<li>Use <code>beginBitmapFill()</code> and <code>drawRect()</code> to blit the bitmap into the display list.</li>
</ol>
<p>And that&#8217;s it!  Now, some caveats.</p>
<ul>
<li>You may notice that I set <code>showDataTips="false"</code> on the sliders in the demo.  I turned them off because the data tips don&#8217;t actually show up in the reflection (like vampires, I guess), since they&#8217;re not children of the Panel.</li>
<li>I also set <code>liveDragging="true"</code> on the sliders. Without this, they don&#8217;t seem to send out <code>updateComplete</code> events as they&#8217;re being dragged.  (One glitch in the demo is that if you click on the slider track rather than dragging it, the reflection doesn&#8217;t update as the slider animates to its new position, presumably because update events don&#8217;t get sent out during the animation even if <code>liveDragging</code> is set.)</li>
<li>This isn&#8217;t visible on the black background, but normally Panels have a small dropshadow around them.  That dropshadow doesn&#8217;t get drawn into the reflection; I&#8217;m guessing that <code>BitmapData.draw()</code> doesn&#8217;t render bitmap filters that are attached to the target component.</li>
</ul>
<p>In a future entry, I&#8217;ll describe the draggable panel component that&#8217;s included in this demo.</p>
<p>Please let me know if you find a bug, or have any questions about how it works.</p>
<p>(<strong>Addendum</strong>: Someone noted that this code is GPL&#8217;ed.  I did this because Trey&#8217;s original code was GPL&#8217;ed, and I didn&#8217;t go through the motions of reinventing the wheel.  Future code I publish will likely be under some flavor of Creative Commons license, for easier reuse.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rictus.com/muchado/2006/07/05/live-reflection-component/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
	</channel>
</rss>

