<?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>Lost in the Triangles &#187; work</title>
	<atom:link href="http://aras-p.info/blog/tags/work/feed/" rel="self" type="application/rss+xml" />
	<link>http://aras-p.info/blog</link>
	<description>Random thoughts of a triangle pusher</description>
	<lastBuildDate>Fri, 16 Jul 2010 07:04:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Four years ago today&#8230;</title>
		<link>http://aras-p.info/blog/2010/01/04/four-years-ago-today/</link>
		<comments>http://aras-p.info/blog/2010/01/04/four-years-ago-today/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 17:54:41 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=466</guid>
		<description><![CDATA[&#8230;I took a plane to Copenhagen. Oh, this sounds familiar&#8230; Well ok, it all started a bit before: I exchanged some emails with David and Joachim and they invited me for a gamejam in their office. Then one thing led to another, I was young and needed money (oops! wrong topic) and on January 2006 [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;I took a plane to Copenhagen. <a href="http://aras-p.info/blog/2008/01/15/about-two-years-ago/"><em>Oh, this sounds familiar&#8230;</em></a></p>
<p>Well ok, it all started a bit before: <span id="more-466"></span><br />
<img src="http://aras-p.info/blog/wp-content/uploads/2010/01/futureofmiddleware.png" alt="" title="Future of Middleware" width="548" height="19" class="alignnone size-full wp-image-472" /></p>
<p>I exchanged some emails with <a href="http://blogs.unity3d.com/author/david/">David</a> and <a href="http://blogs.unity3d.com/author/joe/">Joachim</a> and they invited me for a <a href="http://unity3d.com/pakimono/">gamejam</a> in their office. Then one thing led to another, I was young and needed money <em>(oops! wrong topic)</em> and on January 2006 I started working on this thing called &#8220;Unity&#8221;.</p>
<p>Unity was at version <a href="http://unity3d.com/unity/whats-new/unity-1.2">1.2.1</a> then. Since then we&#8217;ve released about a dozen new versions, added hundreds (or thousands?) of new features, a handful of new platforms and <a href="http://blogs.unity3d.com/2009/11/13/blast-from-the-past-pt-3-a-growing-company/">have grown a lot</a>.</p>
<p><img src="http://aras-p.info/blog/wp-content/uploads/2010/01/insanesales.png" alt="" title="Sales are INSANE!!!111" width="333" height="72" class="alignright size-full wp-image-474" />Also, we stopped saying &#8220;Sales are INSANE!!!!11&#8243; whenever they exceeded a whopping ten thousand euros per week. <em><span style="color: #808080;">Seriously, that much money in 2006 was a big thing. Our Windows build machine was a single core Celeron with 512MB RAM because that&#8217;s what we could afford!</span></em> Well ok, we&#8217;re still saying &#8220;sales are insane!&#8221; from time to time, just the threshold has gone way up.</p>
<p style="clear:both"><img src="http://aras-p.info/blog/wp-content/uploads/2010/01/greatsuccess.png" alt="" title="Great Success" width="220" height="121" class="alignright size-full wp-image-473" />Occasionally we&#8217;d get excited about strangest things. I think this email is about some car model from ATI that was on front page of <a href="http://aras-p.info/blog/wp-content/uploads/2010/01/website2006.png">our website in 2006</a>. It&#8217;s beyond me why we&#8217;d put a car on Unity website, but somehow it seemed to make sense at the time.</p>
<p style="clear:both">It would take too much space to list all the awesome things that happened in those four years. I got to work on some things too, like <a href="http://aras-p.info/blog/wp-content/uploads/2010/01/200603-firefox.jpg">Windows Web Player</a>, <a href="http://aras-p.info/blog/wp-content/uploads/2010/01/200702-fastd3d.png">Direct3D renderer</a>, <a href="http://aras-p.info/blog/2007/08/28/lolshadows/">shadows</a>, <a href="http://blogs.unity3d.com/2009/05/16/blast-from-the-recent-past-unity-25/">editor for Windows</a> and whatnot. But I mostly concentrate on creating trouble, which does not seem to hinder Unity that much. I need to get more efficient!</p>
<p>Seriously though, it has been an amazing ride so far, and I hope it will only become better. Thanks to everyone at Unity Technologies and the community!</p>
<p>Rock on!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2010/01/04/four-years-ago-today/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Deferred Cascaded Shadow Maps</title>
		<link>http://aras-p.info/blog/2009/11/04/deferred-cascaded-shadow-maps/</link>
		<comments>http://aras-p.info/blog/2009/11/04/deferred-cascaded-shadow-maps/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 14:42:08 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=434</guid>
		<description><![CDATA[Reading &#8220;Rendering Technology at Black Rock Studios&#8221; made me realize that cascaded shadow maps I did 2+ years ago in Unity 2.0 are probably called &#8220;deferred shadowing&#8221;. Since I never wrote how they are done&#8230; here: The process is roughly this (all of this is DX9 level tech on PCs; later tech or consoles could [...]]]></description>
			<content:encoded><![CDATA[<p>Reading &#8220;<a href="http://www.bungie.net/News/content.aspx?type=topnews&#038;link=Siggraph_09">Rendering Technology at Black Rock Studios</a>&#8221; made me realize that cascaded shadow maps I did 2+ years ago in Unity 2.0 are <em>probably</em> called &#8220;deferred shadowing&#8221;. Since I never wrote how they are done&#8230; here:</p>
<p>The process is roughly this (all of this is DX9 level tech on PCs; later tech or consoles could and should use more optimizations):</p>
<ol>
<li>Render shadow map cascades. All of them packed into one shadow map via viewports.</li>
<li>Collect shadows into screen sized render target. This is the shadow term.</li>
<li>Blur the shadow term.</li>
<li>In regular forward rendering, use shadow term in screen space.</li>
</ol>
<p>More detail:</p>
<p><strong>Render Shadow Cascades</strong></p>
<p>Nothing fancy here. All cascades packed into a single shadow map. For example two 512&#215;512 cascades would be packed into 1024&#215;512 shadow map side by side.</p>
<p><strong>Screen-space Shadow Term</strong></p>
<p>Render all shadow receivers with a shader that &#8220;collects&#8221; shadow map term. In effect, shadows from all cascades are collected into a screen-sized texture. After this step, original cascaded shadowmaps are not needed anymore.</p>
<p>Unity supports up to 4 shadow map cascades, which neatly fit into a float4 register in the pixel shader. Correct cascade is sampled just once, <em>without</em> using static or dynamic branching. Pixel shader pseudocode:</p>
<blockquote><pre>
float4 near = float4 (z >= _LightSplitsNear);
float4 far = float4 (z < _LightSplitsFar);
float4 weights = near * far;
float2 coord =
    i._ShadowCoord[0] * weights.x +
    i._ShadowCoord[1] * weights.y +
    i._ShadowCoord[2] * weights.z +
    i._ShadowCoord[3] * weights.w;
float sm = tex2D (_ShadowMapTexture, coord.xy).r;
</pre>
</blockquote>
<p>Additionally, shadow fadeout is applied here (shadows in Unity can be cast up to specified distance from the camera, and they fade out when approaching that distance).</p>
<p>After this I end up having shadow term in screen space. Note that here I do not do any shadow map filtering; that is done in screen space later.</p>
<p>On PCs in DX9 there is (or there was?) no easy/sane way to read depth buffer in the pixel shader, so while collecting shadows the shader also outputs depth packed into two channels of the render target.</p>
<p><strong>Screen-space Shadow Blur</strong></p>
<p>Previous step results in screen space shadow term and depth. Shadow term is blurred into another render target, using a spatially varying Poisson disc-like filter.</p>
<p>Filter size depends on depth (shadow boundaries closer to the camera are blurred more). Filter also discards samples if difference in depth is larger <em>than something</em>, to avoid blurring over object boundaries. It's not totally robust, but seems to work quite well.</p>
<p><strong>Using shadow term in forward rendering</strong></p>
<p>In forward rendering, this blurred shadow term texture is used. Here shadow term already has filtering &#038; fadeout applied, and the shaders do not need to know anything about shadow cascades. Just read pixel from the texture and use it in lighting computation. Done!</p>
<p><strong>Fin</strong></p>
<p>Back then I didn't know this would be called "deferred" <em>(that would probably have scared me away!)</em>. I don't know if this approach is any good, but so far it works quite well for Unity needs. Also, reduces shader permutation count a lot, which I like.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/11/04/deferred-cascaded-shadow-maps/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Fixing bugs, in Tom Waits&#8217; words</title>
		<link>http://aras-p.info/blog/2009/09/20/fixing-bugs-in-tom-waits-words/</link>
		<comments>http://aras-p.info/blog/2009/09/20/fixing-bugs-in-tom-waits-words/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 07:19:27 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=431</guid>
		<description><![CDATA[Mixing a sprint of bug fixing before the release and Tom Waits&#8217; music results in interesting combination. For example, Crossroads describes bug fixing process perfectly: And that&#8217;s where ol&#8217; George found himself out there at the FogBugz Fixin&#8217; the devil&#8217;s bugs Now, a man figures it&#8217;s his bugs and he&#8217;ll assign whom he wants But [...]]]></description>
			<content:encoded><![CDATA[<p>Mixing a sprint of bug fixing before the release and Tom Waits&#8217; music results in interesting combination. For example, <a href="http://en.wikipedia.org/wiki/The_Black_Rider_(album)">Crossroads</a> describes bug fixing process perfectly:</p>
<blockquote><p>And that&#8217;s where ol&#8217; George found himself out there at the FogBugz<br />
Fixin&#8217; the devil&#8217;s bugs<br />
Now, a man figures it&#8217;s his bugs and he&#8217;ll assign whom he wants<br />
But it don&#8217;t always work out that way<br />
You see, some bugs are special for a certain target<br />
A certain platform, or a certain person<br />
And no matter whom you&#8217;re assignin&#8217;, that&#8217;s where the bug &#8216;ll end up<br />
And in the moment of assigning your mouse turns into a dowser&#8217;s wand<br />
And clicks where the bug wants to go.</p></blockquote>
<p>Uhm. Yeah.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/09/20/fixing-bugs-in-tom-waits-words/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Strided blur and other tips for SSAO</title>
		<link>http://aras-p.info/blog/2009/09/17/strided-blur-and-other-tips-for-ssao/</link>
		<comments>http://aras-p.info/blog/2009/09/17/strided-blur-and-other-tips-for-ssao/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 07:59:01 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[gpu]]></category>
		<category><![CDATA[papers]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=409</guid>
		<description><![CDATA[If you&#8217;re new to SSAO, here are good overview blog posts: meshula.net and levelofdetail. Some tips and an idea on strided blur below. Bits and pieces I found useful SSAO can be generated at a smaller resolution than screen, with depth+normals aware upsample/blur step. If random offset vector points away from surface normal, flip it. [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re new to SSAO, here are good overview blog posts: <a href="http://meshula.net/wordpress/?p=145">meshula.net</a> and <a href="http://levelofdetail.wordpress.com/2008/02/10/2007-the-year-ssao-broke/">levelofdetail</a>. Some tips and an idea on strided blur below.</p>
<p><span id="more-409"></span><strong>Bits and pieces I found useful</strong></p>
<ul>
<li>SSAO can be generated at a smaller resolution than screen, with depth+normals aware upsample/blur step.</li>
<li>If random offset vector points away from surface normal, flip it. This makes random vectors be in the upper hemisphere, which reduces false occlusion on flat surfaces. Of course this requires having surface normals.</li>
<li>When generating random vectors for your AO kernel:
<ul>
<li>Generate vectors <i>inside</i> unit sphere (not <i>on</i> unit sphere).</li>
<li>Use energy minimization to distribute your samples better, especially at low sample counts. See <a href="http://www.malmer.nu/index.php/2008-04-11_energy-minimization-is-your-friend">malmer.ru</a> blog post.</li>
</ul>
</li>
<li>In your AO blurring/upsampling step: no need to sample each pixel for blur. Just skip some of them, i.e. make kernel offsets larger. See below.</li>
</ul>
<p><strong>Strided blur for AO</strong></p>
<p>Normally you&#8217;d blur AO term using some sort of standard blur, for example separable Gaussian: horizontal blur, followed by vertical blur. How one can imagine horizontal blur kernel:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/blur1.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/blur1.png" alt="Horizontal Blur Kernel" title="Horizontal Blur Kernel" width="291" height="51" class="alignnone size-full wp-image-420" /></a></p>
<p>Here&#8217;s how <a href="http://runevision.com/">Rune</a> taught me how to blur better:</p>
<blockquote>
<dl>
<dt>Rune:</dt>
<dd>The other thing is the blur. I tried to make the blur 4 times stronger, and it looks much better IMO without any artifacts I could see. I could even use 4x downsampling with that blur amount and still get acceptable results.</dd>
<dt>Aras:</dt>
<dd>how did you make it 4x stronger? <i>(I was going to say that blur step is already quite expensive, and I don&#8217;t want to add more samples to make it even more expensive, yadda yadda)</i></dd>
<dt>Rune:</dt>
<dd>m_SSAOMaterial.SetVector (&#8220;_TexelOffsetScale&#8221;, m_IsOpenGL ?<br />
	&nbsp;&nbsp;new Vector4 (<b>4</b>,0,1.0f/m_Downsampling,0) :<br />
	&nbsp;&nbsp;new Vector4 (<b>4.0f</b>/source.width,0,0,0));<br />
	And similar for vertical.</dd>
<dt>Aras:</dt>
<dd>hmm. that&#8217;s strange :)</dd>
<dt>Rune:</dt>
<dd>I have no idea what I&#8217;m doing of course but it looks good.</dd>
<dt>Aras:</dt>
<dd>so this way it does not do Gaussian on 9&#215;9 pixels, but instead only takes each 4th pixel. Wider area, but&#8230; it should not work! :)</dd>
<dt>Rune:</dt>
<dd>It creates a very fine pattern at pixel level but it&#8217;s way more subtle than the noise you get otherwise.</dd>
<dt>Aras:</dt>
<dd>ok <i>(hides in the corner and weeps)</i></dd>
</dl>
</blockquote>
<p>So yeah. The blur kernel can be &#8220;spread&#8221; to skip some pixels, effectively resulting in a larger blur radius for the same sample count:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/blur2.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/blur2.png" alt="Blur with 2 pixel stride" title="Blur with 2 pixel stride" width="291" height="51" class="alignnone size-full wp-image-421" /></a></p>
<p>Or even this:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/blur3.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/blur3.png" alt="Blur with 3 pixel stride" title="Blur with 3 pixel stride" width="291" height="51" class="alignnone size-full wp-image-422" /></a></p>
<p>Yes, it&#8217;s not correct blur. <strong>But that&#8217;s okay</strong>, we&#8217;re not building nuclear reactors that depend on SSAO blur being accurate. <em>If you are, SSAO is probably a wrong approach anyway, I&#8217;ve heard it&#8217;s not that useful for nuclear stuff</em>.</p>
<p>I&#8217;m not sure how this blur should be called. Strided blur? Interleaved blur? Interlaced blur? Or maybe everyone is doing that already and it has a well established name? Let me know.</p>
<p>Some images of blur in action. Raw AO term (very low &#8211; 8 &#8211; sample count and increased contrast on purpose):<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO1raw.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO1raw-500x270.png" alt="Raw AO at low sample count" title="Raw AO at low sample count" width="500" height="270" class="alignnone size-medium wp-image-412" /></a></p>
<p>Regular 9&#215;9 blur (does not blur over depth+normals discontinuities):<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO2blur.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO2blur-500x270.png" alt="Blurred AO" title="Blurred AO" width="500" height="270" class="alignnone size-medium wp-image-413" /></a></p>
<p>Blur that goes in 2 pixel stride (effectively 17&#215;17):<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO3blur2.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO3blur2-500x271.png" alt="Blurred AO with stride 2" title="Blurred AO with stride 2" width="500" height="271" class="alignnone size-medium wp-image-414" /></a><br />
It does create a fine interleaved pattern because it skips pixels. But you get wider blur!<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO3blur2mag.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO3blur2mag.png" alt="Blurred AO with stride 2, magnified" title="Blurred AO with stride 2, magnified" width="256" height="244" class="alignnone size-full wp-image-415" /></a></p>
<p>Blur that goes in 3 pixel stride (effectively 25&#215;25):<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO4blur3.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO4blur3-500x269.png" alt="Blurred AO with stride 3" title="Blurred AO with stride 3" width="500" height="269" class="alignnone size-medium wp-image-416" /></a><br />
At 3 pixel stride the artifacts are becoming apparent. But hey, this is very<br />
low AO sample count, increased contrast and no textures in the scene.<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO4blur3mag.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO4blur3mag.png" alt="Blured AO with stride 3, magnified" title="Blured AO with stride 3, magnified" width="256" height="244" class="alignnone size-full wp-image-417" /></a></p>
<p>For sake of completeness, the same raw AO term, but computed at 2&#215;2 smaller resolution (still using low sample count etc.):<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO5down2.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO5down2-500x270.png" alt="AO computed at lower resolution" title="AO computed at lower resolution" width="500" height="270" class="alignnone size-medium wp-image-418" /></a></p>
<p>Now, 2&#215;2 smaller AO, blurred with 3 pixels stride:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/AO6down2blur3.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/AO6down2blur3-499x272.png" alt="AO at lower resolution, blurred with 3 pixel stride" title="AO at lower resolution, blurred with 3 pixel stride" width="499" height="272" class="alignnone size-medium wp-image-419" /></a></p>
<p>Happy blurring!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/09/17/strided-blur-and-other-tips-for-ssao/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Usability depends on context!</title>
		<link>http://aras-p.info/blog/2009/09/14/usability-depends-on-context/</link>
		<comments>http://aras-p.info/blog/2009/09/14/usability-depends-on-context/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 13:16:02 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=387</guid>
		<description><![CDATA[Here&#8217;s a little story on how usability decisions need to depend on context. In Unity editor pretty much any window can be &#8220;detached&#8221; from the main window. An obvious use case is putting it onto a separate monitor. But of course you can just end up having a ton of detached windows overlapping each other. [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a little story on how usability decisions need to depend on context.</p>
<p>In Unity editor pretty much any window can be &#8220;detached&#8221; from the main window. An obvious use case is putting it onto a separate monitor. But of course you can just end up having a ton of detached windows overlapping each other.</p>
<p>Here I have four windows in total on OS X:<span id="more-387"></span><br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/OSXOverlapped.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/OSXOverlapped-500x324.jpg" alt="Overlapped Windows on OS X" title="Overlapped Windows on OS X" width="500" height="324" class="size-medium wp-image-389" /></a></p>
<p>Here I have four windows on Windows:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/WinOverlapped.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/WinOverlapped-500x312.jpg" alt="Overlapped Windows on Windows" title="Overlapped Windows on Windows" width="500" height="312" class="size-medium wp-image-393" /></a></p>
<p>However, users of OS X and Windows are used to applications behaving differently.</p>
<p>On OS X, it is <em>very</em> common that a single application has many overlapping windows. Usually users don&#8217;t have problems finding their windows either, thanks to Exposé. Press a key, voilà, here they are:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/OSXExpose.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/OSXExpose-500x316.jpg" alt="Exposé on OS X" title="Exposé on OS X" width="500" height="316" class="size-medium wp-image-388" /></a></p>
<p>On Windows, there is no Exposé. So there&#8217;s a problem: when a detached window is obscured by another window, how do you get to it? One would ask &#8220;well, what&#8217;s wrong in having windows partially overlapped, like in above screenshot?&#8221;, to which I&#8217;d say &#8220;you&#8217;re a Mac user&#8221;.</p>
<p>Windows users do not have a ton of windows on screen. They tend to maximize the application they are currently working with. <em>I was doing this myself</em> all the time, and it took 3 years of Mac laptop usage before I stopped maximizing everything on my Windows box!</p>
<p>So what a typical Windows user might see when using Unity is this. Now, where are the other three detached windows?<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/WinMaximized.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/WinMaximized-500x312.jpg" alt="Maximized" title="Maximized" width="500" height="312" class="size-medium wp-image-392" /></a></p>
<p>On Windows, it is <em>very uncommon</em> for a single application to have many overlapped windows. When an application does that, the &#8220;detached&#8221; windows are always positioned on top of the main window. There are some applications that do not do this (yes I&#8217;m looking at you GIMP), and almost everyone is not happy with their usability.</p>
<p>So we decided to take this context into account. Windows users do not have Exposé, <em>and</em> they expect &#8220;detached&#8221; windows to be always on top of the main window. Unity 2.6 will do this soon.<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/WinInFront.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/WinInFront-500x312.jpg" alt="In Front on Windows" title="In Front on Windows" width="500" height="312" class="size-medium wp-image-391" /></a></p>
<p>Of course, you still can dock all the windows together and this whole &#8220;windows are obscured by other windows&#8221; issue goes away:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/09/WinDocked.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/09/WinDocked-500x312.jpg" alt="Docked on Windows" title="Docked on Windows" width="500" height="312" class="size-medium wp-image-390" /></a></p>
<p><em>Hmm&#8230; I think the screenshots above show two new big features in upcoming Unity 2.6. Preemptive note: UI of the stuff above is not final. Anything might change, don&#8217;t become attached to any particular pixel!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/09/14/usability-depends-on-context/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Compact Normal Storage for small g-buffers</title>
		<link>http://aras-p.info/blog/2009/08/04/compact-normal-storage-for-small-g-buffers/</link>
		<comments>http://aras-p.info/blog/2009/08/04/compact-normal-storage-for-small-g-buffers/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 09:39:51 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[d3d]]></category>
		<category><![CDATA[gpu]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=377</guid>
		<description><![CDATA[I&#8217;ve been experimenting with compact storage of view space normals for small g-buffers. Think about storing depth and normal in a single 8 bit/channel RGBA texture. Here are my findings &#8211; with error visualization and shader performance numbers for some GPUs. If you know any other method to encode/store normals in a compact way, please [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been experimenting with compact storage of view space normals for small g-buffers. Think about storing depth and normal in a single 8 bit/channel RGBA texture.</p>
<p><a href="http://aras-p.info/texts/CompactNormalStorage.html"><strong>Here are my findings</strong></a> &#8211; with error visualization and shader performance numbers for some GPUs.</p>
<p>If you know any other method to encode/store normals in a compact way, please let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/08/04/compact-normal-storage-for-small-g-buffers/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Implementing fixed function T&amp;L in vertex shaders</title>
		<link>http://aras-p.info/blog/2009/06/09/implementing-fixed-function-tl-in-vertex-shaders/</link>
		<comments>http://aras-p.info/blog/2009/06/09/implementing-fixed-function-tl-in-vertex-shaders/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 06:08:50 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[d3d]]></category>
		<category><![CDATA[gpu]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=364</guid>
		<description><![CDATA[Almost half a year ago I was wondering how to implement T&#038;L in vertex shaders. Well, finally I implemented it for upcoming Unity 2.6. I wrote some sort of a technical report here. In short, I&#8217;m combining assembly fragments and doing simple temporary register allocation, which seems to work quite well. Performance is very similar [...]]]></description>
			<content:encoded><![CDATA[<p>Almost half a year ago I was wondering <a href="http://aras-p.info/blog/2009/01/22/fixed-function-lighting-in-vertex-shader-how/">how to implement T&#038;L in vertex shaders</a>.</p>
<p>Well, finally I implemented it for upcoming Unity 2.6. I wrote some sort of a <a href="http://aras-p.info/texts/VertexShaderTnL.html"><strong>technical report here</strong></a>.</p>
<p>In short, I&#8217;m combining assembly fragments and doing simple temporary register allocation, which seems to work quite well. Performance is very similar to using fixed function (I know it&#8217;s implemented as vertex shaders internally by the runtime/driver) on several different cards I tried (Radeon HD 3xxx, GeForce 8xxx, Intel GMA 950).</p>
<p>What was unexpected: the most complex piece is not the vertex lighting! Most complexity is in how to route/generate texture coordinates and transform them. Huge combination explosion there.</p>
<p>Otherwise &#8211; I like! Here&#8217;s a link to the <a href="http://aras-p.info/texts/VertexShaderTnL.html">article again</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/06/09/implementing-fixed-function-tl-in-vertex-shaders/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Unity 2.5 is out</title>
		<link>http://aras-p.info/blog/2009/03/19/unity-25-is-out/</link>
		<comments>http://aras-p.info/blog/2009/03/19/unity-25-is-out/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 13:13:48 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=304</guid>
		<description><![CDATA[Unity 2.5 is finally released. In summary: Here&#8217;s what&#8217;s new. Here&#8217;s the download page. My 11th Unity release since I joined 3+ years ago. This is quite a crazy release that involved almost complete editor tools rewrite and lots of other juggling. Was not exactly a walk in the park, but it&#8217;s done now. Meet [...]]]></description>
			<content:encoded><![CDATA[<p>Unity 2.5 is finally released. In summary:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/03/unity25.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2009/03/unity25-500x241.jpg" alt="Unity 2.5" title="Unity 2.5" width="500" height="241" class="alignnone size-medium wp-image-305" /></a></p>
<p>Here&#8217;s <a href="http://unity3d.com/unity/whats-new/unity-2.5">what&#8217;s new</a>. Here&#8217;s the <a href="http://unity3d.com/unity/download">download page</a>.</p>
<p>My 11th Unity release since I joined <a href="http://aras-p.info/blog/2006/01/10/switched-jobs-almost-back-in-this-crazy-industry/">3+ years ago</a>. This is quite a crazy release that involved <em>almost complete</em> editor tools rewrite and lots of other juggling. Was not exactly a walk in the park, but it&#8217;s done now. Meet me at <a href="http://www.gdconf.com/">GDC in San Francisco</a> next week and I&#8217;ll tell you the war stories (Unity booth is 5110 NH).</p>
<p>Here&#8217;s the obligatory source code commits graph:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/03/25commits.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/03/25commits-500x170.png" alt="2.5 svn commits" title="2.5 svn commits" width="500" height="170" class="alignnone size-medium wp-image-308" /></a><br />
18 people involved in source code, 5315 commits, 18501 file changes. Of course, svn commits do not <em>mean</em> anything&#8230; I&#8217;m just fascinated by graphs and numbers.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/03/19/unity-25-is-out/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Another Vista review (after 6 months of usage)</title>
		<link>http://aras-p.info/blog/2009/03/18/another-vista-review-after-6-months-of-usage/</link>
		<comments>http://aras-p.info/blog/2009/03/18/another-vista-review-after-6-months-of-usage/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 12:16:37 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=294</guid>
		<description><![CDATA[Ok, I don&#8217;t exactly like Windows Vista. But I just spent 6 months using Vista as my primary OS at work&#8230; because everyone else was using XP, and someone had to make sure everything works on Vista as well. So it was me. In summary, Vista is not that bad. Once you get used to [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, I <a href="http://aras-p.info/blog/2008/06/03/the-problem-with-vista/">don&#8217;t exactly like Windows Vista</a>. But I just spent 6 months using Vista as my primary OS at work&#8230; because everyone else was using XP, and <em>someone</em> had to make sure everything works on Vista as well. So it was me.</p>
<p>In summary, Vista is not <em>that bad</em>.</p>
<p>Once you get used to changes in Explorer, different skin and so on &#8211; it&#8217;s actually usable. I think they have made some real improvements in the underlying technology, too bad they managed to &#8220;compensate&#8221; for all of that by inconsistencies and lack of polish in user interface.</p>
<p>At this point it&#8217;s minor quirks in UI that annoy me, but apart from that, Vista is okay. Look:</p>
<p><img src="http://aras-p.info/blog/wp-content/uploads/2009/03/vista-iconoverlay.png" alt="Icon overlay blending" title="Icon overlay blending" width="144" height="152" class="alignnone size-full wp-image-295" /><br />
Who implemented blending of icon overlays and do they still have a job? No sir, that shield icon is <em>not</em> properly blended here!</p>
<p><img src="http://aras-p.info/blog/wp-content/uploads/2009/03/vista-burn.png" alt="Burn icon" title="Burn icon" width="323" height="132" class="alignnone size-full wp-image-296" /><br />
Who thought it&#8217;s a good idea to make the Burn icon bright red? In 6 months, I <em>never</em> used it. Why is it the brightest thing in the whole Explorer window?</p>
<p><img src="http://aras-p.info/blog/wp-content/uploads/2009/03/vista-upfolder.png" alt="Up one folder" title="Up one folder" width="366" height="143" class="alignnone size-full wp-image-297" /><br />
Try going one folder up without resorting to this drop down menu. Utilities is the <em>current</em> folder here. <del datetime="2009-03-18T12:52:27+00:00">And no, there&#8217;s no keyboard shortcut for &#8220;go up&#8221; either (there was in XP, which was perfect)</del>.</p>
<p><img src="http://aras-p.info/blog/wp-content/uploads/2009/03/vista-shutdown.png" alt="Shutdown awesome" title="Shutdown awesome" width="283" height="158" class="alignnone size-full wp-image-298" /><br />
And of course, the awesome shutdown menu. The two buttons &#8211; <em>never</em> used them. What I always use is &#8220;Shut Down&#8221; from the menu. And let&#8217;s not even talk about all the choices in the menu (no, more choices is not always better).</p>
<p>So yeah. It&#8217;s not stellar, it has tons of small annoyances (and some large ones &#8211; try developing web plugins with UAC on&#8230;), but it&#8217;s usable. I might have gotten used to it by now, actually.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/03/18/another-vista-review-after-6-months-of-usage/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Fixed function lighting in vertex shader &#8211; how?</title>
		<link>http://aras-p.info/blog/2009/01/22/fixed-function-lighting-in-vertex-shader-how/</link>
		<comments>http://aras-p.info/blog/2009/01/22/fixed-function-lighting-in-vertex-shader-how/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 20:32:49 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[d3d]]></category>
		<category><![CDATA[gpu]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=261</guid>
		<description><![CDATA[Sometime soon I&#8217;ll have to implement fixed function lighting pipeline in vertex shaders. Why? Because mixing fixed function and vertex shaders in multiple passes does not guarantee identical transformation results, thus requiring depth bias or projection matrix tweaks, which leads to various artifacts that annoy people to hell. I don&#8217;t really know why that happens, [...]]]></description>
			<content:encoded><![CDATA[<p>Sometime soon I&#8217;ll have to implement fixed function lighting pipeline in vertex shaders. Why? Because mixing fixed function and vertex shaders in multiple passes does not guarantee identical transformation results, thus requiring depth bias or projection matrix tweaks, which leads to <a href="http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/">various artifacts</a> that annoy people to hell.</p>
<p>I don&#8217;t really know <em>why</em> that happens, because it seems that most modern cards don&#8217;t have fixed function units, so internally they are running shaders anyway. DX9 runtime on Vista&#8217;s WDDM also seems to be only handling shaders to the driver internally. Still, for some reason somewhere the precision does not match&#8230;</p>
<p>How such a task should be approached?</p>
<p>My requirements are:</p>
<ul>
<li>Should handle any possible state combination in D3D fixed function T&#038;L.</li>
<li>D3D 9.0c, using vertex shader 2.0 is ok. For now I don&#8217;t care about OpenGL.</li>
<li>No HLSL at runtime. I don&#8217;t want to add a megabyte or more to Unity web player just for HLSL. DX9 shader assembly is ok, because we already have the assembler code.</li>
<li>Should work as fast (or close to) as the regular fixed function pipeline.</li>
</ul>
<p>I looked at ATI&#8217;s <a href="http://developer.amd.com/samples/FixedFuncShader/Pages/default.aspx">FixedFuncShader sample</a>. It&#8217;s an <strong>ubershader approach</strong>; one large (230 instructions or so) shader with static VS2.0 branching. It had some obvious places to optimize, I could get it down to 190 or so instructions, kill some <a href="http://msdn.microsoft.com/en-us/library/bb147316(VS.85).aspx">rcp</a>&#8216;s and reduce the amount of constant storage by 2x.</p>
<p>Still, it did not handle some things in the D3D T&#038;L or had some issues:</p>
<ul>
<li>It assumes one input UV, one output UV and no texture matrices. This place in T&#038;L gets quite convoluted &#8211; any input UVs or a texgen mode can be transformed by matrices of various sizes, and routed into any output UVs.</li>
<li>It was not using full T&#038;L lighting model. No biggie here.</li>
<li>I haven&#8217;t checked with NVShaderPerf or AMD ShaderAnalyzer yet, but last time I checked the static branch instruction was taking two clocks on some NV architecture. So ubershader approach does not come for free.</li>
</ul>
<p>Another thing I&#8217;m considering, is to combine final shader(s) from <strong>assembly fragments</strong>, with some simple register allocation.</p>
<p>In T&#038;L shader code, there&#8217;s only limited set of could-be-redundant computations, mostly computing world space position, camera space normal, view vector and so on (those could be used lighting, texgen or fog). Those computations can be explicitly put into separate fragments, and later fragments could just use their result.</p>
<p>What is left then is some register allocation. A shader assembly fragment could want some temporary registers for internal use (this is simple, just give it a bunch of unused registers), also want some registers as input (from previous fragments), and save some output in registers.</p>
<p>Again, I haven&#8217;t checked with shader performance tools, but I <em>think, guess and hope</em> that the drivers do additional register allocation, liveness analysis etc. when converting D3D shader bytecode into hardware format. This would mean that <em>I</em> can be quite sloppy with it, i.e. don&#8217;t have to implement some super smart allocation scheme.</p>
<p>I wrote some experimental code for the shader assembly combiner and so far it looks like a reasonable approach (and not too hard either).</p>
<p>Does that make sense? Or did everyone solve those problems eons ago already?</p>
<p><strong>Edit</strong>: half a year later, I wrote a technical report on how I implemented all this: <a href="http://aras-p.info/texts/VertexShaderTnL.html">http://aras-p.info/texts/VertexShaderTnL.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/01/22/fixed-function-lighting-in-vertex-shader-how/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Achievement of the week: MakeVistaDWMHappyDance</title>
		<link>http://aras-p.info/blog/2008/12/11/achievement-of-the-week-makevistadwmhappydance/</link>
		<comments>http://aras-p.info/blog/2008/12/11/achievement-of-the-week-makevistadwmhappydance/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 16:16:05 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[random]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=247</guid>
		<description><![CDATA[This was the function that I added: void GUIView::MakeVistaDWMHappyDance() { // Looks like Vista has some bug in DWM. Whenever we maximize or dock // a view, we must do something magic, otherwise // white stuff appears in place of the view. // See http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=4208117&#038;SiteID=1 bool earlierThanVista = systeminfo::GetOperatingSystemNumeric() &#60; 600; if( earlierThanVista ) return; [...]]]></description>
			<content:encoded><![CDATA[<p>This was the function that I added:</p>
<blockquote><pre>void GUIView::<strong>MakeVistaDWMHappyDance</strong>()
{
    // Looks like Vista has some bug in DWM. Whenever we maximize or dock
    // a view, we must do something magic, otherwise
    // white stuff appears in place of the view.
    // See http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=4208117&#038;SiteID=1

    bool earlierThanVista = systeminfo::GetOperatingSystemNumeric() &lt; 600;
    if( earlierThanVista )
        return;

    // What seems to work is drawing one pixel via GDI.
    // We draw it at (1,1) with usual background color.
    int grayColor = 0.61f * 255.0f;
    PAINTSTRUCT ps;
    BeginPaint(m_View, &#038;ps);
    SetPixel(ps.hdc, 1, 1, RGB(grayColor,grayColor,grayColor));
    EndPaint(m_View, &#038;ps);
}</pre>
</blockquote>
<p>I know. Reading from screen when Aero is on is slow, bad and wrong. But then, what do you do? It&#8217;s better than users staring an all-white window just because Vista decided to draw it white, no matter what you think you&#8217;re drawing into it.</p>
<p>&#8230;still, <code>MakeVistaDWMHappyDance</code> is not nearly as cool as </p>
<blockquote><p>internal interface ICanHazCustomMenu { &#8230; }</p></blockquote>
<p> that Nicholas added a while ago.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/12/11/achievement-of-the-week-makevistadwmhappydance/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cool tech vs. boring details</title>
		<link>http://aras-p.info/blog/2008/11/22/cool-tech-vs-boring-details/</link>
		<comments>http://aras-p.info/blog/2008/11/22/cool-tech-vs-boring-details/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 19:24:37 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=243</guid>
		<description><![CDATA[Some of the stuff I&#8217;ve been working on last week: Fixed import progress bar for movies with no audio Fixed first context menu click not working on Windows Eye dropper backend on Windows Export Package actually works on Windows Compare Binary works on Windows Add checkbox to project wizard to always open it on startup [...]]]></description>
			<content:encoded><![CDATA[<p>Some of the stuff I&#8217;ve been working on last week:</p>
<ul>
<li>Fixed import progress bar for movies with no audio</li>
<li>Fixed first context menu click not working on Windows</li>
<li>Eye dropper backend on Windows</li>
<li>Export Package actually works on Windows</li>
<li>Compare Binary works on Windows</li>
<li>Add checkbox to project wizard to always open it on startup</li>
<li>F1 in bundled text editor goes to scripting docs for current word</li>
<li>Fixed q/w/e/r keys in password fields and text areas toggling active Tool on Windows</li>
<li>Fixed panes not repainting on Windows after some change is done via context menu on them</li>
<li>&#8230;and so on.</li>
</ul>
<p><em>Boring tiny little details.</em></p>
<p>This probably best summarizes where lion&#8217;s share of time goes when developing anything. I&#8217;m not working on some cool spherical harmonics lightmap compression. Or on cunning ways to encode shadow map information for better filtering. Or on using CUDA to compute something interesting.</p>
<p>In other words, I&#8217;m not working on cool technology. Instead I&#8217;m adding missing menu items. Fixing obscure corner cases. Fighting inconsistencies in operating system APIs. Spotting misplaced pixels. Adding missing keyboard shortcuts.</p>
<p><em>Nothing interesting to blog about!</em></p>
<p>But still, methinks the difference between software that is merely &#8220;good&#8221; and software that is &#8220;great&#8221; is in the details. And <em>only</em> in the details.</p>
<p>I&#8217;ll just take care of tons of more details. Maybe it will result in something good.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/11/22/cool-tech-vs-boring-details/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Crunchtime!</title>
		<link>http://aras-p.info/blog/2008/11/10/crunchtime/</link>
		<comments>http://aras-p.info/blog/2008/11/10/crunchtime/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 13:09:14 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=239</guid>
		<description><![CDATA[A few weeks ago it was all calm in the source control. Now it&#8217;s crunchtime! I&#8217;m the master of svn deception. I do tons of useless commits just so that the stats look good. Yeah! &#8230;ok, back to work.]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://aras-p.info/blog/2008/10/29/unite-2008/">few weeks ago</a> it was all calm in the source control. Now it&#8217;s crunchtime!</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2008/11/crunch.png"><img src="http://aras-p.info/blog/wp-content/uploads/2008/11/crunch.png" alt="" title="Crunchtime!" class="alignnone size-full wp-image-240" /></a></p>
<p>I&#8217;m the master of svn deception. I do tons of useless commits just so that the stats look good. Yeah!</p>
<p>&#8230;ok, back to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/11/10/crunchtime/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The awesome support we do</title>
		<link>http://aras-p.info/blog/2008/10/30/the-awesome-support-we-do/</link>
		<comments>http://aras-p.info/blog/2008/10/30/the-awesome-support-we-do/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 07:00:47 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[rant]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=235</guid>
		<description><![CDATA[Yesterday&#8217;s experience catching up with Unity forums, as I remember it: Take a quick look at zillions of new posts. Answer about five questions with &#8220;what&#8217;s the value of your camera&#8217;s near plane?&#8221;. There should be some way to automate all of this. For every 20th question, reply with &#8220;increase your near plane!&#8221;, or something.]]></description>
			<content:encoded><![CDATA[<p>Yesterday&#8217;s experience catching up with Unity forums, as I remember it:</p>
<p>Take a quick look at zillions of new posts.</p>
<p>Answer about five questions with &#8220;what&#8217;s the value of your camera&#8217;s near plane?&#8221;.</p>
<p>There should be some way to automate all of this. For every 20th question, reply with &#8220;increase your near plane!&#8221;, or something.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/10/30/the-awesome-support-we-do/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unite 2008</title>
		<link>http://aras-p.info/blog/2008/10/29/unite-2008/</link>
		<comments>http://aras-p.info/blog/2008/10/29/unite-2008/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 20:24:35 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=225</guid>
		<description><![CDATA[Spent last week at our conference, Unite 2008. Lots of people, lots of stuff and goodness, tired as hell, but almost recovered already. We showed a glimpse of Unity editor for Windows at the keynote, so it is public now &#8211; yes, we are working on Windows toolchain. About the time! This is the major [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://aras-p.info/blog/wp-content/uploads/2008/10/unitea.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2008/10/unitea-150x150.jpg" alt="" title="Unite logo" width="150" height="150" class="alignright size-thumbnail wp-image-226" /></a>Spent last week at our conference, <a href="http://unity3d.com/unite/">Unite 2008</a>. Lots of people, lots of stuff and goodness, tired as hell, but almost recovered already.</p>
<p>We showed a glimpse of Unity editor for Windows at the keynote, so it is public now &#8211; yes, we are working on Windows toolchain. About the time! This is the major area I&#8217;m spending time these days &#8211; Windows, Windows, Windows. Learning WinAPI as I cruise along :) Before Unity 2.1 I spent months fixing tons of small issues, now I&#8217;m spending months doing tons of small Windows related things. Someday I&#8217;ll get back to doing tons of small things on the rendering side.</p>
<p>Here&#8217;s a couple of random photos that I <del datetime="2008-10-29T17:09:08+00:00">stole</del><ins datetime="2008-10-29T17:09:08+00:00">borrowed</ins> from Mantas:</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2008/10/unitec.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2008/10/unitec-300x199.jpg" alt="" title="Keynote" width="300" height="199" class="alignnone size-medium wp-image-228" /></a><br />
Keynote in front of a Sentinel from The Matrix.</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2008/10/united.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2008/10/united-300x199.jpg" alt="" title="Talking" width="300" height="199" class="alignnone size-medium wp-image-229" /></a><br />
Presenters talking.</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2008/10/unitee.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2008/10/unitee-300x199.jpg" alt="" title="Listening" width="300" height="199" class="alignnone size-medium wp-image-230" /></a><br />
People listening!</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2008/10/uniteb.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2008/10/uniteb-300x199.jpg" alt="" title="I don&#039;t know this guy" width="300" height="199" class="alignnone size-medium wp-image-227" /></a><br />
I don&#8217;t know that guy in the center. Probably some stupid outsider. Really!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/10/29/unite-2008/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Implicit to-pointer operators must die!</title>
		<link>http://aras-p.info/blog/2008/10/09/implicit-to-pointer-operators-must-die/</link>
		<comments>http://aras-p.info/blog/2008/10/09/implicit-to-pointer-operators-must-die/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 13:15:26 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=223</guid>
		<description><![CDATA[For the sake of the nation, this operator must die! Seriously. Suppose there is some class, let&#8217;s say ColorRGBAf. That has four floats inside. Now, someone at some point decided to add this operator to it: operator float* () { /**/ } operator const float* () const { /**/ } Probably because it&#8217;s easier to [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>For the sake of the nation,<br />
this operator must die!</p></blockquote>
<p>Seriously. Suppose there is some class, let&#8217;s say <code>ColorRGBAf</code>. That has four floats inside. Now, someone at some point decided to add this operator to it:</p>
<blockquote><p>operator float* () { /**/ }<br />
operator const float* () const { /**/ }</p></blockquote>
<p>Probably because it&#8217;s easier to pass color to OpenGL this way, or something like that.</p>
<p>This is evil. Like, really <strong>evil</strong>. Especially if that class did not have comparison operators defined, and some totally unrelated code four years later does:</p>
<blockquote><p>if (color != oldColor) { /* &#8230; */ }</p></blockquote>
<p>Ouch! Sounds like someone will spend four hours debugging something that looks like an event routing issue that <em>only</em> happens on Windows and <em>only</em> with optimizations on <em>(yes, I just did that&#8230;)</em>.</p>
<p>What happens here? The compiler takes pointers to two colors and compares <em>the pointers</em>. If for some reason both colors are temporary objects, then it can even happen that <em>both</em> get folded into the same variable/register/whatnot. The pointers are the same. Ouch!</p>
<p>Implicit &#8220;nice&#8221; operators are just disguised evil. Remove that operator, add something like <code>GetPointer()</code> to class if someone really wants to use that, and better even make the comparison operators private and without implementations. Yes. Much better.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/10/09/implicit-to-pointer-operators-must-die/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How watchdog threads should NOT be done&#8230;</title>
		<link>http://aras-p.info/blog/2008/09/05/how-watchdog-threads-should-not-be-done/</link>
		<comments>http://aras-p.info/blog/2008/09/05/how-watchdog-threads-should-not-be-done/#comments</comments>
		<pubDate>Fri, 05 Sep 2008 09:48:22 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=207</guid>
		<description><![CDATA[Here, a thread function that checks whether some tool got stuck: static void WatchdogFunc() { while( true ) { time_t now = time(NULL); Mutex::AutoLock lock(g_WatchdogMutex); if( now - g_StartTime > kWatchdogTimeout ) ComplainLoudlyAndDoSomething(); Thread::Sleep( 0.1f ); } } Mutex is taken because g_StartTime can be occasionally updated by the same tool. Yes, possibly a mutex [...]]]></description>
			<content:encoded><![CDATA[<p>Here, a thread function that checks whether some tool got stuck:</p>
<blockquote><p><code>
<pre>static void WatchdogFunc()
{
    while( true )
    {
        time_t now = time(NULL);
        Mutex::AutoLock lock(g_WatchdogMutex);
        if( now - g_StartTime > kWatchdogTimeout )
            ComplainLoudlyAndDoSomething();
        Thread::Sleep( 0.1f );
    }
}</pre>
<p></code></p></blockquote>
<p>Mutex is taken because g_StartTime can be occasionally updated by the same tool. Yes, possibly a mutex is an overkill here, and aligned variable + some memory fences should be enough (or just nothing), but hey, this is some random offline tool code.</p>
<p>What is horribly wrong with it?</p>
<p>Mutex is held locked for the whole duration of Sleep! That is, almost all the time; and other thread(s) barely have a chance to ever update g_StartTime.</p>
<p>And this is the code I&#8217;ve written. Oh stupid me.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/09/05/how-watchdog-threads-should-not-be-done/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Depth bias and the power of deceiving yourself</title>
		<link>http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/</link>
		<comments>http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 06:52:19 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[d3d]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=176</guid>
		<description><![CDATA[In Unity we very often mix fixed function and programmable vertex pipelines. In our lighting model, some amount of brightest lights per object are drawn in pixel lit mode, and the rest are drawn using fixed function vertex lighting. Naturally the pixel lights most often use vertex shaders, as they want to calculate some texcoords [...]]]></description>
			<content:encoded><![CDATA[<p>In Unity we very often mix fixed function and programmable vertex pipelines. In our lighting model, some amount of brightest lights per object are drawn in pixel lit mode, and the rest are drawn using fixed function vertex lighting. Naturally the pixel lights most often use vertex shaders, as they want to calculate some texcoords for light cookies, or do something with tangent space, or calculate some texcoords for shadow mapping, and so on. The vertex lighting pass uses fixed function, because it&#8217;s the easiest way. It is possible to implement fixed function lighting equivalent in vertex shaders, but we haven&#8217;t done that yet because of complexities of Direct3D <em>and</em> OpenGL, the need to support shader model 1.1 and various other issues. Call me lazy.</p>
<p>And herein lies the problem: most often precision of vertex transformations is not the same in fixed function versus programmable vertex pipelines. If you&#8217;d just draw some objects in multiple passes, mixing fixed function and programmable paths, this is roughly what you will get (excuse my programmer&#8217;s art):<br />
<a href='http://aras-p.info/blog/wp-content/uploads/2008/06/scenenobias.png'><img src="http://aras-p.info/blog/wp-content/uploads/2008/06/scenenobias-300x225.png" alt="Mixing fixed function and vertex shaders" title="scenenobias" width="300" height="225" class="alignnone size-medium wp-image-177" /></a></p>
<p><em>Not pretty at all!</em> This should have looked like this:<br />
<a href='http://aras-p.info/blog/wp-content/uploads/2008/06/scenegoodbias.png'><img src="http://aras-p.info/blog/wp-content/uploads/2008/06/scenegoodbias-300x225.png" alt="All good here" title="scenegoodbias" width="300" height="225" class="alignnone size-medium wp-image-178" /></a></p>
<p>So what do we do to make it look like this? We &#8220;pull&#8221; (bias) some rendering passes slighly towards the camera, so there is no depth fighting.</p>
<p>Now, at the moment Unity editor runs only on the Macs, which use OpenGL. In there, most of hardware configurations do not need this depth bias at all &#8211; they are able to generate same results in fixed function and programmable pipelines. Only Intel cards do need the depth bias on Mac OS X (on Windows, AMD and Intel cards need depth bias). So people author their games using OpenGL, where it does not need depth bias in most cases.</p>
<p>How do you apply depth bias in OpenGL? Enable GL_POLYGON_OFFSET_FILL and set <a href="http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/polygonoffset.html">glPolygonOffset</a> to something like -1, -1. This works.</p>
<p>How do you apply depth bias in Direct3D 9? <em>Conceptually</em>, you do the same. There are <a href="http://msdn.microsoft.com/en-us/library/bb205599(VS.85).aspx">DEPTHBIAS and SLOPESCALEDEPTHBIAS</a> render states that do just that. And so we did use them.</p>
<p><a href="http://forum.unity3d.com/viewtopic.php?t=8443">And people complained</a> about funky results on Windows.</p>
<p>And I&#8217;d look at their projects, see that they are using something like 0.01 for camera&#8217;s near plane and 1000.0 for the far plane, and tell them something along the lines of <em>&#8220;increase your near plane, stupid!&#8221;</em> (well ok, without the &#8220;stupid&#8221; part). And I&#8217;d explain all the above about mixing fixed function and vertex shaders, and how we do depth bias in that case, and how on OpenGL it&#8217;s often not needed but on Direct3D it&#8217;s pretty much always needed. And yes, how sometimes that can produce &#8220;double lighting&#8221; artifacts on close or intersecting geometry, and how the only solution is to increase the near plane and/or avoid close or intersecting geometry.</p>
<p>Sometimes this helped! I was <em>so convinced</em> that their too-low-near-plane was always the culprit.</p>
<p>And then one day I decided to check. This is what I&#8217;ve got on Direct3D:<br />
<a href='http://aras-p.info/blog/wp-content/uploads/2008/06/scenebadbias.png'><img src="http://aras-p.info/blog/wp-content/uploads/2008/06/scenebadbias-300x225.png" alt="Depth bias artefacts" title="scenebadbias" width="300" height="225" class="alignnone size-medium wp-image-179" /></a></p>
<p>Ok, this scene is intentionally using a low near plane, but let me stress this again. This is what I&#8217;ve got:<br />
<a href='http://aras-p.info/blog/wp-content/uploads/2008/06/scenebadbiasfail.png'><img src="http://aras-p.info/blog/wp-content/uploads/2008/06/scenebadbiasfail-300x225.png" alt="Epic fail!" title="scenebadbiasfail" width="300" height="225" class="alignnone size-medium wp-image-180" /></a></p>
<p><em>Not good at all.</em></p>
<p>What happened? It happened in roughly this way:</p>
<ol>
<li>First, depth bias <a href="http://msdn.microsoft.com/en-us/library/bb205599(VS.85).aspx">documentation</a> on Direct3D is wrong. Depth bias is <em>not</em> in 0..16 range, it is in 0..1 range which corresponds to entire range of depth buffer.</li>
<li>Back then, our code was always using 16 bit depth buffers, so the equivalent of -1,-1 depth bias in OpenGL was multiplied with something like 1.0/65535.0, and that was fed into Direct3D. <em>Hey, it seemed to work!</em></li>
<li>Later on, the device setup code was modified to do proper format selection, so most often it ended up using 24 bit depth buffer. <em>Of course</em> <del datetime="2008-06-12T06:33:50+00:00">no one</del><ins datetime="2008-06-12T06:50:43+00:00"> I</ins> never modified the depth bias code to account for this change&#8230;</li>
<li>And it stayed there. And I kept deceiving myself that the content of the users is to blame, and not some stupid code of mine.</li>
</ol>
<p><strong>It&#8217;s good to check your assumptions once in a while.</strong></p>
<p>So yeah, the proper multiplier for depth bias on Direct3D with 24 bit depth buffer should be not 1.0/65535.0, but something like 1.0/(2^24-1). Except that this value is <em>really small</em>, so something like 4.8e-7 should be used instead (see <a href="http://terathon.com/gdc07_lengyel.ppt">Lengyel&#8217;s GDC2007 talk</a>). Oh, but for some reason it&#8217;s not really enough in practice, so something like 2.0*4.8e-7 should be used instead (tested so far on GeForce 8600, Radeon HD 3850, Radeon 9600, Intel 945, reference rasterizer). Oh, and the same value should be used even when a 16 bit depth buffer is used; using 1.0/65535.0 multiplier with 16 bit depth buffer produces way too large bias.</p>
<p>With proper bias values the image is good on Direct3D again. Yay for that (fix is coming in Unity 2.1 soon).</p>
<p><em>&#8230;and yes, I know that real men fudge projection matrix instead of using depth bias&#8230; someday maybe.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Argh MFC!</title>
		<link>http://aras-p.info/blog/2008/05/20/argh-mfc/</link>
		<comments>http://aras-p.info/blog/2008/05/20/argh-mfc/#comments</comments>
		<pubDate>Tue, 20 May 2008 07:02:32 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=172</guid>
		<description><![CDATA[When introductory documentation for something has this, you know it won&#8217;t be pretty: CAsyncMonikerFile is derived from CMonikerFile, which in turn is derived from COleStreamFile. A COleStreamFile object represents a stream of data; a CMonikerFile object uses an IMoniker to obtain the data, and a CAsyncMonikerFile object does so asynchronously. So yeah, I am dealing [...]]]></description>
			<content:encoded><![CDATA[<p>When introductory documentation for something <a href="http://msdn.microsoft.com/en-us/library/35a0c067.aspx">has this</a>, you know it won&#8217;t be pretty:</p>
<blockquote><p>CAsyncMonikerFile is derived from CMonikerFile, which in turn is derived from COleStreamFile. A COleStreamFile object represents a stream of data; a CMonikerFile object uses an IMoniker to obtain the data, and a CAsyncMonikerFile object does so asynchronously.</p></blockquote>
<p>So yeah, I am dealing with downloading something from the internet inside an ActiveX control that is written in MFC. A seemingly simple task &#8211; I give you an URL, you give me back the bytes. But no! That would not be a proper architecture, so instead it has asynchronous monikers which are based on monikers which are based on stream files which use some interfaces and whatnot. And for ActiveX controls the docs suggest using CDataPathProperty or CCachedDataPathProperty, which are abstractions build on top of the above crap. And I don&#8217;t even know <em>what</em> &#8220;a moniker&#8221; is!</p>
<p>Of course all this complexity fails spectacularly in some quite common situations. For example, try downloading something when the web server serves gzip compressed html output. Good luck trying to figure out why everything seemingly works, you are notified of downloading progress, but never get the actual downloaded bytes.</p>
<p>Turns out the solution is to change downloading behaviour of the above pile of abstractions to <a href="http://groups.google.be/group/microsoft.public.inetsdk.programming.urlmonikers/browse_thread/thread/45315a0d0860d61a/cfa2bbabad8ff438?hl=en">use &#8220;pull data&#8221; model</a>, instead of default &#8220;push data&#8221; model. The default behaviour just seems to be broken (though it is not broken in that pile of abstractions, instead it is broken somewhere deeper in Windows code). Is this mentioned <em>anywhere</em> in the docs? Of course not!</p>
<p>This is pretty much how a code comment looks like for this:</p>
<blockquote><p>We don&#8217;t use CCachedDataPathProperty because it&#8217;s awfully slow, doing data reallocations for each 1KB received. For 8MB file it&#8217;s 8000 reallocations and 32 GB (!) of data copied for no good reason!</p>
<p>While we&#8217;re at it, we don&#8217;t use CDataPathProperty either, because it&#8217;s a useless wrapper over CAsyncMonikerFile.</p>
<p>Oh, and we don&#8217;t use CAsyncMonikerFile either, because it has bugs in VS2003&#8242; MFC where it never notifies the container that it is done with download, making IE still display &#8220;X items remaining&#8221; indefinitely. Some smart coder was converting information message and returning &#8220;out of memory&#8221; error if result was NULL, even if input message was NULL (which it often was). So we use our own &#8220;fixed&#8221; version of CAsyncMonikerFile instead.
</p></blockquote>
<p>Oh MFC, how we love thee.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/05/20/argh-mfc/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Lolshadows strike again</title>
		<link>http://aras-p.info/blog/2008/05/09/lolshadows-strike-again/</link>
		<comments>http://aras-p.info/blog/2008/05/09/lolshadows-strike-again/#comments</comments>
		<pubDate>Fri, 09 May 2008 12:59:44 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=170</guid>
		<description><![CDATA[Continuing the old theme&#8230; CAN I HAS MOIRE SHADOWS?]]></description>
			<content:encoded><![CDATA[<p>Continuing the <a href="http://aras-p.info/blog/2007/08/28/lolshadows/">old theme</a>&#8230;</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2008/05/canhasmoireshadows.png'><img src="http://aras-p.info/blog/wp-content/uploads/2008/05/canhasmoireshadows.png" alt="CAN I HAS MOIRE SHADOWS" title="canhasmoireshadows" class="alignnone size-full wp-image-169" /></a></p>
<p>CAN I HAS MO<strong>I</strong>RE SHADOWS?</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/05/09/lolshadows-strike-again/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>On job titles and design patterns</title>
		<link>http://aras-p.info/blog/2008/05/09/on-job-titles-and-design-patterns/</link>
		<comments>http://aras-p.info/blog/2008/05/09/on-job-titles-and-design-patterns/#comments</comments>
		<pubDate>Fri, 09 May 2008 11:25:20 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=168</guid>
		<description><![CDATA[I just changed my job title to say &#8220;Code Chef&#8220;. I like it, and it represents my current understanding of programming pretty well. I cook code. That&#8217;s my job. Some N years ago I would have liked a title with &#8220;Architect&#8221; or &#8220;Analyst&#8221; or something like that. I would have called myself &#8220;developer&#8221; instead of [...]]]></description>
			<content:encoded><![CDATA[<p>I just changed my job title to say &#8220;<a href="http://www.linkedin.com/in/nearaz">Code Chef</a>&#8220;. I like it, and it represents my current understanding of programming pretty well. I cook code. That&#8217;s my job.</p>
<p>Some N years ago I would have liked a title with &#8220;Architect&#8221; or &#8220;Analyst&#8221; or something like that. I would have called myself &#8220;developer&#8221; instead of &#8220;programmer&#8221; because hey, a developer thinks up things, whereas a programmer is a mere &#8220;code monkey&#8221;. More on code monkeys below.</p>
<p>But wait! Back then I also believed that knowing and using <a href="http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29">Design Patterns</a> is essential for a programmer! In one place when I was interviewing new hires, design pattern knowledge was something I would look for&#8230; <em>how stupid!</em> Nowadays my view of patterns is more along the lines of &#8220;yeah, whatever&#8221;. I don&#8217;t exactly think of them as <a href="http://realtimecollisiondetection.net/blog?p=44">things from hell</a>, but they could have caused more harm than good already.</p>
<p>Back to job titles. Code monkey is actually the key employee. A software product is largely defined by the code, heck, it <em>is</em> code. Sure, it also has the user interface, the fancy icons, the documentation, the website, the support, the roadmap and whatnot, but the code <em>is</em> the product, whereas everything else is more or less addons (possibly excluding UI&#8230; UI also defines the product).</p>
<p>Code design? Design patterns? Who cares about that.</p>
<p>It&#8217;s the final result that matters. <a href="http://meshula.net/wordpress?p=168">Futurist programming</a> for the win.</p>
<p><em>On the other hand, <a href="http://realtimecollisiondetection.net/blog/?p=44#comment-662">Memento Observer</a> is probably very cool.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/05/09/on-job-titles-and-design-patterns/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>One-liners: biawesome filtering</title>
		<link>http://aras-p.info/blog/2008/04/28/one-liners-biawesome-filtering/</link>
		<comments>http://aras-p.info/blog/2008/04/28/one-liners-biawesome-filtering/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 08:48:42 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=167</guid>
		<description><![CDATA[Said by Jonathan Czeck of Graveck: What kind of filtering does Resize() function use? Nearest-neighbor, bilinear, bicubic, biawesome? Since then &#8220;biawesome&#8221; became a local meme at work. Biawesome is awesome on steroids.]]></description>
			<content:encoded><![CDATA[<p>Said by Jonathan Czeck of <a href="http://graveck.com/">Graveck</a>:</p>
<blockquote><p>What kind of filtering does Resize() function use?  Nearest-neighbor, bilinear, bicubic, biawesome?</p></blockquote>
<p>Since then &#8220;biawesome&#8221; became a local meme at work. Biawesome is awesome on steroids.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/04/28/one-liners-biawesome-filtering/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tricky bugs: peculiarities of dynamic linking, and magic divisions</title>
		<link>http://aras-p.info/blog/2008/04/19/tricky-bugs/</link>
		<comments>http://aras-p.info/blog/2008/04/19/tricky-bugs/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 19:00:41 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=166</guid>
		<description><![CDATA[After wasting nearly two days on some really funky animation import crash, I checked in a code change with this log message: Fix FBX animation import crash once more. When exported symbols are not listed for a dylib, it seems to link back to calling executable (?!), making them share function impls with the same [...]]]></description>
			<content:encoded><![CDATA[<p>After wasting nearly two days on some really funky animation import crash, I checked in a code change with this log message:</p>
<blockquote><p>Fix FBX animation import crash once more. When exported symbols are not listed for a dylib, it seems to link <em>back</em> to calling executable (?!), making them share function impls with the same name. And because Keyframe is actually different in editor vs ImportFBX, this is wrong. Apparently this is OS X Leopard only, or something. Argh.</p></blockquote>
<p>The code change in question was just telling the compiler &#8220;here&#8217;s the list of the functions that are exported from this dynamic library&#8221;. The list was already there, just the compiler was never told about existence of it.</p>
<p>The bug manifested itself as a crash when importing animations. But it would not happen when importer was run from a small unit test application. There were no memory corruptions happening, it was not running out of memory, yet the code was crashing with access violation, usually because STL&#8217;s vector was returning it&#8217;s wrong size (but the actual data of the vector was correct; it was just returning bogus size). And it was doing that only on OS X Leopard, and not on OS X Tiger. <em>Huh?</em></p>
<p>Turns out what did happen &#8211; and I&#8217;m not sure if that&#8217;s a bug in OS X or a feature &#8211; is that the calling application did contain a class called Keyframe. And the shared library (where the crash was happening) also contained a class called Keyframe. But those classes were slightly different; first was 20 bytes in size, and second one was 16 bytes.</p>
<p>Now, <em>somehow</em> when the shared library was calling vector&lt;Keyframe&gt;::size(), the <em>function from the calling application</em> was used. I have no idea at all <em>how or why</em> this was happening, but it sure was! I could see from tracing the assembly code, that it was doing difference of two pointers, and then doing <em>something that for sure was not</em> division by 16.</p>
<p>What was the code doing? Turns out it was calculating division by 20 in a cunning way:</p>
<blockquote><pre>
mov  edx,esi   # edx = end()
sub  edx,eax   # edx -= begin()
mov  eax,edx   # eax = edx
sar  eax,0x2   # eax >>= 2
imul eax,eax,0xcccccccd # eax *= 0xcccccccd
</pre>
</blockquote>
<p>In other words, the compiler was replacing division by constant (as used in vector&#8217;s size()) by a shift and multiplication with a magic number. You can read more about the technique <a href="http://blogs.msdn.com/devdev/archive/2005/12/12/502980.aspx">here</a> or <a href="http://www.nynaeve.net/?p=115">here</a>.</p>
<p>But of course the code above <em>only works</em> if the number was actually divisible by 20; otherwise it returns <em>totally wrong</em> result. This is perfectly fine for computing the difference in two pointers to structures of known size&#8230; Except that inside the shared library the Keyframe structures are 16 bytes, and not 20!</p>
<p>So yeah. Watch out for peculiarities of dynamic linking on your platform.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/04/19/tricky-bugs/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Holy FPU precision, Batman!</title>
		<link>http://aras-p.info/blog/2008/01/22/holy-fpu-precision-batman/</link>
		<comments>http://aras-p.info/blog/2008/01/22/holy-fpu-precision-batman/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 09:46:38 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[d3d]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2008/01/22/holy-fpu-precision-batman/</guid>
		<description><![CDATA[(cross-posted from blogs.unity3d.com) One of our customers found an interesting bug the other day: embedding Unity Web Player into a web page makes some javascript animation libraries not work correctly. For example, script.aculo.us or Dojo Toolkit would stop doing some of their tasks. But only on Windows, and only on some browsers (Firefox and Safari). [...]]]></description>
			<content:encoded><![CDATA[<p><em>(cross-posted from <a href="http://blogs.unity3d.com/2008/01/22/holy-fpu-precision-batman/">blogs.unity3d.com</a>)</em></p>
<p>One of our customers found an interesting bug the other day: embedding Unity Web Player into a web page makes some javascript animation libraries not work correctly. For example, <a href="http://script.aculo.us/">script.aculo.us</a> or <a href="http://dojotoolkit.org/">Dojo Toolkit</a> would stop doing some of their tasks. But only on Windows, and only on some browsers (Firefox and Safari).</p>
<p>Wait a moment&#8230; Unity plugin makes nice wobbling web page elements not wobble anymore!? Sounds like an <em>interesting</em> issue&#8230;</p>
<p>So I prepared for a debug session and tried the usual &#8220;divide by two until you locate the problem&#8221; approach.</p>
<ul>
<li>Unity Web Player is composed of two parts: a small browser plugin, and the actual &#8220;engine&#8221; (let&#8217;s call it &#8220;runtime&#8221;). First I change the plugin so that it only loads the data, but never loads or starts the runtime. Everything works. So the problem is not in the plugin. <em>Good</em>.</li>
<li>Load the runtime and do basic initialization (create child window, load Mono, &#8230;), but never actually start playing the content &#8211; everything works.</li>
<li>Load the runtime and <em>fully</em> initialize everything, but never actually start playing the content &#8211; the bug appears! By now I know that the problem is <em>somewhere</em> in the initialization.</li>
</ul>
<p>Initialization reads some settings from the data file, creates some &#8220;manager objects&#8221; for the runtime,     initializes graphics device, loads first game &#8220;level&#8221; and then the game can play.</p>
<p>What of the above could cause <em>something</em> inside browser&#8217;s JavaScript engine stop working? And do that only on Windows, and only on some browsers? My first guess was the most platform-specific part: intialization of the graphics device, which on Windows usually happens to be Direct3D.</p>
<p>So I continued:</p>
<ul>
<li>Try using OpenGL instead of Direct3D &#8211; everything works. By now it&#8217;s confirmed that initializing Direct3D causes something else in the browser not work.</li>
<li>&#8220;A-ha!&#8221; moment: tell Direct3D to not change floating point precision (via a <a href="http://msdn2.microsoft.com/en-us/library/bb172527(VS.85).aspx">create flag</a>). Voilà, everything works!</li>
</ul>
<p>I don&#8217;t know how I <em>actually</em> came up with the idea of testing floating point precision flag. Maybe I remembered some related problems we had a while ago, where Direct3D would cause timing calculations be &#8220;off&#8221;, if the user&#8217;s machine was not rebooted for a couple of weeks or more. That time around we properly changed our timing code to use 64 bit integers, but left Direct3D precision setting intact.</p>
<blockquote><p>
Side note: Intel x86 floating point unit (FPU) can operate in various <a href="http://www.stereopsis.com/FPU.html">precision modes</a>, usually 32, 64 or 80 bit. By default Direct3D 9 sets FPU precision to 32 bit (i.e. single precision). Telling D3D to not change FPU settings <em>could</em> lower performance somewhat, but in my tests it did not have any noticeable impact.
</p></blockquote>
<p>So there it was. A debugging session, one line of change in the code, and fancy javascript webpage animations work on Windows in Firefox and Safari. This is coming out in Unity 2.0.2 update soon.</p>
<p>The moral? Something in one place can affect seemingly <em>completely</em> unrelated things in another place!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/01/22/holy-fpu-precision-batman/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>About two years ago&#8230;</title>
		<link>http://aras-p.info/blog/2008/01/15/about-two-years-ago/</link>
		<comments>http://aras-p.info/blog/2008/01/15/about-two-years-ago/#comments</comments>
		<pubDate>Tue, 15 Jan 2008 16:48:20 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2008/01/15/about-two-years-ago/</guid>
		<description><![CDATA[&#8230;I flew to Copenhagen and started working at Unity Technologies (OTEE back then). Here&#8217;s the famous last blog entry; and indeed with day work that is actually interesting there&#8217;s little time to spam the forums or the blogosphere. It&#8217;s been an amazing ride so far. I&#8217;m working with amazing people, we have (mostly :)) amazing [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;I flew to Copenhagen and started working at <a href="http://unity3d.com/company/">Unity Technologies</a> (OTEE back then). Here&#8217;s the famous <a href="http://aras-p.info/blog/2006/01/10/switched-jobs-almost-back-in-this-crazy-industry/">last blog entry</a>; and indeed with day work that is actually interesting there&#8217;s little time to spam the forums or the blogosphere.</p>
<p>It&#8217;s been an amazing ride so far. I&#8217;m working with amazing people, we have <em>(mostly :))</em> amazing customers, we&#8217;ve done three major releases and five minor ones, I&#8217;ve seen sales grow from ridiculously low amount to <em>feels good</em> levels, I&#8217;ve seen the team expansion, and I took svn revision number 10000 for myself (that happened half a year ago):</p>
<blockquote><p><em>&gt; Wohoo! Congratulations on the 10,000th commit Aras! You have won a warm cup of freshly brewed coffee when  you come to work! :)<br />
</em><br />
You don&#8217;t know the whole exciting story behind this&#8230; :)</p>
<p>I had two tiny &#8220;cleanups&#8221; to two files &#8211; removing unused variable from each. Now, I&#8217;d so something on my Mac, start compiling, and while it&#8217;s compiling I&#8217;d check svn log on the windows machine.</p>
<p>As soon as Valdemar checked in revision number 9998, I knew what I had to do. Two trivial svn commits!
</p></blockquote>
<p>Some serious work, as you can see. Oh, some of my work also ended up being actually released, I&#8217;m not just sitting there claiming svn revisions for myself. Honestly!</p>
<p>I&#8217;ve moving back to Lithuania now, continuing to work on Unity from home. Gonna miss some of the office fun, but oh well. Tradeoffs have to be made.</p>
<p>Let&#8217;s see what the coming years will bring. Rock on.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/01/15/about-two-years-ago/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>What if eyes were orthographic?</title>
		<link>http://aras-p.info/blog/2007/12/13/what-if-eyes-were-orthographic/</link>
		<comments>http://aras-p.info/blog/2007/12/13/what-if-eyes-were-orthographic/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 10:26:56 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/12/13/what-if-eyes-were-orthographic/</guid>
		<description><![CDATA[Yesterday at work we had some small discussion, involving something about projecting things behind the near plane onto the near plane (don&#8217;t remember what exactly). It went onto &#8220;now that you look at something, you see this, and this is because the eyes are perspective, not orthographic, and &#8230;&#8221;. And then it struck us: What [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday at work we had some small discussion, involving something about projecting things behind the near plane onto the near plane (don&#8217;t remember what exactly). It went onto &#8220;now that you look at something, you see this, and this is because the eyes are perspective, not orthographic, and &#8230;&#8221;. And then it struck us:</p>
<blockquote><p>What if the eyes were orthographic?</p></blockquote>
<p>Think about it&#8230;. that would be <em>totally weird</em>!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/12/13/what-if-eyes-were-orthographic/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Lolshadows!</title>
		<link>http://aras-p.info/blog/2007/08/28/lolshadows/</link>
		<comments>http://aras-p.info/blog/2007/08/28/lolshadows/#comments</comments>
		<pubDate>Tue, 28 Aug 2007 18:53:13 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/08/28/lolshadows/</guid>
		<description><![CDATA[In this age of the interwebs we have Lolcats, we even have LOLCODE&#8230; why can&#8217;t we have Lolshadows? This is actually me debugging point light shadows (that happen to use depth encoded into RGBA8 cubemaps). This is what happens when you use a too wide Poisson disc blurring in screen space and no prevention of [...]]]></description>
			<content:encoded><![CDATA[<p>In this age of the interwebs we have <a href="http://en.wikipedia.org/wiki/Lolcat">Lolcats</a>, we even have <a href="http://en.wikipedia.org/wiki/LOLCODE">LOLCODE</a>&#8230; why can&#8217;t we have Lolshadows?</p>
<p><img src="http://aras-p.info/img/unity/CanIHasShadows.jpg" alt="CAN I HAS SHADOWS? PLZ?" /></p>
<p>This is actually me debugging point light shadows (that happen to use depth encoded into RGBA8 cubemaps).</p>
<p><img src="http://aras-p.info/img/unity/PoissonedShadows.jpg" alt="OMG ITS POISSON!" /></p>
<p>This is what happens when you use a too wide Poisson disc blurring in screen space <em>and</em> no prevention of &#8220;shadow leakage&#8221; over different depths.</p>
<p>LOL! Internet!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/08/28/lolshadows/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Testing graphics code</title>
		<link>http://aras-p.info/blog/2007/07/31/testing-graphics-code/</link>
		<comments>http://aras-p.info/blog/2007/07/31/testing-graphics-code/#comments</comments>
		<pubDate>Tue, 31 Jul 2007 21:49:45 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/07/31/testing-graphics-code/</guid>
		<description><![CDATA[Everyone is saying &#8220;unit tests for the win!&#8221; all over the place. That&#8217;s good, but how would you actually test graphics related code? Especially considering all the different hardware and drivers out there, where the result might be different just because the hardware is different, or because the hardware/driver understands your code in a funky [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone is saying &#8220;unit tests for the win!&#8221; all over the place. That&#8217;s good, but how would you actually test graphics related code? Especially considering all the different hardware and drivers out there, where the result might be different just because the hardware is different, or because the hardware/driver understands your code in a <em>funky</em> way&#8230;</p>
<p>Here is how we do it at <a href="http://unity3d.com">work</a>. This took quite some time to set up, but I think it&#8217;s very worth it.</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/07/test-lab.jpg' title='Testing Lab in action'><img class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2007/07/test-lab.thumbnail.jpg' alt='Testing Lab in action' /></a>First you need <strong>hardware</strong> to test things on. For a start just a couple of graphics cards that you can swap in and out might do the trick. A larger problem is integrated graphics cards &#8211; it&#8217;s quite hard to swap them in and out, so we bit the bullet and bought a machine for each integrated card that we care about. The same machines are then used to test discrete cards (we have several shelves of those by now, going all the way back to&#8230; <em>does ATI Rage, Matrox G45 or S3 ProSavage say anything to you?</em>).</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/07/test-shots.png' title='It looks pretty random, huh?'><img  class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2007/07/test-shots.thumbnail.png' alt='It looks pretty random, huh?' /></a>Then you make the <strong>unit tests</strong> (or perhaps these should be called the functional tests). Build a small scene for every possible thing that you can imagine. Some examples:</p>
<ul>
<li>Do all blend modes work?</li>
<li>Do light cookies work?</li>
<li>Does automatic texture coordinate generation and texture transforms work?</li>
<li>Does rendering of particles work?</li>
<li>Does glow image postprocessing effect work?</li>
<li>Does mesh skinning work?</li>
<li>Do shadows from point lights work?</li>
</ul>
<p>This will result in a lot of tests, with each test hopefully testing a small, isolated feature. Make some setup that can load all defined tests in succession and take screenshots of the results. Make sure time always progresses at fixed rate (for the case where a test does not produce a constant image&#8230; like particle or animation tests), and take a screenshot of, for example, frame 5 for each test (so that some tests have some data to warm up&#8230; for example motion blur test).</p>
<p>By this time you have something that you can run and it spits out lots of screenshots. This is already <strong>very useful</strong>. Get a new graphics card, upgrade to new OS or install a new shiny driver? Run the tests, and obvious errors (if any) can be found just by quickly flipping through the shots. Same with the changes that are made in rendering related code &#8211; run the tests, see if anything became broken.</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/07/test-perl.png' title='My crappy Perl code…'><img class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2007/07/test-perl.thumbnail.png' alt='My crappy Perl code…' /></a>The testing process can be further <strong>automated</strong>. Here we have a small set of Perl scripts that can either produce a suite of test images for the current hardware, or run all the tests and compare the results with &#8220;known to be correct&#8221; suite of images. As graphics cards are different from each other, the &#8220;correct&#8221; results will be somewhat different (because of different capabilities, internal precision etc.). So we keep a set of test results for each graphics card.</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/07/test-drivers.png' title='That’s an awful lot of drivers!'><img class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2007/07/test-drivers.thumbnail.png' alt='That’s an awful lot of drivers!' /></a>Then these scripts can be run for <strong>various driver versions</strong> on every graphics card. They compare results for each test case, and for failed tests copy out the resulting screenshot, the correct screenshot, log the failures into a wiki-compatible format (to be posted on some internal wiki), etc.</p>
<p>I&#8217;ve heard that some folks even go a step further &#8211; fully automate the testing of all driver versions. Install one driver in silent mode, reboot the machine, after reboot runs another script that launches the tests and proceeds with the next driver version. I don&#8217;t know if that is only an urban legend or if someone actually does this<sup>*</sup>, but that would be an interesting thing to try. The testing per card then would be: 1) install a card, 2) run the test script, 3) coffee break, happiness and profit!</p>
<p><sup>* My impression is that at least with the big games it works the other way around &#8211; you don&#8217;t test with the hardware; instead the hardware guys test with your game. That&#8217;s how it looks for a clueless observer like me at least.</sup></p>
<p>So far this unit test suite was really helpful in a couple of ways: making of the <a href="http://unity3d.com/unity/whats-new/unity-2.0">just-announced</a> Direct3D renderer and discovering new &#038; exciting graphics card/driver workarounds that we have to do. Making of the suite did take a lot of time, but I&#8217;m happy with it!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/07/31/testing-graphics-code/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Can you set OpenGL states independently?</title>
		<link>http://aras-p.info/blog/2007/07/25/can-you-set-opengl-states-independently/</link>
		<comments>http://aras-p.info/blog/2007/07/25/can-you-set-opengl-states-independently/#comments</comments>
		<pubDate>Wed, 25 Jul 2007 20:50:11 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[opengl]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/07/25/can-you-set-opengl-states-independently/</guid>
		<description><![CDATA[Most of the time, yes, you can just set the needed states! You can set alpha blending on and turn light #0 off, and often nothing bad will happen. Blending will be on, and light #0 will be off. Fine. Until you hit a graphics card (quite new &#8211; from 2006, it can even do [...]]]></description>
			<content:encoded><![CDATA[<p>Most of the time, yes, you can just set the needed states! You can set alpha blending on and turn light #0 off, and often nothing bad will happen. Blending will be on, and light #0 will be off. Fine.</p>
<p>Until you hit a graphics card (quite new &#8211; from 2006, it can even do pixel shader 2.0) that completely hangs up the machine in one of your unit tests. In fact, in the first unit test, that does almost nothing. Debugging that thing is <em>total awesomeness</em> &#8211; try something out, and the machine either hangs up or it does not. Reboot, repeat.</p>
<p>After something like 30 hang-ups I found the cause: <em>you are damned</em> if you set GL_SEPARATE_SPECULAR_COLOR and GL_COLOR_SUM to different values (i.e. use separate specular but don&#8217;t turn on color sum). Because, you know, some code was there that did not see a point in changing light mode color control when no lighting was on. So yeah, always set those two in sync. Just to please this card&#8217;s drivers.</p>
<p>It&#8217;s hard for me to have any faith in driver developers. I know that their job is hard, walking the fine line between correctness and getting decent benchmark scores&#8230; But still &#8211; hanging up the machine when two OpenGL 1.2 states are set to different values? Would you trust those people to write <a href="http://www.opengl.org/documentation/glsl">full fledged compilers</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/07/25/can-you-set-opengl-states-independently/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging story: video memory leaks</title>
		<link>http://aras-p.info/blog/2007/07/14/debugging-story-video-memory-leaks/</link>
		<comments>http://aras-p.info/blog/2007/07/14/debugging-story-video-memory-leaks/#comments</comments>
		<pubDate>Sat, 14 Jul 2007 19:31:19 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/07/14/debugging-story-video-memory-leaks/</guid>
		<description><![CDATA[I ranted about OpenGL p-buffers a while ago. Time for the whole story! From time to time I hit some nasty debugging situation, and it always takes ages to figure out, and the path to the solution is always different. This is an example of such a debugging story. While developing shadow mapping I implemented [...]]]></description>
			<content:encoded><![CDATA[<p>I <a href="http://aras-p.info/blog/2007/06/04/opengl-pbuffers-suck">ranted</a> about OpenGL p-buffers a while ago. Time for the whole story!</p>
<p>From time to time I hit some nasty debugging situation, and it always takes <em>ages</em> to figure out, and the path to the solution is always different. This is an example of such a debugging story.</p>
<p>While developing shadow mapping I implemented a &#8220;screen space shadows&#8221; thing (where cascaded shadow maps are gathered into a screen-space texture and shadow receiver rendering later uses only that texture). Then while being in the editor and maximizing/restoring the window a few times, everything locks up for 3 or 5 seconds, then resumes normally.</p>
<p>So there&#8217;s a problem: a complete freeze after editor window is being resized after a couple of times (not immediately!), but otherwise everything just works. Where is the bug? What caused it?</p>
<p>Since shadows were working fine before, and I never noticed such lock-ups &#8211; it must be the screen-space shadow gathering thing that I just implemented, right? <em>(Fast-forward answer: no)</em> So I try to figure out <em>where</em> the lock-up is happening. Profiling does not give any insights &#8211; the lock-up is not even in my process, instead &#8220;somewhere&#8221;. Hm&#8230; I insert lots of manual timing code around various code blocks (that deal with shadows). They say the lock-up <em>most often</em> happens when activating a new render texture (an OpenGL p-buffer), specifically, calling a glFlush(). But not always, sometimes it&#8217;s still somewhere else.</p>
<p>After some head-scratching, a session with OpenGL Driver Profiler reveals what is actually happening &#8211; video memory is leaked! Apparently Mac OS X &#8220;virtualizes&#8221; VRAM, and when it runs out, the OS will still happily create p-buffers and so on, it will just start swapping VRAM contents to AGP/PCIe area. This swapping causes the lock-up. Ok, so now I know <em>what</em> is happening, I just need to find out <em>why</em>.</p>
<p>I look at all the code that deals with render textures &#8211; it looks ok. And it would be pretty strange if a VRAM leak would be unnoticed for two years since Unity is out in the wild&#8230; So that must be the depth render textures that are causing a leak (since they are a new type for the shadows), right? <em>(Answer: no)</em></p>
<p>I build a test case that allocates and deallocates a bunch of depth render textures each frame. No leaks&#8230; Huh.</p>
<p>I change my original code so that it gathers screen-space shadows onto the screen directly, instead of the screen-sized texture. No leaks&#8230; Hm&#8230; So it must be the depth render texture followed by screen-size render texture, that is causing the leaks, right? <em>(Answer: no)</em> Because when I have just the depth render texture, I have no leaks; and when I have no depth render texture, instead I gather shadows &#8220;from nothing&#8221; into a screen-size texture, I also have no leaks. So it must be the combination!</p>
<p>So far, the theory is that rendering into a depth texture followed by creation of screen-size texture will cause a video memory leak <em>(Answer: no)</em>. It looks like it leaks the amount that should be taken by depth texture (I say &#8220;it looks&#8221; because in OpenGL you never know&#8230; it&#8217;s all abstracted to make my life easier, hurray!). Looks like a fine bug report, time to build a small repro application that is completely separate from Unity.</p>
<p>So I grab some p-buffer sample code from Apple&#8217;s developer site, change it to also use depth textures and rectangle textures, remove all unused cruft, code the expected bug pattern (render into depth texture followed by rectangle p-buffer creation) and&#8230; it does not leak. D&#8217;oh.</p>
<p>Ok, another attempt: I take the p-buffer related code out of Unity, build a small application with just that code, code the expected bug pattern and&#8230; it does not leak! Huh?</p>
<p><em>Now what?</em></p>
<p>I compare the OpenGL call traces of Unity-in-test-case (leaks) and Unity-code-in-a-separate-app (does not leak). Of course, the Unity case does a lot more; setting up various state, shaders, textures, rendering actual objects with actual shaders, filtering out redundant state changes and whatnot. So I try to bring in bits of stuff that Unity does into my test application.</p>
<p>After a while I made my test app leak video memory (now that&#8217;s an achievement)! Turns out the leak happens when doing this:</p>
<ol>
<li>Create depth p-buffer</li>
<li>Draw to depth p-buffer</li>
<li>Copy it&#8217;s contents into a depth texture</li>
<li>Create a screen-sized p-buffer</li>
<li>Draw something into it <em>using</em> the depth texture</li>
<li>Release the depth texture and p-buffer</li>
<li>Release the screen-sized p-buffer</li>
</ol>
<p>My initial test app was not doing step 5&#8230; Now, <em>why</em> the leaks happens? Is it a bug or something I am doing wrong? And more importantly: how to get rid of it?</p>
<p>My suspicion was that OpenGL context sharing was somehow to blame here <em>(finally, a correct suspicion)</em>. We share OpenGL contexts, because, well, it&#8217;s the only sane thing to do &#8211; if you have a texture, mesh or shader somewhere, you really want to have it available both to the screen and when rendering into something else. The documentation on sharing of OpenGL contexts is extremely spartan, however. Like: &#8220;yeah, when they are shared, then the resources are shared&#8221; &#8211; great. Well, the actual text is like this (Apple&#8217;s <a href="http://developer.apple.com/qa/qa2001/qa1248.html">QA1248</a>):</p>
<blockquote><p>All sharing is peer to peer and developers can assume that shared resources are reference counted and thus will be<br />
maintained until explicitly released or when the last context sharing resources is itself released. It is helpful to think of this in the simplest terms possible and not to assume excess complication.</p></blockquote>
<p>Ok, <em>I am</em> thinking of this in the simplest terms possible&#8230; and it leaks video memory! The docs do not have a single word on <em>how</em> the resources are reference counted and what happens when a context is deleted.</p>
<p>Anyway, armed with my suspicion of context sharing being The Bad Guy here, I tried random things in my small test app. Turns out that unbinding any active textures from a context before switching to new one got rid of the leak. It looks like objects are refcounted by contexts, and they are not actually deleted while they are bound in some context (that is what I expect to happen). However, when a context itself is deleted, it seems as if it does not decrease refcounts of these objects (that is definitely what I don&#8217;t expect to happen). I am not sure if that&#8217;s a bug, or just undocumented &#8220;feature&#8221;&#8230;</p>
<p>All happy, I bring in my changes to the full codebase (&#8220;unbind any active textures before switching to a new context!&#8221;)&#8230; and the leak is still there. Huh?</p>
<p>After some head-scratching and randomly experimenting with <em>whatever</em>, turns out that you have to unbind any active &#8220;things&#8221; before switching to a new context. Even leaving a vertex buffer object bound can make a depth texture memory be leaked when another context is destroyed. Funky, eh?</p>
<p>So that was some 4 days wasted on chasing the bug that started out as &#8220;mysterious 5 second lock-ups&#8221;, went through &#8220;screen-space shadows leak video memory&#8221;, then through &#8220;depth textures followed by screen-size textures leak video memory&#8221; and through &#8220;unbind textures before switching contexts&#8221; to &#8220;unbind everything before switching contexts&#8221;. Would I have guessed it would end up like this? Not at all. I am still not sure if that&#8217;s the intended behavior or a bug; it looks more like a bug to me.</p>
<p>The take-away for OpenGL developers: <strong>when using shared contexts, unbind active textures, VBOs, shader programs etc. before switching OpenGL contexts</strong>. Otherwise at least on Mac OS X you will hit video memory leaks.</p>
<p>It&#8217;s somewhat sad that I find myself fighting issues like that most of my development time &#8211; not actually implementing some cool new stuff, but <em>making stuff actually work</em>. Oh well, I guess that is the difference between making (tech)demos and an actual software product.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/07/14/debugging-story-video-memory-leaks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
