<?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, 09 Sep 2011 17:03:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Testing Graphics Code, 4 years later</title>
		<link>http://aras-p.info/blog/2011/06/17/testing-graphics-code-4-years-later/</link>
		<comments>http://aras-p.info/blog/2011/06/17/testing-graphics-code-4-years-later/#comments</comments>
		<pubDate>Fri, 17 Jun 2011 04:44:46 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=762</guid>
		<description><![CDATA[Almost four years ago I wrote how we test rendering code at Unity. Did it stand the test of time and more importantly, growing the company from less than 10 people to more than 100 people? I&#8217;m happy to say it did! That&#8217;s it, move on to read the rest of the internets. The earlier [...]]]></description>
			<content:encoded><![CDATA[<p>Almost four years ago <a href="http://aras-p.info/blog/2007/07/31/testing-graphics-code/">I wrote how we test rendering code</a> at Unity. Did it stand the test of time and more importantly, growing the company from less than 10 people to more than 100 people?</p>
<p><em>I&#8217;m happy to say it did! That&#8217;s it, move on to read the rest of the internets.<br />
</em></p>
<p>The earlier post was more focused on hardware compatibility area (differences between platforms, GPUs, driver versions, driver bugs and their workarounds etc.). In addition to that, we do regression tests on a bunch of <a href="http://blogs.unity3d.com/2010/01/12/on-web-player-regression-testing/">actual Unity made games</a>. All that is good and works, let&#8217;s talk about what tests the rendering team at Unity is using in the daily lives instead.</p>
<p><strong>Graphics Feature &#038; Regression Testing</strong></p>
<p>In daily life of a graphics programmer, you care about two things related to testing:</p>
<p><span id="more-762"></span><strong>1.</strong> Whether a new feature you are adding, more or less, works.<br />
<strong>2.</strong> Whether something new you added or something you refactored broke or changed any existing features.</p>
<p>Now, &#8220;works&#8221; is a vague term. Definitions can range from equally vague</p>
<blockquote><p>Works For Me!</p></blockquote>
<p>to something like </p>
<blockquote><p>It has been battle tested on thousands of use cases, hundreds of shipped games, dozens of platforms, thousands of platform configurations and within each and every one of them there&#8217;s not a single wrong pixel, not a single wasted memory byte and not a single wasted nanosecond! <em>No kittehs were harmed either!</em></p></blockquote>
<p>In ideal world we&#8217;d only consider the latter as &#8220;works&#8221;, however that&#8217;s quite hard to achieve.</p>
<p>So instead we settle for small &#8220;functional tests&#8221;, where each feature has a small scene setup that exercises said feature (very much like talked about in <a href="http://aras-p.info/blog/2007/07/31/testing-graphics-code/">previous post</a>). It&#8217;s graphics programmer&#8217;s responsibility to add tests like that for his stuff.</p>
<p>For example, Fog handling might be tested by a couple scenes like this:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/092-FogModes.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/092-FogModes.png" alt="" title="Fog Modes" width="400" height="300" class="alignnone size-full wp-image-770" /></a><br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/017-Fog.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/017-Fog.png" alt="" title="Fog vs. different shaders; Forward rendering above, Deferred Lighting below" width="400" height="300" class="alignnone size-full wp-image-771" /></a></p>
<p>Another example, tests for various corner cases of Deferred Lighting:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/118-DeferredLMCases.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/118-DeferredLMCases.png" alt="" title="Lighmapped/NonLightmapped objects vs. Baked/NonBaked lights" width="400" height="300" class="alignnone size-full wp-image-774" /></a><br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/134-DefLightShapes.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/134-DefLightShapes.png" alt="" title="Light volumes crossing near/far planes" width="400" height="300" class="alignnone size-full wp-image-775" /></a><br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/143-DefLargeCoords.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/143-DefLargeCoords.png" alt="" title="Ability to handle small near plane &amp; large world coordinates" width="400" height="300" class="alignnone size-full wp-image-776" /></a></p>
<p>So that&#8217;s basic testing for &#8220;it works&#8221; that the graphics programmers themselves do. Beyond that, features are tested by QA and a large beta testing group, tried, profiled and optimized on real actual game projects and so on.</p>
<p>The good thing is, doing these basic tests also provides you with point 2 (did I break or change something?) automatically. If after your changes, all the graphics tests still pass, there&#8217;s a pretty good chance you did not break anything. Of course this testing is not exhaustive, but any time a regression is spotted by QA, beta testers or reported by users, you can add a new graphics test to check for that situation.</p>
<p><strong>How do we actually do it?</strong></p>
<p>We use <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> for the build/test farm. It has several build machines set up as graphics test agents (unlike most other build machines, they need an actual GPU, or a iOS device connected to them, or a console devkit etc.) that run graphics test configurations for all branches automatically. Each branch has it&#8217;s graphics tests run daily, and branches with &#8220;high graphics code activity&#8221; (i.e. branches that the rendering team is actually working on) have them run more often. You can always initiate the tests manually by clicking a button of course. What you want to see at any time is this:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/teamcity-gfx-tests.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/teamcity-gfx-tests.png" alt="" title="The graphics tests are passing one by one!" width="445" height="362" class="alignnone size-full wp-image-778" /></a></p>
<p>The basic approach is the same as <a href="http://aras-p.info/blog/2007/07/31/testing-graphics-code/">4 years ago</a>: a &#8220;game level&#8221; (&#8220;scene&#8221; in Unity speak) for each test, runs for defined number of frames, run everything at fixed timestep, take a screenshot at end of each frame. Compare each screenshot with &#8220;known good&#8221; image for that platform; any differences equals &#8220;FAIL&#8221;. On many platforms you have to allow a couple of wrong pixels because many consumer GPUs are not <i>fully</i> deterministic it seems.</p>
<p>So you have this bunch of &#8220;this is the golden truth&#8221; images for all the tests:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/some-gfx-tests.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/some-gfx-tests-500x247.png" alt="" title="Images for some of the graphics tests" width="500" height="247" class="alignnone size-medium wp-image-781" /></a></p>
<p>And each platform automatically tested on TeamCity has it&#8217;s own set:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/06/gfx-test-platforms.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/06/gfx-test-platforms.png" alt="" title="Platforms of graphics tests" width="187" height="181" class="alignnone size-full wp-image-782" /></a></p>
<p>Since the &#8220;test controller&#8221; can run on a different device than actual tests (the case for iOS, Xbox 360 etc.), the test executable opens a socket connection to transfer the screenshots. The test controller is a relatively simple C# application that listens on a socket, fetches the screenshots and compares them with the template ones. The result of it is output that TeamCity can understand; along with &#8220;build artifacts&#8221; that consist of failed tests (for each failed test: expected image, failed image, difference image with increased contrast).</p>
<p>That&#8217;s pretty much it! And of course, automated tests are nice and all, but that should not get too much into the way of actual <a href="http://programming-motherfucker.com/">programming manifesto</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2011/06/17/testing-graphics-code-4-years-later/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Mercurial/Kiln experience so far</title>
		<link>http://aras-p.info/blog/2011/04/18/mercurialkiln-experience-so-far/</link>
		<comments>http://aras-p.info/blog/2011/04/18/mercurialkiln-experience-so-far/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 07:14:33 +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/?p=668</guid>
		<description><![CDATA[At work we switched to Mercurial almost two months ago. Like Richard says, it was time to stop using Subversion. Here are my impressions so far. Preemptive warning: I&#8217;ve only ever used CVS, SourceSafe, Subversion, git and Mercurial as source contro systems (never used Perforce). I never really used a code review tool before Kiln. [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://unity3d.com/">work</a> we switched to <a href="http://mercurial.selenic.com/">Mercurial</a> almost two months ago. Like <a href="http://altdevblogaday.org/2011/03/09/its-time-to-stop-using-subversion/">Richard says</a>, it was time to stop using Subversion. Here are my impressions so far.</p>
<p><span id="more-668"></span><em>Preemptive warning: I&#8217;ve only ever used CVS, SourceSafe, Subversion, git and Mercurial as source contro systems (never used Perforce). I never really used a code review tool before Kiln. Everything below might be non-issues in other tools/systems, or not suitable for different setups/workflows!<br />
</em></p>
<p><strong>The Story</strong></p>
<p>At Unity we used <a href="http://subversion.apache.org/">Subversion</a> for source code versioning as long as I remember. svn revision 1 &#8212; an import from CVS &#8212; happened in 2005. We don&#8217;t talk about CVS. Nor about SourceSafe. Subversion was fine while the number of developers was small; we had a saying that CVS scales up to 5 people, and experimentally found out that svn scales up to about 50.</p>
<p>Since merging branches in subversion does not <em>really</em> work well, everyone was mostly working on one trunk, <em>carefully</em>. We would do an occasional branch for &#8220;this will surely break everything&#8221; features; and would branch off trunk sometime before each Unity release, but that&#8217;s about it. Having something like 50 people and 10 platforms on a single branch in version control does get a bit uneasy.</p>
<p>So we looked at various options, like <a href="http://git-scm.com/">git</a>, <a href="http://mercurial.selenic.com/">Mercurial</a>, <a href="http://www.perforce.com/">Perforce</a> and so on. I don&#8217;t know why exactly we ended up with Mercurial (someone made a decision I guess&#8230;). It <em>felt</em> like distributed versioning systems are <em>teh future</em> and unlike most game developers we don&#8217;t need to version hundreds of gigabytes of binary assets (hence no big need for Perforce).</p>
<p>So while some people were at GDC, we did a big switch to several things at once: 1) replace Subversion with Mercurial, 2) replace &#8220;everyone works on the same trunk&#8221; workflow with &#8220;teams work on their own topic branches&#8221;, 3) introduce a bit more formal code reviews via <a href="http://www.fogcreek.com/kiln/">Kiln</a>.</p>
<p>In hindsight, maybe switching three things at once wasn&#8217;t the brightest idea; there&#8217;s only so much change a person can absorb per unit of time. On the other hand, everyone experienced a large initial shock but now that the debris is setting down they just continue working with no big shocks predicted in the near future.</p>
<p><strong>Our Setup</strong></p>
<p>We use Fogcreek&#8217;s Kiln and host it on <a href="http://www.fogcreek.com/kiln/for-your-server.html">our own servers</a>. This is mostly for legal reasons I think (in our source code we have 3rd party bits which are under strict NDAs). Advantage of hosting ourselves is that we&#8217;re under complete control. Disadvantage is that we have to do some work; and we only get Kiln updates each couple of months (so for example everyone who lets Fogcreek host Kiln is on Kiln 2.4.x right now, while we&#8217;re still on 2.3.x).</p>
<p>Our source tree is about 12000 files amounting to about 600MB. Mercurial&#8217;s history (60000 revisions imported from svn) adds another 200MB. Additionally, we pull almost 1GB of binary files (see below for binary file versioning) into the source tree.</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2011/04/hg-branches.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/hg-branches-150x150.png" alt="" title="Team+feature branches in Mercurial" width="150" height="150" class="alignright size-thumbnail wp-image-685" /></a>Each &#8220;team&#8221; (core, editor, graphics, ios, android, &#8230;) has it&#8217;s own &#8220;branch&#8221; (actually, a separate repository clone) of the codebase, and merge back and forth between &#8220;trunk&#8221; repository. The trunk is supposed to be stable and shippable at almost any time (in theory&#8230; :)); unfinished, unreviewed code or code that has any failing tests can&#8217;t be pushed into trunk. Additionally, long-lasting features get their own &#8220;feature branches&#8221; (again, actually full clones of the repository). So right now we have more than 40 of those team+feature branches.</p>
<p>We have almost 50 developers committing to the source tree. Additionally, there is a build farm of 30 machines building most of those branches and running automated test suites. All this <em>does</em> put some pressure on the Kiln server ;) Everything below describes usage of Kiln 2.3.x with Mercurial 1.7.x; with more recent versions anything might have changed.</p>
<p><strong>Mercurial, or: I Have Two Heads!</strong></p>
<p>Probably the hardest thing to grok is the whole centralized-to-distributed versioning transition. Not everyone has github as their start page yet, and DVCS is actually more complex than a simple centralized model that Subversion has.</p>
<p>Things like this:</p>
<blockquote><p>OMG it says I have two heads now, what do I do?!</p></blockquote>
<p>just do not happen in centralized systems. <em>It&#8217;s not easy for a developer to accept he has two heads now, either. Or where this extra head came from&#8230;</em></p>
<p>And the benefits of distributed source control system are not immediately obvious to someone who&#8217;s never used one. The initial reaction is that suddenly everything got more complex for no good reason. Compare operations that you would use daily:</p>
<ul>
<li>Subversion: update, commit.
<ul>
<li>Since merges don&#8217;t really work: branch, switch &#038; merge are rarely used by mere mortals.</li>
</ul>
</li>
<li>Mercurial: pull, update or merge, commit, push.
<ul>
<li>And you might find you have two heads now!</li>
</ul>
<ul>
<li>You should also see their faces when you go &#8220;well, let me tell you about rebase&#8230;&#8221;. You might just as well explain everything with <a href="http://tartley.com/?p=1267">easy to understand spatial analogies</a> ;)</li>
</ul>
</li>
</ul>
<p>Thankfully, there&#8217;s this thing called the intertubes, which often has <a href="http://hginit.com/">helpful tutorials</a>.</p>
<p>Myself, I think <em>maybe</em> switching to git would have been a smaller overall shock. Mercurial is easier to get into, but it kind of pretends to work like ye olde versioning system, while underneath it is very different. Git, on the other hand, does not even try to look similar; it says &#8220;I&#8217;ll fuck with your brain&#8221; immediately after initial &#8220;hi how are you&#8221;. So it&#8217;s a larger initial shock, but maybe that <em>forces</em> people to get into this different mindset faster.</p>
<p><strong>Versioning large binary files</strong></p>
<p>Even if we <em>mostly</em> version only the code, there are occasional binaries. In our case it&#8217;s mostly 3rd party SDKs that are linked into Unity. For example, PhysX, Mono, FMOD, D3DX, Cg etc. We do have the source code for most of them, but we don&#8217;t need each developer to have 30000 files of Mono&#8217;s source code for example. So we build them separately, and version the prebuilt headers/libraries/DLLs in the regular source tree. Some of those prebuilt things can get quite large though (think couple hundred megabytes).</p>
<p>Most distributed version control systems (including git and mercurial) have trouble with this. <em>Every</em> version of <em>every</em> file is stored in your own local <del datetime="whoops, wrong terminology!">checkout</del>clone. Try having 50 versions of whole Mono build in there and you&#8217;ll wonder where the precious SSD space on your laptop did go!</p>
<p>Luckily, Kiln has a solution for this: <a href="http://kiln.stackexchange.com/questions/1873">kbfiles</a> extension. For each file marked as &#8220;large binary file&#8221;, only it&#8217;s &#8220;stand in&#8221; SHA1 hash is versioned, and the file itself is fetched from a central server into your local machine on demand. Think of it as a centralized versioning model for those special binary files. kbfiles itself is based on <a href="http://mercurial.selenic.com/wiki/BfilesExtension">bfiles extension</a>, with a tighter integration into Mercurial.</p>
<p>So the good news, with Kiln large binary files are handled easy and with no pain. You can globally set &#8220;large size&#8221; threshold, filename patterns etc. that are turned into &#8220;big files&#8221; automatically; or manually indicate &#8220;big file&#8221; when adding new files. And then continue using Mercurial as usual.</p>
<p>The bad news, however, is that kbfiles still has occasional bugs. Of course they will be fixed eventually, but for example right now <a href="http://blog.bitquabit.com/2008/11/25/rebasing-mercurial/">rebasing</a> with an incoming bigfiles commit will result in the wrong bigfile version in the end. Or, presence of kbfiles extension makes various Mercurial operations (like <tt>hg status</tt>) be <em>much</em> <a href="http://kiln.stackexchange.com/questions/3319">slower than usual</a>.</p>
<p><strong>Kiln as Web Interface</strong></p>
<p>Kiln itself is the server hosting Mercurial repositories, a web interface to view/admin them, and a code review tool. It&#8217;s fairly nice and does all the standard stuff, like show overview of all activity happening in a group of repositories:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-overview.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-overview-500x288.png" alt="" title="Overview of all activity in Kiln" width="500" height="288" class="alignnone size-medium wp-image-688" /></a></p>
<p>And shows the overview of any particular repository:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-repo.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-repo-500x279.png" alt="" title="One repository in Kiln" width="500" height="279" class="alignnone size-medium wp-image-689" /></a></p>
<p>And of course diff view of any particular commit:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-diff.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-diff-500x173.png" alt="" title="Diff view in Kiln" width="500" height="173" class="alignnone size-medium wp-image-686" /></a></p>
<p>My largest complaints about Kiln&#8217;s web interface are: 1) speed and 2) merge spiderwebs.</p>
<p><b><em>Speed</em></b>: like oh so many modern fancy-web systems, Kiln sometimes feels sluggish. Sometimes, in a time taken for Kiln to display a diff, Crysis 2 <em>would have rendered New York fifty times</em>. We did various things to boost up our server&#8217;s <em>oomph</em>, but it still does not feel fast enough. Maybe we don&#8217;t know how to setup our servers right; or maybe Kiln is actually quite slow; or maybe our repository size + branch count + number of people hitting it are exceeding whatever limits Kiln was designed for. That said, this is not unique of Kiln, <em>lots</em> of web systems are slow for sometimes no good reasons. If you are a web developer, however, keep this in mind: latency of any user operation is super important.</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-merge-spiderweb.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-merge-spiderweb-150x150.png" alt="" title="It&#039;s a merge forest!" width="150" height="150" class="alignright size-thumbnail wp-image-687" /></a><b><em>Merge spiderwebs</em></b>: distributed version control makes merges reliable and easy. However, merges happen all the time and can make it hard to see what was <em>actually</em> going on in the code. You can&#8217;t see the actual changes through the merge spiderwebs.</p>
<p>The change history is littered with &#8220;merge&#8221;, &#8220;merge remote repo&#8221;, &#8220;merge again&#8221; commits. The branch graph goes crazy and starts taking half of the page width. Not good! Now of course, this is where <a href="http://blog.bitquabit.com/2008/11/25/rebasing-mercurial/">rebasing</a> would help, however right now we&#8217;re not very keen on using it because of Kiln&#8217;s bigfiles bug mentioned above.</p>
<p><strong>Kiln as Code Review Tool</strong></p>
<p>Reviewing code is fairly easy: there&#8217;s a Review button that shows up when hovering over any commit. Each commit also shows how many reviews it has pending or accepted. So you just click on something, and voilà, you can request a code review:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-reviewrequest.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-reviewrequest-500x230.png" alt="" title="Requesting a review in Kiln" width="500" height="230" class="alignnone size-medium wp-image-691" /></a></p>
<p>Within each review you see the diffs, send comments back and forth between people, and highlight code snippets to be attached with each comment:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-review.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/04/kiln-review-500x332.png" alt="" title="Code review in Kiln" width="500" height="332" class="alignnone size-medium wp-image-690" /></a></p>
<p>In Kiln 2.3.x (which is what we use at the moment) the reviews still have a sort of &#8220;unfinished&#8221; feeling. For example, if you want multiple people to review a change, Kiln actually creates multiple reviews that are only very loosely coupled. The good news is that in Kiln 2.4 they have <a href="http://blog.fogcreek.com/rethinking-reviews/">improved this</a>, and I&#8217;m quite sure more improvements will come in the future.</p>
<p>Another option that I&#8217;m missing right now: in the repository views, filter out all approved commits. As an occasional &#8220;merge master&#8221;, I need to see if my big merge had any unreviewed or pending-review commits &#8212; something that&#8217;s quite hard to see with a merge-heavy history.</p>
<p><strong>Summary</strong></p>
<p>I&#8217;m quite happy with how switch to Mercurial + Kiln turned out to be so far. With each team working on their own repository, it does feel like we&#8217;re much less stepping on each other&#8217;s toes. That said, we haven&#8217;t shipped any Unity release from Mercurial yet; doing that will be a future exercise.</p>
<p><a href="http://www.fogcreek.com/kiln/">Kiln</a> is promising. It has some very good ideas (integrated code reviews &#038; versioning of big files in Mercurial), but it still has quite a lot of rough edges. I&#8217;m not totally happy with the web side performance of it either. That said, Fogcreek&#8217;s support for us has been fantastic; we got some bugfixes in the matter of days and they&#8217;ve been really helpful with setup/workflow/optimization issues. So it seems like it has a good future. Fogcreek guys, if you&#8217;re reading this: <a href="http://farm1.static.flickr.com/225/524768428_e20c722cc0.jpg">keep up wrk</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2011/04/18/mercurialkiln-experience-so-far/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Non-Uniform Work Distribution</title>
		<link>http://aras-p.info/blog/2011/02/16/a-non-uniform-work-distribution/</link>
		<comments>http://aras-p.info/blog/2011/02/16/a-non-uniform-work-distribution/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 15:47:57 +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=630</guid>
		<description><![CDATA[Warning: a post with stupid questions and no answers whatsoever! You need to do ten thousand things for the gold master / release / ShipIt(tm) moment. And you have 40 people who do the actual work&#8230; this means each of them only has to do 10000/40=250 things, which is not that bad. Right? Meanwhile in [...]]]></description>
			<content:encoded><![CDATA[<p><em>Warning: a post with stupid questions and no answers whatsoever!</em></p>
<p>You need to do ten thousand things for the gold master / release / ShipIt(tm) moment. And you have 40 people who do the actual work&#8230; this means each of them <em>only</em> has to do 10000/40=250 things, which is not that bad. Right?</p>
<p><span id="more-630"></span>Meanwhile in the real world&#8230; it does not actually work like that. And that&#8217;s something that has been on my mind for a long time. I don&#8217;t know how much of this is truth vs. perception, or what to do about it. But here&#8217;s my feeling, simplified:</p>
<p><strong>20 percent of the people are responsible for getting 80 percent of the work done</strong></p>
<p>I am somewhat exaggerating just to keep it consistent with the <a href="http://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>. But my feeling is that &#8220;work done&#8221; distribution is highly non uniform everywhere I worked where the team was more than a handful of people.</p>
<p>Here are some stupid statistics to illustrate my point (with graphs, and everyone loves graphs!):</p>
<p>Graph of bugs fixed per developer, over one week during the bug fixing phase. Red/yellow/green corresponds to priority 1,2,3 issues:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/02/graphbugs.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/02/graphbugs.png" alt="" title="Bugs fixed per developer" width="375" height="309" class="alignnone size-full wp-image-631" /></a></p>
<p>The distribution of bugs fixes is, shall we say, <em>somewhat</em> non uniform.</p>
<p>Is it a valid measure of &#8220;productivity&#8221;? Absolutely not. Some people probably haven&#8217;t been fixing bugs at all that week. Some bugs are <em>way</em> harder to fix than others. Some people could have made major part of the fix, but the finishing touches &#038; the act of actually resolving the bug was made by someone else. So yes, this statistics is absolutely flawed, but do we have anything else?</p>
<p>We could be checking version control commits.</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2011/02/svntimeline.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/02/svntimeline-500x243.png" alt="" title="Source code commits over time period" width="500" height="243" class="alignnone size-medium wp-image-637" /></a></p>
<p>Or putting the same into &#8220;commits by developer&#8221;:</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2011/02/svnauthor.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/02/svnauthor-500x269.png" alt="" title="Source code commits by author" width="500" height="269" class="alignnone size-medium wp-image-638" /></a></p>
<p>Of course this is even easier to game than resolving bugs. <em>&#8220;Moving buttons to the left&#8221;, &#8220;Whoops, that was wrong, moving them to the right again&#8221;</em> anyone? And people will be trolling statistics just because they can.<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2011/02/svntroll.png"><img src="http://aras-p.info/blog/wp-content/uploads/2011/02/svntroll.png" alt="" title="svn trolling!" width="330" height="108" class="alignnone size-full wp-image-633" /></a></p>
<p>However, there is still this highly subjective &#8220;feeling&#8221; that some folks are way, <em>way</em> faster than others. And not in just &#8220;can do some mess real fast&#8221; way, but in the &#8220;gets actual work done, and done well&#8221; way.</p>
<p>Or is it just my experience? How is it in your company? What can be done about it? Should something be done about it? I don&#8217;t know the answers&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2011/02/16/a-non-uniform-work-distribution/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<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>17</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>3</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>
	</channel>
</rss>

