<?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>What Ev &#187; Aliens</title>
	<atom:link href="http://what-ev.net/tag/aliens/feed/" rel="self" type="application/rss+xml" />
	<link>http://what-ev.net</link>
	<description>Chris Cascioli - Graphics Programming &#124; Game Design</description>
	<lastBuildDate>Mon, 07 Mar 2011 04:48:54 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dynamic Billboarded Integer Rendering</title>
		<link>http://what-ev.net/2010/06/13/dynamic-billboarded-integer-rendering/</link>
		<comments>http://what-ev.net/2010/06/13/dynamic-billboarded-integer-rendering/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 21:06:48 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[My Graphics Programming]]></category>
		<category><![CDATA[My Stuff]]></category>
		<category><![CDATA[Aliens]]></category>
		<category><![CDATA[graphics programming]]></category>

		<guid isPermaLink="false">http://what-ev.net/?p=115</guid>
		<description><![CDATA[
A few months ago I was working on Aliens and implementing a new scoring system.  I ran into an issue: I needed a way to dynamically render a number (basically a point value) on a billboarded quad.  It had to be dynamic because the value of each item would change based on a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://what-ev.net/wordpress/wp-content/uploads/2010/06/scores.png" target="_blank"><img class="size-medium wp-image-119 alignnone" title="Aliens Dynamic Score 2" src="http://what-ev.net/wordpress/wp-content/uploads/2010/06/scores-300x145.png" alt="Aliens Dynamic Score" width="300" height="145" /></a></p>
<p>A few months ago I was working on Aliens and implementing a new scoring system.  I ran into an issue: I needed a way to dynamically render a number (basically a point value) on a billboarded quad.  It had to be dynamic because the value of each item would change based on a multiplier, which could also change at any time.  I could have done it as a UI element instead of actual geometry, but that didn&#8217;t feel right for the game.  I was committed to having the scores be billboarded quads in the scene.</p>
<p><img class="size-medium wp-image-118   alignright" title="Aliens Dynamic Score" src="http://what-ev.net/wordpress/wp-content/uploads/2010/06/score-261x300.png" alt="Aliens Dynamic Score" width="190" height="218" /></p>
<p>My first thought was to simply render a number to a texture and apply that texture to the quads.  This would work great if I needed few unique numbers.  I could render the current numbers to a few textures, or create a large texture with multiple numbers and map the numbers to different quads.  I quickly realized that this wouldn&#8217;t work for Aliens; if different items were worth different amounts, and your multiplier was frequently changing, the quantity of different numbers that were required would be changing as well.  Since the quads fade in and out, the player could destroy an object worth 500 points, get a multiplier, and then destroy the same type of object which is now worth 1000 points.  Both quads would be on the screen at the same time.  It could get hairy fast.</p>
<p>I needed the whole process to be dynamic, so that I could feed an integer to the shader and have it render.  I wrestled with it for a few days until I came up with the solution I ended up using: If I could get both the number of digits in a number, and any one digit based on the position inside the quad, I could render that number.  The results were exactly what I wanted: Dynamic numbers on geometry in the scene, in a font that matched the rest of the game.</p>
<p>So how does it work?  I&#8217;ve got some shader code below that shows the process.  Several pieces of data are passed in: the number itself, the number of digits, the age of the quad, a scale and a color.  The number, scale and color are self-explanatory.  The number of digits is used in several places.  It could have been calculated in the shader, but it seemed better to calculate it once when the quad was created.  The age of the quad is used to fade it in and out, as well as make it float upwards.  The numbers are pulled from a greyscale texture:</p>
<p><img class="size-full wp-image-116  alignnone" title="Digit Texture" src="http://what-ev.net/wordpress/wp-content/uploads/2010/06/digits.png" alt="Digit Texture" width="512" height="64" /></p>
<p>Below is my vertex shader code.  The first block of code does the billboarding and scaling.  The overall scale and Y position are based on age.  This allows the quad to grow and move upwards over time.  The width is based on the number of digits that we need to render; the quad auto-adjusts to fit the number.  The BigUV output parameter scales the overall UV by the number of digits, which is used in the pixel shader to determine which digit a particular pixel represents.  There are constants mixed in which adjust the height and alpha (to achieve the exact look I wanted).</p>
<div class="codecolorer-container glsl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="glsl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">// Calculate the position</span><br />
scale <span style="color: #000066;">*=</span> 1<span style="color: #000066;">.</span>0f <span style="color: #000066;">+</span> age<span style="color: #000066;">;</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span> <span style="color: #000066;">=</span> mul<span style="color: #000066;">&#40;</span>float4<span style="color: #000066;">&#40;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> mul<span style="color: #000066;">&#40;</span>World<span style="color: #000066;">,</span> View<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span><span style="color: #000066;">.</span><span style="color: #006600;">x</span> <span style="color: #000066;">+=</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span><span style="color: #000066;">.</span><span style="color: #006600;">x</span> <span style="color: #000066;">*</span> scale <span style="color: #000066;">*</span> numDigits<span style="color: #000066;">;</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span><span style="color: #000066;">.</span><span style="color: #006600;">y</span> <span style="color: #000066;">+=</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span><span style="color: #000066;">.</span><span style="color: #006600;">y</span> <span style="color: #000066;">*</span> scale <span style="color: #000066;">*</span> 1<span style="color: #000066;">.</span>5f <span style="color: #000066;">+</span> <span style="color: #000066;">&#40;</span>15<span style="color: #000066;">.</span>0f <span style="color: #000066;">*</span> age<span style="color: #000066;">&#41;</span> <span style="color: #000066;">+</span> 5<span style="color: #000066;">.</span>0f<span style="color: #000066;">;</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span> <span style="color: #000066;">=</span> mul<span style="color: #000066;">&#40;</span><span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">Position</span><span style="color: #000066;">,</span> Projection<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Pass the UVs through</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">UV</span> <span style="color: #000066;">=</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">UV</span><span style="color: #000066;">;</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">BigUV</span> <span style="color: #000066;">=</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">UV</span><span style="color: #000066;">.</span><span style="color: #006600;">x</span> <span style="color: #000066;">*</span> numDigits<span style="color: #000066;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Adjust the alpha based on age</span><br />
<span style="color: #333399; font-weight: bold;">output</span><span style="color: #000066;">.</span><span style="color: #006600;">Alpha</span> <span style="color: #000066;">=</span> saturate<span style="color: #000066;">&#40;</span>5<span style="color: #000066;">.</span>0f <span style="color: #000066;">-</span> <span style="color: #993333; font-weight: bold;">abs</span><span style="color: #000066;">&#40;</span>age <span style="color: #000066;">*</span> 10<span style="color: #000066;">.</span>0f <span style="color: #000066;">-</span> 5<span style="color: #000066;">.</span>0f<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></div></td></tr></tbody></table></div>
<p>The pixel shader code below determines which place the current pixel represents and which digit from the digit texture it needs to sample.</p>
<div class="codecolorer-container glsl default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="glsl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">// Get the current digit</span><br />
<span style="color: #000066; font-weight: bold;">float</span> place <span style="color: #000066;">=</span> numDigits <span style="color: #000066;">-</span> <span style="color: #993333; font-weight: bold;">floor</span><span style="color: #000066;">&#40;</span><span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">BigUV</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
<span style="color: #000066; font-weight: bold;">float</span> digit <span style="color: #000066;">=</span> <span style="color: #993333; font-weight: bold;">floor</span><span style="color: #000066;">&#40;</span><span style="color: #000066;">&#40;</span>number <span style="color: #000066;">%</span> <span style="color: #993333; font-weight: bold;">pow</span><span style="color: #000066;">&#40;</span><span style="color: #0000ff;">10</span><span style="color: #000066;">,</span> place<span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">/</span> <span style="color: #993333; font-weight: bold;">pow</span><span style="color: #000066;">&#40;</span><span style="color: #0000ff;">10</span><span style="color: #000066;">,</span> place <span style="color: #000066;">-</span> <span style="color: #0000ff;">1</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Calculate the correct U coord</span><br />
<span style="color: #000066; font-weight: bold;">float</span> u <span style="color: #000066;">=</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">BigUV</span><span style="color: #000066;">.</span><span style="color: #006600;">x</span> <span style="color: #000066;">-</span> <span style="color: #993333; font-weight: bold;">floor</span><span style="color: #000066;">&#40;</span><span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">BigUV</span><span style="color: #000066;">.</span><span style="color: #006600;">x</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span><br />
u <span style="color: #000066;">*=</span> 0<span style="color: #000066;">.</span>1f<span style="color: #000066;">;</span><br />
u <span style="color: #000066;">+=</span> digit <span style="color: #000066;">*</span> 0<span style="color: #000066;">.</span>1f<span style="color: #000066;">;</span><br />
<span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">UV</span><span style="color: #000066;">.</span><span style="color: #006600;">x</span> <span style="color: #000066;">=</span> u<span style="color: #000066;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;">// Return the correct color</span><br />
color<span style="color: #000066;">.</span><span style="color: #006600;">a</span> <span style="color: #000066;">=</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">Alpha</span><span style="color: #000066;">;</span><br />
<span style="color: #000000; font-weight: bold;">return</span> tex2D<span style="color: #000066;">&#40;</span>digitSampler<span style="color: #000066;">,</span> <span style="color: #333399; font-weight: bold;">input</span><span style="color: #000066;">.</span><span style="color: #006600;">UV</span><span style="color: #000066;">&#41;</span> <span style="color: #000066;">*</span> color<span style="color: #000066;">;</span></div></td></tr></tbody></table></div>
<p><a href="http://what-ev.net/wordpress/wp-content/uploads/2010/06/DynamicBillboardInteger.jpg" target="_blank"><img class="alignright size-thumbnail wp-image-117" title="Dynamic Billboarded Integer Rendering" src="http://what-ev.net/wordpress/wp-content/uploads/2010/06/DynamicBillboardInteger-80x150.jpg" alt="Dynamic Billboarded Integer Rendering" width="80" height="150" /></a></p>
<p>That&#8217;s about it!  I haven&#8217;t really done any optimization, and my math may be a little verbose, but it works pretty well.  I&#8217;ve been meaning to make a post about this for a while, but I haven&#8217;t been working on Aliens since development started on Blocks.  Once Blocks wraps up, I&#8217;ll probably revisit this (and start refactoring most of Aliens).  I made a simple <a href="http://what-ev.net/wordpress/wp-content/uploads/2010/06/DynamicBillboardInteger.jpg" target="_blank">info-graphic</a> on the overall process, which may or may not help visualize what&#8217;s going on.</p>
<p>-Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://what-ev.net/2010/06/13/dynamic-billboarded-integer-rendering/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

