<?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; unity</title>
	<atom:link href="http://aras-p.info/blog/tags/unity/feed/" rel="self" type="application/rss+xml" />
	<link>http://aras-p.info/blog</link>
	<description>Random thoughts of a triangle pusher</description>
	<lastBuildDate>Fri, 16 Jul 2010 07:04:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Surface Shaders, one year later</title>
		<link>http://aras-p.info/blog/2010/07/16/surface-shaders-one-year-later/</link>
		<comments>http://aras-p.info/blog/2010/07/16/surface-shaders-one-year-later/#comments</comments>
		<pubDate>Fri, 16 Jul 2010 06:38:43 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[gpu]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=530</guid>
		<description><![CDATA[Over a year ago I had a thought that &#8220;Shaders must die&#8221; (part 1, part 2, part 3). And what do you know &#8211; turns out we&#8217;re trying to pull this off in upcoming Unity 3. We call this Surface Shaders cause I&#8217;ve a suspicion &#8220;shaders must die&#8221; as a feature name wouldn&#8217;t have flied [...]]]></description>
			<content:encoded><![CDATA[<p>Over a year ago I had a thought that &#8220;Shaders must die&#8221; (<a href="http://aras-p.info/blog/2009/05/05/shaders-must-die/">part 1</a>, <a href="http://aras-p.info/blog/2009/05/07/shaders-must-die-part-2/">part 2</a>, <a href="http://aras-p.info/blog/2009/05/10/shaders-must-die-part-3/">part 3</a>).</p>
<p>And what do you know &#8211; turns out we&#8217;re trying to pull this off in upcoming <a href="http://unity3d.com/unity/coming-soon/unity-3">Unity 3</a>. We call this <strong>Surface Shaders</strong> cause I&#8217;ve a suspicion &#8220;shaders must die&#8221; as a feature name wouldn&#8217;t have flied very far.</p>
<p><span id="more-530"></span></p>
<p><strong>Idea</strong></p>
<p>The main idea is that 90% of the time I just want to declare surface properties. This is what I want to say:</p>
<blockquote><p>Hey, albedo comes from this texture mixed with this texture, and normal comes from this normal map. Use Blinn-Phong lighting model please, and don&#8217;t bother me again!</p></blockquote>
<p>With the above, I don&#8217;t have to care whether this will be used in a forward or deferred rendering, or how various light types will be handled, or how many lights per pass will be done in a forward renderer, or how some indirect illumination SH probes will come in, etc. I&#8217;m not interested in all that! These dirty bits are job of rendering programmers, <em>just make it work dammit</em>!</p>
<p>This is not a new idea. Most graphical shader editors <em>that make sense</em> do not have &#8220;pixel color&#8221; as the final output node; instead they have some node that basically describes surface parameters (diffuse, specularity, normal, &#8230;), and all the lighting code is usually not expressed in the shader graph itself. <a href="http://code.google.com/p/openshadinglanguage/">OpenShadingLanguage</a> is a similar idea as well (but because it&#8217;s targeted at offline rendering for movies, it&#8217;s much richer &#038; more complex).</p>
<p><strong>Example</strong></p>
<p>Here&#8217;s a simple &#8211; but full &#038; complete &#8211; Unity 3.0 shader that does diffuse lighting with a texture &#038; a normal map.<br />
<code>
<pre>
  <span style="color:gray">Shader "Example/Diffuse Bump" {
    Properties {
      _MainTex ("Texture", 2D) = "white" {}
      _BumpMap ("Bumpmap", 2D) = "bump" {}
    }
    SubShader {
      Tags { "RenderType" = "Opaque" }
      CGPROGRAM</span>
      #pragma surface surf Lambert
      struct Input {
        float2 uv_MainTex;
        float2 uv_BumpMap;
      };
      sampler2D _MainTex;
      sampler2D _BumpMap;
      void surf (Input IN, inout SurfaceOutput o) {
        o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
        o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
      }
      <span style="color:gray">ENDCG
    }
    Fallback "Diffuse"
  }</span></pre>
<p></code><br />
<a href="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfaceShaderDiffuseBump.png"><img src="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfaceShaderDiffuseBump-150x150.png" alt="" title="SurfaceShaderDiffuseBump" width="150" height="150" class="alignright size-thumbnail wp-image-543" /></a>Given pretty model &#038; textures, it can produce pretty pictures! How cool is that?</p>
<p>I grayed out bits that are not really interesting (declaration of serialized shader properties &#038; their UI names, shader fallback for older machines etc.). What&#8217;s left is Cg/HLSL code, which is then augmented by tons of auto-generated code that deals with lighting &#038; whatnot.</p>
<p>This surface shader dissected into pieces:</p>
<ul>
<li><code>#pragma surface surf Lambert</code>: this is a surface shader with main function &#8220;surf&#8221;, and a Lambert lighting model. Lambert is one of predefined lighting models, but you can write your own.</li>
<li><code>struct Input</code>: input data for the surface shader. This can have various predefined inputs that will be computed per-vertex &#038; passed into your surface function per-pixel. In this case, it&#8217;s two texture coordinates.</li>
<li><code>surf</code> function: actual surface shader code. It takes Input, and writes into <code>SurfaceOutput</code> (a predefined structure). It is possible to write into custom structures, provided you use lighting models that operate on those structures. The actual code just writes Albedo and Normal to the output.</li>
</ul>
<p><strong>What is generated</strong></p>
<p>Unity&#8217;s &#8220;surface shader code generator&#8221; would take this, generate <em>actual</em> vertex &#038; pixel shaders, and compile them to various target platforms. With default settings in Unity 3.0, it would make this shader support:</p>
<ul>
<li>Forward renderer and Deferred Lighting (Light Pre-Pass) renderer.</li>
<li>Objects with precomputed lightmaps and without.</li>
<li>Directional, Point and Spot lights; with projected light cookies or without; with shadowmaps or without. Well ok, this is only for forward renderer because in Light Pre-Pass lighting happens elsewhere.</li>
<li>For Forward renderer, it would compile in support for lights computed per-vertex and spherical harmonics lights computed per-object. It would also generate extra additive blended pass if needed for the case when additional per-pixel lights have to be rendered in separate passes.</li>
<li>For Light Pre-Pass renderer, it would generate base pass that outputs normals &#038; specular power; and a final pass that combines albedo with lighting, adds in any lightmaps or emissive lighting etc.</li>
<li>It can optionally generate a shadow caster rendering pass (needed if custom vertex position modifiers are used for vertex shader based animation; or some complex alpha-test effects are done).</li>
</ul>
<p>For example, here&#8217;s code that would be compiled for a forward-rendered base pass with one directional light, 4 per-vertex point lights, 3rd order SH lights; optional lightmaps <em>(I suggest just scrolling down)</em>: </p>
<pre style="font-size: 75%;">
#pragma vertex vert_surf
#pragma fragment frag_surf
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_fwdbase
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
struct Input {
	float2 uv_MainTex : TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _BumpMap;
void surf (Input IN, inout SurfaceOutput o)
{
	o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
	o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_MainTex));
}
struct v2f_surf {
  V2F_POS_FOG;
  float2 hip_pack0 : TEXCOORD0;
  #ifndef LIGHTMAP_OFF
  float2 hip_lmap : TEXCOORD1;
  #else
  float3 lightDir : TEXCOORD1;
  float3 vlight : TEXCOORD2;
  #endif
  LIGHTING_COORDS(3,4)
};
#ifndef LIGHTMAP_OFF
float4 unity_LightmapST;
#endif
float4 _MainTex_ST;
v2f_surf vert_surf (appdata_full v) {
  v2f_surf o;
  PositionFog( v.vertex, o.pos, o.fog );
  o.hip_pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
  #ifndef LIGHTMAP_OFF
  o.hip_lmap.xy = v.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  #endif
  float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
  TANGENT_SPACE_ROTATION;
  #ifdef LIGHTMAP_OFF
  o.lightDir = mul (rotation, ObjSpaceLightDir(v.vertex));
  #endif
  #ifdef LIGHTMAP_OFF
  float3 shlight = ShadeSH9 (float4(worldN,1.0));
  o.vlight = shlight;
  #ifdef VERTEXLIGHT_ON
  float3 worldPos = mul(_Object2World, v.vertex).xyz;
  o.vlight += Shade4PointLights (
    unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
    unity_LightColor0, unity_LightColor1, unity_LightColor2, unity_LightColor3,
    unity_4LightAtten0, worldPos, worldN );
  #endif // VERTEXLIGHT_ON
  #endif // LIGHTMAP_OFF
  TRANSFER_VERTEX_TO_FRAGMENT(o);
  return o;
}
#ifndef LIGHTMAP_OFF
sampler2D unity_Lightmap;
#endif
half4 frag_surf (v2f_surf IN) : COLOR {
  Input surfIN;
  surfIN.uv_MainTex = IN.hip_pack0.xy;
  SurfaceOutput o;
  o.Albedo = 0.0;
  o.Emission = 0.0;
  o.Specular = 0.0;
  o.Alpha = 0.0;
  o.Gloss = 0.0;
  surf (surfIN, o);
  half atten = LIGHT_ATTENUATION(IN);
  half4 c;
  #ifdef LIGHTMAP_OFF
  c = LightingLambert (o, IN.lightDir, atten);
  c.rgb += o.Albedo * IN.vlight;
  #else // LIGHTMAP_OFF
  half3 lmFull = DecodeLightmap (tex2D(unity_Lightmap, IN.hip_lmap.xy));
  #ifdef SHADOWS_SCREEN
  c.rgb = o.Albedo * min(lmFull, atten*2);
  #else
  c.rgb = o.Albedo * lmFull;
  #endif
  c.a = o.Alpha;
  #endif // LIGHTMAP_OFF
  return c;
}
</pre>
<p>Of those 90 lines of code, 10 are your original surface shader code; the remaining 80 would have to be pretty much written by hand in Unity 2.x days (well ok, less code would have to be written because 2.x had less rendering features). <em>But wait</em>, that was only base pass of the forward renderer! It also generates code for additive pass, for deferred base pass, deferred final pass, optionally for shadow caster pass and so on.</p>
<p>So this should be an easier to write lit shaders (it is for me at least). I hope this will also increase the number of Unity users who can write shaders at least 3 times <em>(i.e. to 30 up from 10!)</em>. It <em>should</em> be more future proof to accomodate changes to the lighting pipeline we&#8217;ll do in Unity next.</p>
<p><strong>Predefined Input values</strong></p>
<p>The Input structure can contain texture coordinates and some predefined values, for example view direction, world space position, world space reflection vector and so on. Code to compute them is only generated if they are <em>actually</em> used. For example, if you use world space reflection to do some cubemap reflections (as emissive term) in your surface shader, then in Light Pre-Pass base pass the reflection vector will <em>not be computed</em> (since it does not output emission, so by extension does not need reflection vector).</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfaceShaderRim.png"><img src="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfaceShaderRim-150x150.png" alt="" title="SurfaceShaderRim" width="150" height="150" class="alignright size-thumbnail wp-image-545" /></a>As a small example, the shader above extended to do simple rim lighting:<br />
<code>
<pre>
  <span style="color:gray">#pragma surface surf Lambert
  struct Input {
      float2 uv_MainTex;
      float2 uv_BumpMap;</span>
      float3 viewDir;
  <span style="color:gray">};
  sampler2D _MainTex;
  sampler2D _BumpMap;</span>
  float4 _RimColor;
  float _RimPower;
  <span style="color:gray">void surf (Input IN, inout SurfaceOutput o) {
      o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));</span>
      half rim =
          1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
      o.Emission = _RimColor.rgb * pow (rim, _RimPower);
  <span style="color:gray">}</span>
</pre>
<p></code></p>
<p><strong>Vertex shader modifiers</strong></p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfaceShaderNormalExtrusion.png"><img src="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfaceShaderNormalExtrusion-150x150.png" alt="" title="SurfaceShaderNormalExtrusion" width="150" height="150" class="alignright size-thumbnail wp-image-551" /></a>It is possible to specify custom &#8220;vertex modifier&#8221; function that will be called at start of the generated vertex shader, to modify (or generate) per-vertex data. You know, vertex shader based tree wind animation, grass billboard extrusion and so on. It can also fill in any non-predefined values in the Input structure.</p>
<p>My favorite vertex modifier? Moving vertices along their normals.</p>
<p><strong>Custom Lighting Models</strong></p>
<p>There are a couple simple lighting models built-in, but it&#8217;s possible to specify your own. A lighting model is nothing more than a function that will be called with the filled SurfaceOutput structure and per-light parameters (direction, attenuation and so on). Different functions would have to be called in forward &#038; light pre-pass rendering cases; and naturally the light pre-pass one has much less flexibility. So for any fancy effects, it is possible to say &#8220;do not compile this shader for light pre-pass&#8221;, in which case it will be rendered via forward rendering.</p>
<p><a href="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfWrapLambert.png"><img src="http://aras-p.info/blog/wp-content/uploads/2010/07/SurfWrapLambert-150x150.png" alt="" title="SurfWrapLambert" width="150" height="150" class="alignright size-thumbnail wp-image-549" /></a>Example of wrapped-Lambert lighting model:<br />
<code>
<pre>
  #pragma surface surf WrapLambert
  half4 LightingWrapLambert (SurfaceOutput s, half3 dir, half atten) {
      dir = normalize(dir);
      half NdotL = dot (s.Normal, dir);
      half diff = NdotL * 0.5 + 0.5;
      half4 c;
      c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
      c.a = s.Alpha;
      return c;
  }
  <span style="color:gray">struct Input {
      float2 uv_MainTex;
  };
  sampler2D _MainTex;
  void surf (Input IN, inout SurfaceOutput o) {
      o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
  }</span></pre>
<p></code></p>
<p><strong>Behind the scenes</strong></p>
<p>I&#8217;m using HLSL parser from Ryan Gordon&#8217;s <a href="http://hg.icculus.org/icculus/mojoshader/">mojoshader</a> to parse the original surface shader code and infer some things from the AST mojoshader produces. This way I can figure out what members are in what structures, go over function prototypes and so on. At this stage some error checking is done to tell the user his surface function is of wrong prototype, or his structures are missing required members &#8211; which is much better than failing with dozens of compile errors in the generated code later.</p>
<p>To figure out which surface shader inputs are <em>actually</em> used in the various lighting passes, I&#8217;m generating small dummy pixel shaders, compile them with Cg and use Cg&#8217;s API to query used inputs &#038; outputs. This way I can figure out, for example, that a normal map nor it&#8217;s texture coordinate is not actually used in Light Pre-Pass&#8217; final pass, and save some vertex shader instructions &#038; a texcoord interpolator.</p>
<p>The code that is ultimately generated is compiled with various shader compilers depending on the target platform (Cg for PC/Mac, XDK HLSL for Xbox 360, PS3 Cg for PS3, and my own <a href="http://code.google.com/p/hlsl2glslfork/">fork of HLSL2GLSL</a> for iPhone, Android and upcoming <a href="http://blogs.unity3d.com/2010/05/19/google-android-and-the-future-of-games-on-the-web/">NativeClient port of Unity</a>).</p>
<p>So yeah, that&#8217;s it. We&#8217;ll see where this goes next, or what happens when Unity 3 will be released.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2010/07/16/surface-shaders-one-year-later/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Compiling HLSL into GLSL in 2010</title>
		<link>http://aras-p.info/blog/2010/05/21/compiling-hlsl-into-glsl-in-2010/</link>
		<comments>http://aras-p.info/blog/2010/05/21/compiling-hlsl-into-glsl-in-2010/#comments</comments>
		<pubDate>Fri, 21 May 2010 19:59:38 +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>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=523</guid>
		<description><![CDATA[Realtime shader languages these days have settled down into two camps: HLSL (or Cg, which for all practical reasons is the same) and GLSL (or GLSL ES, which is sufficiently similar). HLSL/Cg is used by Direct3D and the big consoles (Xbox 360, PS3). GLSL/ES is used by OpenGL and pretty much all modern mobile platforms [...]]]></description>
			<content:encoded><![CDATA[<p>Realtime shader languages these days have settled down into two camps: HLSL (or Cg, which for all practical reasons is the same) and GLSL (or GLSL ES, which is sufficiently similar). HLSL/Cg is used by Direct3D and the big consoles (Xbox 360, PS3). GLSL/ES is used by OpenGL and pretty much all modern mobile platforms (iPhone, Android, &#8230;).</p>
<p>Since shaders are more or less &#8220;assets&#8221;, having two different languages to deal with is not very nice. What, I&#8217;m supposed to write my shader twice just to support both (for example) D3D and iPad? You would think in 2010, almost a decade since high level realtime shader languages have appeared, this problem would be solved&#8230; but it isn&#8217;t!</p>
<p><span id="more-523"></span>In <a href="http://unity3d.com/unity/coming-soon/unity-3">upcoming Unity 3.0</a>, we&#8217;re going to have OpenGL ES 2.0 for mobile platforms, where GLSL ES is the only option to write shaders in. However, almost all other platforms (Windows, 360, PS3) need HLSL/Cg.</p>
<p>I tried a bit making <a href="http://developer.nvidia.com/object/cg_toolkit.html">Cg</a> spit out GLSL code. In theory it can, and I read somewhere that <a href="http://en.wikipedia.org/wiki/Id_Software">id</a> uses it for OpenGL backend for <a href="http://en.wikipedia.org/wiki/Rage_(video_game)">Rage</a>&#8230; But I just couldn&#8217;t make it work. What&#8217;s possible for <a href="http://en.wikipedia.org/wiki/John_Carmack">John</a> apparently is not possible for mere mortals.</p>
<p>Then I looked at ATI&#8217;s <a href="http://sourceforge.net/projects/hlsl2glsl/">HLSL2GLSL</a>. That did produce GLSL shaders that were not absolutely horrible. So I started using it, and <em>(surprise!)</em> quickly ran into small issues here and there. Too bad development of the library stopped around 2006&#8230; on the plus side, it&#8217;s open source!</p>
<p>So I just forked it. Here it is: <a href="http://code.google.com/p/hlsl2glslfork/"><strong>http://code.google.com/p/hlsl2glslfork/</strong></a> (<a href="http://code.google.com/p/hlsl2glslfork/source/list">commit log here</a>). There are no prebuilt binaries or source drops right now, just a Mercurial repository. BSD license. Patches welcome.</p>
<p><em>Note on the codebase</em>: I don&#8217;t particularly like the codebase. It seems somewhat over-engineered code, that was probably taken from reference GLSL parser that 3DLabs once did, and adapted to parse HLSL and spit out GLSL. There are pieces of code that are unused, unfinished or duplicated. Judging from comments, some pieces of code have been in the hands of 3DLabs, ATI and NVIDIA (what good can come out of <em>that</em>?!). However, it <em>works</em>, and that&#8217;s the most important trait any code can have.</p>
<p><em>Note on the preprocessor</em>: I bumped into some preprocessor issues that couldn&#8217;t be easily fixed without first understanding someone else&#8217;s ancient code and then changing it significantly. Fortunately, Ryan Gordon&#8217;s project, <a href="http://icculus.org/mojoshader/">MojoShader</a>, happens to have preprocessor that very closely emulates HLSL&#8217;s one (including various quirks). So I&#8217;m using that to preprocess any source before passing it down to HLSL2GLSL. Kudos to Ryan!</p>
<p><em>Side note on MojoShader</em>: Ryan is also working on HLSL->GLSL cross compiler in MojoShader. I like that codebase much more; will certainly try it out once it&#8217;s somewhat ready.</p>
<p><em>You can never have enough notes</em>: Google&#8217;s <a href="http://code.google.com/p/angleproject/">ANGLE project</a> (running OpenGL ES 2.0 on top of Direct3D runtime+drivers) seems to be working on the opposite tool. For obvious reasons, they need to take GLSL ES shaders and produce D3D compatible shaders (HLSL or shader assembly/bytecode). The project seems to be moving fast; and if one day we&#8217;ll decide to default to GLSL as shader language in Unity, I&#8217;ll know where to look for a translator into HLSL :)</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2010/05/21/compiling-hlsl-into-glsl-in-2010/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>GDC 2010 report</title>
		<link>http://aras-p.info/blog/2010/03/17/gdc-2010-report/</link>
		<comments>http://aras-p.info/blog/2010/03/17/gdc-2010-report/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 12:30:26 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=507</guid>
		<description><![CDATA[Just returned from exciting (and exhausting) trip to Game Developers Conference 2010. Random notes: Unity It seems that everyone is talking about Unity this year. At GDC 2009 some people have heard about us, some others were &#8220;where the f*** this came from?!&#8221;, and some had no idea what Unity is. This year it&#8217;s hard [...]]]></description>
			<content:encoded><![CDATA[<p>Just returned from exciting (and exhausting) trip to <a href="http://www.gdconf.com/">Game Developers Conference 2010</a>. Random notes:</p>
<p><strong>Unity</strong></p>
<p>It seems that everyone is talking about Unity this year. At GDC 2009 some people have heard about us, some others were &#8220;where the f*** this came from?!&#8221;, and some had no idea what Unity is. This year it&#8217;s hard to find anyone who hasn&#8217;t heard about Unity. I was surprised by number of AAA developers who are playing around with Unity internally (for prototyping, mobile &#038; whatnot) and/or are big fans of Unity. <em>I like!</em></p>
<p>We had a cool booth that was very busy at all times. As a bonus, the Unity chairs could be used as weapons!<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2010/03/UnityBooth1.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2010/03/UnityBooth1-150x150.jpg" alt="" title="Unity Booth at GDC2010" width="150" height="150" class="alignnone size-thumbnail wp-image-508" /></a> <a href="http://aras-p.info/blog/wp-content/uploads/2010/03/UnityBooth2.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2010/03/UnityBooth2-150x150.jpg" alt="" title="Busy!" width="150" height="150" class="alignnone size-thumbnail wp-image-509" /></a> <a href="http://aras-p.info/blog/wp-content/uploads/2010/03/UnityBooth3.jpg"><img src="http://aras-p.info/blog/wp-content/uploads/2010/03/UnityBooth3-150x150.jpg" alt="" title="Unity Transformers! (Uniformers?)" width="150" height="150" class="alignnone size-thumbnail wp-image-510" /></a></p>
<p>Awesome quote: CEO of <del datetime="2010-03-17T11:16:46+00:00">censored</del> (competing middleware company) said: &#8220;yeah, Unity is going up, we are going down&#8221;. This is taken <em>completely</em> out of context of course.</p>
<p>We were busy demoing <a href="http://unity3d.com/unity/coming-soon/unity-3">upcoming Unity 3</a> which I think will be quite awesome. Three days before the conference were spent crunching on the demos for GDC :)</p>
<p><strong>Cool Stuff</strong></p>
<p><em>Only managed to go to two sessions :(</em></p>
<p><a href="http://twitter.com/self_shadow">Stephen Hill</a>&#8216;s &#8220;<a href="https://www.cmpevents.com/GD10/a.asp?option=C&#038;V=11&#038;SessID=10333">Rendering Tools and Techniques of Splinter Cell: Conviction</a>&#8221; had interesting bits &#038; pieces of stuff. Nice work on hierarchical Z occlusion and ambient occlusion fields! (probably first time I see AO fields used in actual game production)</p>
<p><a href="http://twitter.com/mike_acton">Mike Acton</a>&#8216;s &#8220;<a href="https://www.cmpevents.com/GD10/a.asp?option=C&#038;V=11&#038;SessID=10892">Three Big Lies: Typical Design Failures in Game Programming</a>&#8221; was entertaining. Content wise I pretty much knew what to expect. If you aren&#8217;t following Mike &#8211; <a href="http://www.youtube.com/watch#!v=u6ALySsPXt0">do it now</a>! Talk slides are <a href="http://www.insomniacgames.com/research_dev/articles/2010/1522262">at Insomniac&#8217;s site</a>.</p>
<p><a href="http://www.radgametools.com/">RAD</a>&#8216;s Telemetry profiler looks totally sweet. <em>I think</em> they acquired <a href="http://www.youtube.com/watch?v=oKRJNUvIJlg">this one</a> and improved it. Some <em>very</em> good UI ideas in there. On a related note, Scaleform&#8217;s new profiler looks&#8230; <em>kinda inspired</em> by Unity&#8217;s (<a href="http://aras-p.info/blog/wp-content/uploads/2010/03/ScaleformVsUnityProfiler.png">comparison: Scaleform on the left, Unity on the right</a>).</p>
<p><strong>Fun Stuff</strong></p>
<p><em>Managed to sneak in some fun (dare I say &#8220;social&#8221;?) stuff.</em></p>
<p><a href="http://twitter.com/repi/status/10461765908">Rendering folks dinner</a> <em>(thanks <a href="http://repi.se/">Johan</a>!)</em> was awesome, even if it made me feel kinda small &#038; stupid among those super smart guys &#038; gals. <a href="http://img709.yfrog.com/i/ozz.jpg/">Shadow algorithms</a> on receipts FTW! <a href="http://whatmakesyouthinkimnot.wordpress.com/2010/02/18/middleware-meetup/">Middleware Meetup</a> <em>(thanks <a href="http://whatmakesyouthinkimnot.wordpress.com/about/">Dan</a>!)</em> was full of friendly competitors :) <a href="http://macton.posterous.com/initial-details-for-our-gdc-tweetups-gdcdrink">#gdcdrink</a> tweetup <em>(thanks <a href="http://twitter.com/mike_acton">Mike</a>!)</em> had lots of war stories, PS3 talk and how to do fluid simulation on 360&#8242;s pixel shaders.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2010/03/17/gdc-2010-report/feed/</wfw:commentRss>
		<slash:comments>3</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>Improving C#/Mono for Games</title>
		<link>http://aras-p.info/blog/2009/11/14/improving-cmono-for-games/</link>
		<comments>http://aras-p.info/blog/2009/11/14/improving-cmono-for-games/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 19:07:24 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=442</guid>
		<description><![CDATA[A tweet by Michael Hutchinson on C#/Mono usage in games caused me to do a couple of short replies (one, two). But then I started thinking a bit more, and here&#8217;s a longer post on what is needed for C# (and more specifically Mono) to be used in games more. In Unity we use Mono [...]]]></description>
			<content:encoded><![CDATA[<p>A <a href="http://twitter.com/mjhutchinson/status/5643232459">tweet by Michael Hutchinson</a> on C#/Mono usage in games caused me to do a couple of short replies (<a href="http://twitter.com/aras_p/status/5643338294">one</a>, <a href="http://twitter.com/aras_p/status/5643361286">two</a>). But then I started thinking a bit more, and here&#8217;s a longer post on what is needed for C# (and more specifically Mono) to be used in games more.</p>
<p>In <a href="http://unity3d.com/">Unity</a> we use Mono to do game code (well, Unity users are doing that, not us). Overall it&#8217;s great; it has tons of advantages, loads of awesome and a flying ninja here and there. But no technology is perfect, right?</p>
<p><strong>Edit</strong>: Miguel rightly points out in the comments that Mono team is solving or has already solved some of these issues already. In some areas they are moving so fast that we at Unity can&#8217;t keep up!</p>
<p><span id="more-442"></span><br />
<strong>#1: Garbage Collector</strong></p>
<p>Most game developers do not like Garbage Collection (GC) very much. Typically, the more limited/hardcore their target platform is, the more they dislike GC. The reason? Most GC implementations cause rather unpredictable spikes.</p>
<p>Here&#8217;s a run of something recorded in the <em>(awesome)</em> Unity 2.6 profiler. Horizontal axis is time, vertical is CPU time spent in that frame:<br />
<a href="http://aras-p.info/blog/wp-content/uploads/2009/11/gcspikes.png"><img src="http://aras-p.info/blog/wp-content/uploads/2009/11/gcspikes.png" alt="Garbage collection spikes" title="Garbage collection spikes" width="563" height="187" class="alignnone size-full wp-image-441" /></a></p>
<p>At the bottom you see dark red thingies appearing once in a while. This is garbage collector kicking in, because some script code is allocating some memory at runtime.</p>
<p>Now of course, it <em>is possible</em> to write your script code so that it does no allocations (or almost no allocations). Preallocate your objects into pools, manually invoke GC when there&#8217;s a game situation when a small hickup won&#8217;t affect gameplay, etc. In fact, a lot of iPhone games made with Unity do that.</p>
<p>But that kind of side steps the whole advantage of &#8220;garbage collector almost frees you from doing memory management&#8221;. If you&#8217;re not allocating anything anyway, GC could just as well not be there!</p>
<p>A little side story. Me and Unity&#8217;s iPhone tech lead ReJ tried to explain what GC is to a non-programmer. Here&#8217;s what we came up with:</p>
<blockquote><p>
Garbage Collection is this cleaning service for lazy people. They can just leave any garbage on the floor in their house, and once in a while a garbage guy comes, collects all the garbage and takes it outside. Now, there are some intricacies in the service.</p>
<p>First, you never know when the garbage guy will come. You might be taking a shower, doing a meditation or having some &#8220;sexy time&#8221; &#8211; and it&#8217;s in the service agreement that when a garbage guy comes, you have to let him in to do his work.</p>
<p>Second thing is, the garbage guy is usually some homeless drunkard. He smells so bad that when he comes, you have to stop whatever you were doing, go outside and wait until he&#8217;s done with the garbage collection. Even your neighbors, who might be doing something entirely else in parallel, actually have to stop and idle while garbage is being collected in your house!</p>
<p>There are variations of this GC service. One variation is called &#8220;moving GC&#8221;, where the garbage guy also rearranges your furniture while collecting the garbage &#8211; he moves it all into one side of your house. This is so that you can buy a bigger piece of furniture, or throw a huge piece of garbage &#8211; and there will be enough unused space for you to do that! Of course this way GC process takes somewhat longer, but hey, you get all your stuff nicely packed into one corner.</p>
<p>Can&#8217;t you see that this service is the greatest idea of all time?
</p></blockquote>
<p>This is quite a harsh attitude towards GC, and of course it&#8217;s exaggerated. But there is some truth to it. So how could GC be fixed?</p>
<p><em>GC fix #1: more control</em></p>
<p>More explicit control on when &#038; how long GC runs. I want to say to the garbage guy, &#8220;come everyday at 4PM and do your work for 20 minutes&#8221;. In the game, I&#8217;d want to call GC with an upper time limit, say 1 millisecond for each call, and I would be calling that 30 times per second.</p>
<p><em>GC fix #2: sometimes I want to clean garbage myself</em></p>
<p>Inefficiencies and unpredictability of GC cause people to do even more work than a normal, oldskool memory allocation. Why not provide an option to deal with deallocations manually? I.e. a keyword <code>reallynew</code> could allocate an object that is not part of garbage collected world. It would function as a regular .NET object, just it would be user&#8217;s responsibility to <code>reallydelete</code> it.</p>
<p>Mono is already extending .NET (see <a href="http://tirania.org/blog/archive/2008/Nov-03.html">SIMD</a> and <a href="http://tirania.org/blog/archive/2009/Apr-09.html">continuations</a>). Maybe it makes sense to add some way to bypass garbage collector?</p>
<p><strong>#2: Distribution Size</strong></p>
<p>Using C#/.NET in a game requires having .NET runtime. None of the interesting platforms are guaranteed to have it, and even on Windows you can&#8217;t count on it being present. Mono is great here in a sense that it can be used on many more platforms than Microsoft&#8217;s own .NET. It&#8217;s also great on distribution size, but only if you compare it to Microsoft&#8217;s .NET.</p>
<p>In Unity Web Player, we package Mono DLL + mscorlib assembly into something like 1.5 megabytes (after LZMA compression). Which is great compared to 20+ megabytes of .NET runtime, but not that great it you compare it so, say, <a href="http://www.lua.org/">Lua</a> runtime (which is less than 100 kilobytes).</p>
<p>On some platforms (iPhone, Xbox 360, PS3, &#8230;) it&#8217;s not possible to generate code at runtime, so Mono&#8217;s JIT does not work. All code that&#8217;s written in C# has to be precompiled to machine code ahead of time (AOT compilation). This is not a problem per se, but because .NET framework was never designed with small size and few dependencies in mind, <em>doing anything</em> will ultimately pull in a lot of code.</p>
<p>We joke that doing anything in C# will result in an XML parser being included <em>somewhere</em>. This is not that far from the truth; e.g. calling <code>float.ToString()</code> will pull in whole internationalization system, which <em>probably</em> somewhere needs to read some global XML configuration file to figure out whether daylight savings time is active when Eastern European Brazilian Chinese calendar is used.</p>
<p><em>Size fix #1: custom core .NET libraries?</em></p>
<p>For game uses, most of &#8220;fat&#8221; stuff in .NET runtime is not really needed. <code>float.ToString()</code> could just always use period as a decimal separator. Core libraries could consist just of essential collections (list, array, hash table) and maybe a String class, with just essential methods. Maybe it&#8217;s worth sacrificing some of the generality of .NET if that could shave off a couple of megabytes from your iPhone game size?</p>
<p>Of course this is very much doable; &#8220;all that is needed&#8221; &#8482; is writing custom mscorlib+friends, and telling C# compiler to not ever reference <em>any</em> of the &#8220;real&#8221; libraries.</p>
<p><em>Size fix #2: make Mono runtime smaller</em></p>
<p>Uncompressed Mono DLL in our Windows build is 1.5 megabytes. We have turned off all the easy stuff (profiler, debugger, logging, COM, AOT etc.). But <em>probably</em> some more could be stripped away. Do our games really need multiple AppDomains? Some fancy marshalling? I don&#8217;t know, it just <em>feels</em> that 1.5MB is a lot.</p>
<p><strong>#3: Porting to New Platforms</strong></p>
<p>You know this classic: &#8220;There&#8217;s no portable code. There&#8217;s only code that&#8217;s been ported.&#8221;</p>
<p>Most existing gaming platforms are quite weird. Most upcoming smartphone platforms also are quite weird, each in their own interesting way. Porting a large project like Mono is not easy, especially since parts of it (JIT or AOT engine) highly depend on the platform.</p>
<p>For Unity iPhone, unexpected discovery that it&#8217;s not possible to JIT on iPhone made the initial release be delayed by something like 4 months. It did not help that in early iPhone SDK builds JIT was actually possible, and Apple decided to disable runtime generated code later. Making Mono actually work there required significant work both from Mono team and from Unity. We still have one guy working almost exclusively on Mono+iPhone issues!</p>
<p>Of course, <em>maybe</em> all the Mono iPhone work made porting to new platforms easier as a byproduct. But so far we don&#8217;t have Mono ported to any other platform, up to production quality. So judging from experience, we now always assume Mono port will be a pain, just because &#8220;some nasty surprises will come up&#8221; (and they always do).</p>
<p><strong>#4: Small Stuff</strong></p>
<p>There is a ton of small bits where extending .NET would benefit gaming scenarios. For example:</p>
<p>Suppose there is some array on the native engine side; for example vertex positions in a mesh (3xFloat for each vertex). Is it possible to make that piece of memory be represented as a native struct array for .NET side? So that it would not involve any extra memory copies, but N vertices somewhere in memory would look just like Vector3[N] for C#?</p>
<p>On a similar note, having &#8220;strided arrays&#8221; would be useful. For example, mesh data is often interleaved, so for each vertex there is a position, normal, UVs and so on. It would be cool if in C# position array would still look like Vector3[N], but internally the distance between each element would be larger than 12 bytes required for Vector3.</p>
<p><strong>Where do we go from here?</strong></p>
<p>The above are just random ideas, and I&#8217;m not complaining about Mono. It is great! It&#8217;s just not perfect. Mono being open source is a very good thing, which means pretty much any interested party can improve it as needed. So rock on.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/11/14/improving-cmono-for-games/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Deferred Cascaded Shadow Maps</title>
		<link>http://aras-p.info/blog/2009/11/04/deferred-cascaded-shadow-maps/</link>
		<comments>http://aras-p.info/blog/2009/11/04/deferred-cascaded-shadow-maps/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 14:42:08 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

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

		<guid isPermaLink="false">http://aras-p.info/blog/?p=350</guid>
		<description><![CDATA[Continuing the series (see Part 1, Part 2)&#8230; Got different lighting models (BRDFs) working. Without further ado, code snippets that produce real actual working shaders that work with lights &#038; shadows and whatnot: Simple Lambert (single color): Properties Color _Color EndProperties Surface o.Albedo = _Color; EndSurface Lighting Lambert Let&#8217;s add a texture: Properties 2D _MainTex [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing the series (see <a href="http://aras-p.info/blog/2009/05/05/shaders-must-die/">Part 1</a>, <a href="http://aras-p.info/blog/2009/05/07/shaders-must-die-part-2/">Part 2</a>)&#8230;</p>
<p>Got different lighting models (BRDFs) working. Without further ado, code snippets that produce real actual working shaders that work with lights &#038; shadows and whatnot:</p>
<p><span id="more-350"></span>Simple Lambert (single color):</p>
<blockquote><pre>Properties
    Color _Color
EndProperties
Surface
    o.Albedo = _Color;
EndSurface
Lighting Lambert
</pre>
</blockquote>
<p>Let&#8217;s add a texture:</p>
<blockquote><pre>Properties
    2D _MainTex
    Color _Color
EndProperties
Surface
    o.Albedo = SAMPLE(_MainTex) * _Color;
EndSurface
Lighting Lambert</pre>
</blockquote>
<p>Change light model to Half-Lambert (a.k.a. wrapped diffuse):</p>
<blockquote><pre>// ...everything the same
Lighting HalfLambert</pre>
</blockquote>
<p>Blinn-Phong, with constant exponent &#038; constant specular color, modulated by gloss map in main texture&#8217;s alpha:</p>
<blockquote><pre>Properties
    2D _MainTex
    Color _Color
    Color _SpecColor
    Float _Exponent
EndProperties
Surface
    half4 col = SAMPLE(_MainTex);
    o.Albedo = col * _Color;
    o.Specular = _SpecColor.rgb * col.a;
    o.Exponent = _Exponent;
EndSurface
Lighting BlinnPhong</pre>
</blockquote>
<p>The same Blinn-Phong, with added normal map:</p>
<blockquote><pre>Properties
    2D _MainTex
    2D _BumpMap
    Color _Color
    Color _SpecColor
    Float _Exponent
EndProperties
Surface
    half4 col = SAMPLE(_MainTex);
    o.Albedo = col * _Color;
    o.Specular = _SpecColor.rgb * col.a;
    o.Exponent = _Exponent;
    o.Normal = SAMPLE_NORMAL(_BumpMap);
EndSurface
Lighting BlinnPhong</pre>
</blockquote>
<p>I also made an illustrative-style BRDF (see <a href="http://www.valvesoftware.com/publications.html">Illustrative Rendering in Team Fortress 2</a>), but that only requires above sample to have &#8220;Lighting TF2&#8243; at the end.</p>
<p>Another thing I tried is surface that has Albedo dependent on a viewing angle, similar to <a href="http://developer.amd.com/media/gpu_assets/ShaderX2_LayeredCarPaintShader.pdf">Layered Car Paint Shader</a>. It works:</p>
<blockquote><pre>Properties
    2D _MainTex
    2D _BumpMap
    2D _SparkleTex
    Float _Sparkle
    Color _PrimaryColor
    Color _HighlightColor
EndProperties
Surface
    half4 main = SAMPLE(_MainTex);
    half3 normal  = SAMPLE_NORMAL(_BumpMap);
    half3 normalN = normalize(SAMPLE_NORMAL(_SparkleTex));
    half3 ns = normalize (normal + normalN * _Sparkle);
    half3 nss = normalize (normal + normalN);
    i.viewDir = normalize(i.viewDir);
    half nsv = max(0,dot(ns, i.viewDir));
    half3 c0 = _PrimaryColor.rgb;
    half3 c2 = _HighlightColor.rgb;
    half3 c1 = c2 * 0.5;
    half3 cs = c2 * 0.4;
    half3 tone =
        c0 * nsv +
        c1 * (nsv*nsv) +
        c2 * (nsv*nsv*nsv*nsv) +
        cs * pow(saturate(dot(nss,i.viewDir)), 32);
    main.rgb *= tone;
    o.Albedo = main;
    o.Normal = normal;
EndSurface
Lighting Lambert</pre>
</blockquote>
<p>Up next:</p>
<ul>
<li>How and where emissive terms should be placed. I cautiously omitted all emissive terms from the above examples (so my layered car shader is without reflections right now).</li>
<li>Where should things like rim lighting go? I&#8217;m not sure if it&#8217;s a surface property (increasing albedo/emission with angle) or a lighting property (a back light).</li>
</ul>
<p>My impressions so far:</p>
<ul>
<li>I like that I don&#8217;t have to write down vertex-to-fragment structures or the vertex shader. In most cases all the vertex shader does is transform stuff and pass it down to later stages, plus occasional computations that are linear over the triangle. No good reason to write it by hand.</li>
<li>I like that the above shaders do <i>not</i> deal with <i>how</i> the rendering is actually done. For Unity&#8217;s case, I&#8217;m compiling them into single pass per light forward renderer, but they <i>should</i> just work with multiple lights per pass, deferred etc. <em>Of course, that still has to be proven!</em></li>
</ul>
<p>So far so good.</p>
<p>Series index: Shaders must die, <a href="http://aras-p.info/blog/2009/05/05/shaders-must-die/">Part 1</a>, <a href="http://aras-p.info/blog/2009/05/07/shaders-must-die-part-2/">Part 2</a>, <a href="http://aras-p.info/blog/2009/05/10/shaders-must-die-part-3/"><strong>Part 3</strong></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/05/10/shaders-must-die-part-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Shaders must die, part 2</title>
		<link>http://aras-p.info/blog/2009/05/07/shaders-must-die-part-2/</link>
		<comments>http://aras-p.info/blog/2009/05/07/shaders-must-die-part-2/#comments</comments>
		<pubDate>Thu, 07 May 2009 21:35:28 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[gpu]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=339</guid>
		<description><![CDATA[I started playing around with the idea of &#8220;shaders must die&#8220;. I&#8217;m experimenting with extracting &#8220;surface shaders&#8221; for now. Right now my experimental pipeline is: Write a surface shader file Perl script transforms it into Unity 2.x shader file Which in turn is compiled by Unity into all lighting/shadows permutations, for D3D9 and OpenGL backends. [...]]]></description>
			<content:encoded><![CDATA[<p>I started playing around with the idea of &#8220;<a href="http://aras-p.info/blog/2009/05/05/shaders-must-die/">shaders must die</a>&#8220;. I&#8217;m experimenting with extracting &#8220;surface shaders&#8221; for now.</p>
<p>Right now my experimental pipeline is:</p>
<ol>
<li>Write a surface shader file</li>
<li>Perl script transforms it into Unity 2.x shader file</li>
<li>Which in turn is compiled by Unity into all lighting/shadows permutations, for D3D9 and OpenGL backends. Cg is used for actual shader compilation.</li>
</ol>
<p>I have <em>very</em> simple cases working. For example: <span id="more-339"></span></p>
<blockquote><pre>Properties
    2D _MainTex
EndProperties
Surface
    o.Albedo = SAMPLE(_MainTex);
EndSurface</pre>
</blockquote>
<p>This is a &#8220;no bullshit&#8221; source code for a simple Diffuse (Lambertian) shader, 87 bytes of text.</p>
<p>The Perl script produces a Unity 2.x shader. This will be long, but bear with me &#8211; I&#8217;m trying to show how much stuff has to be written right now, when we&#8217;re operating on vertex/pixel shader level. See <a href="http://unity3d.com/support/documentation/Components/SL-Attenuation.html">Attenuation and Shadows for Pixel Lights</a> in Unity docs for how this system works.</p>
<blockquote><pre>Shader "ShaderNinja/Diffuse" {
Properties {
  _MainTex ("_MainTex", 2D) = "" {}
}
SubShader {
  Tags { "RenderType"="Opaque" }
  LOD 200
  Blend AppSrcAdd AppDstAdd
  Fog { Color [_AddFog] }
  Pass {
    Tags { "LightMode"="PixelOrNone" }
CGPROGRAM
#pragma fragment frag
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
struct v2f {
    float2 uv_MainTex : TEXCOORD0;
};
struct f2l {
    half4 Albedo;
};
half4 frag (v2f i) : COLOR0 {
    f2l o;
    o.Albedo = tex2D(_MainTex,i.uv_MainTex);
    return o.Albedo * _PPLAmbient * 2.0;
}
ENDCG
  }
  Pass {
    Tags { "LightMode"="Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct v2f {
    V2F_POS_FOG;
    LIGHTING_COORDS
    float2 uv_MainTex;
    float3 normal;
    float3 lightDir;
};
uniform float4 _MainTex_ST;
v2f vert (appdata_tan v) {
    v2f o;
    PositionFog( v.vertex, o.pos, o.fog );
    o.uv_MainTex = TRANSFORM_TEX(v.texcoord, _MainTex);
    o.normal = v.normal;
    o.lightDir = ObjSpaceLightDir(v.vertex);
    TRANSFER_VERTEX_TO_FRAGMENT(o);
    return o;
}
uniform sampler2D _MainTex;
struct f2l {
    half4 Albedo;
    half3 Normal;
};
half4 frag (v2f i) : COLOR0 {
    f2l o;
    o.Normal = i.normal;
    o.Albedo = tex2D(_MainTex,i.uv_MainTex);
    return DiffuseLight (i.lightDir, o.Normal, o.Albedo, LIGHT_ATTENUATION(i));
}
ENDCG
  }
}
Fallback "VertexLit"
}</pre>
</blockquote>
<p>Phew, that is quite some typing to get simple diffuse shader (1607 bytes)! Well, at least all the lighting/shadow combinations are handled by Unity macros here. When Unity takes this shader and compiles into all permutations, it results in 58 kilobytes of shader assembly (D3D9 + OpenGL, 17 light/shadow combinations).</p>
<p>Let&#8217;s try something slightly different: bumpmapped, with a detail texture:</p>
<blockquote><pre>Properties
    2D _MainTex
    2D _Detail
    2D _BumpMap
EndProperties
Surface
    o.Albedo = SAMPLE(_MainTex) * SAMPLE(_Detail) * 2.0;
    o.Normal = SAMPLE_NORMAL(_BumpMap);
EndSurface
</pre>
</blockquote>
<p>This is 173 bytes of text. Generated Unity shader is 2098 bytes, which compiles into 74 kilobytes of shader assembly.</p>
<p>In this case, the processing script detects that surface shader modifies normal per pixel, and does the necessary tangent space light transformations. It all just works!</p>
<p>So this is where I am now. Next up: detect which lighting model to use based on surface parameters (right now it always uses Lambertian). Fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/05/07/shaders-must-die-part-2/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Google O3D &#8211; it&#8217;s going to be interesting</title>
		<link>http://aras-p.info/blog/2009/05/05/google-o3d-its-going-to-be-interesting/</link>
		<comments>http://aras-p.info/blog/2009/05/05/google-o3d-its-going-to-be-interesting/#comments</comments>
		<pubDate>Tue, 05 May 2009 12:01:24 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[rendering]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=317</guid>
		<description><![CDATA[A couple of weeks ago Google announced O3D: an open source web browser plugin for low level accelerated 3D graphics. The website for O3D project is here. Of course this created some buzz (hey, it&#8217;s Google after all). And it is in some way a competing technology with Unity. I think it&#8217;s going to be [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago Google <a href="http://google-code-updates.blogspot.com/2009/04/toward-open-web-standard-for-3d.html">announced O3D</a>: an open source web browser plugin for low level accelerated 3D graphics. The website for O3D project <a href="http://code.google.com/apis/o3d/">is here</a>.</p>
<p>Of course this created some buzz (hey, it&#8217;s Google after all). And it is in some way a competing technology with <a href="http://unity3d.com/">Unity</a>. I think it&#8217;s going to be interesting, so I say &#8220;welcome competition!&#8221;</p>
<p><em>Preemptive blah blah: this website is my personal opinion and does not represent the views of my employer, former employers or anyone else other than myself.</em></p>
<p>Unity is one of the players in &#8220;3D on the web&#8221; space. 3D graphics in the browser are in fact nothing new. <a href="http://unity3d.com/unity-web-player-2.x">Unity&#8217;s browser plugin</a> has existed since 2005 and is now in eight digits installations count. There is <a href="http://en.wikipedia.org/wiki/VRML">VRML</a>, <a href="http://en.wikipedia.org/wiki/X3D">X3D</a>, <a href="http://en.wikipedia.org/wiki/Adobe_Shockwave">Adobe Shockwave</a>, <a href="http://en.wikipedia.org/wiki/Virtools">3DVIA/Virtools</a>, software rendering approaches on top of <a href="http://en.wikipedia.org/wiki/3D_Flash">Flash</a> and so on.</p>
<p>In my view, major advantages that Unity has compared to O3D:</p>
<ul>
<li>It&#8217;s not only about the graphics. Unity has physics, audio, input, scripting, streaming, networking, asset pipeline and whatnot. O3D is only about the graphics, and at a lower level.</li>
<li>Unity runs on wider range of hardware. O3D requires Shader Mode 2.0 or later hardware, so about 30% of the &#8220;machines on the internet&#8221; can&#8217;t run O3D (based on our <a href="http://unity3d.com/webplayer/hwstats/pages/web-2009Q1-shadergen.html">2009Q1 data</a>). Couple that with lots of compatibility workarounds that we have and it&#8217;s probably safe to say that Unity is more <em>stable and mature</em> at this point.</li>
<li>Unity is not only about the web. There&#8217;s support for iPhone, Nintendo Wii, standalone games, and with time more console and mobile platforms will come.</li>
<li>Creating and improving Unity is our primary and only focus as a company. In Google&#8217;s case, O3D is just another technology in their vast portfolio.</li>
</ul>
<p><em>Of course</em>, O3D also has advantages:</p>
<ul>
<li>It&#8217;s done by Google! When Google does <del datetime="2009-04-24T12:06:53+00:00">something</del> anything, people notice immediately :)</li>
<li>O3D is free and open source. Hard to beat the free price, and open source does have it&#8217;s benefits. O3D is not a &#8220;standard&#8221; of any sort right now, but it looks like Google would want it to become one.</li>
<li>Only focusing on low level graphics has it&#8217;s benefits: it&#8217;s lightweight, it appeals to hackers and graphics programmers who want to be in control. Unity&#8217;s higher level is much easier and faster to use, but low level hacking can be fun.</li>
</ul>
<p>Of course there are tons of other differences (I might have missed something important as well).</p>
<p>For me as a rendering guy, it&#8217;s interesting to see O3D taking similar decisions here and there (e.g. they don&#8217;t use GLSL on OpenGL either because it does not really work in the real world).</p>
<p>So&#8230; we&#8217;ll see where things will go. It&#8217;s going to be interesting!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2009/05/05/google-o3d-its-going-to-be-interesting/feed/</wfw:commentRss>
		<slash:comments>5</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>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>How to announce anything</title>
		<link>http://aras-p.info/blog/2008/09/20/how-to-announce-anything/</link>
		<comments>http://aras-p.info/blog/2008/09/20/how-to-announce-anything/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 04:39:59 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=221</guid>
		<description><![CDATA[I&#8217;m quoting awesome post by Charles Hinshaw from Unity forums: I vote that we complain enough that they don&#8217;t share plans until everything is 200% done &#8211; I personally don&#8217;t want to know about a new version of Unity until after I have already shipped at least one game built with that version. Alternately, UT [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m quoting awesome post by Charles Hinshaw from Unity forums:</p>
<blockquote><p>I vote that we complain enough that they don&#8217;t share plans until everything is 200% done &#8211; I personally don&#8217;t want to know about a new version of Unity until after I have already shipped at least one game built with that version.</p>
<p>Alternately, UT could issue press releases that lack any information that might set expectations and/or require approval from third parties: </p>
<blockquote><p>Unity Technologies ApS, announced today that they may be releasing an update to their popular game development software at an undisclosed future time. </p>
<p>From their offices in Copenhagen, Unity Technologies CEO and co-founder, David Helgason, said &#8220;We&#8217;re pretty excited not to announce anything specific about this potential upcoming release as we think that many of our users may be pleased by the addition of some number of features that may not have been present in previous versions of the software.&#8221; </p>
<p>Tom Higgins, Product Evangelist, added &#8220;The features in this software are making it possible for a number of undisclosed companies to work on various projects that may be released in the future. I think all of our users might be inspired by the things that may currently be under development with this future version of Unity.&#8221;</p></blockquote>
<p><em>edit</em>: Uhm, based on the replies that follow, apparently it wasn&#8217;t obvious that I am not seriously requesting this.</p></blockquote>
<p>Way to go! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/09/20/how-to-announce-anything/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hardware of the casual gamer</title>
		<link>http://aras-p.info/blog/2008/08/28/hardware-of-the-casual-gamer/</link>
		<comments>http://aras-p.info/blog/2008/08/28/hardware-of-the-casual-gamer/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 18:32:57 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[gpu]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=200</guid>
		<description><![CDATA[(if this sounds like a rehash of a blog post on blogs.unity3d.com, well, it is&#8230;) Everyone knows the Valve&#8217;s hardware survey. But what if your target game players are not the traditional &#8220;big budget AAA game&#8221; type? For example, at the moment most Unity Web Player games are oriented to much more casual market, so [...]]]></description>
			<content:encoded><![CDATA[<p><em>(if this sounds like a rehash of a blog post on <a href="http://blogs.unity3d.com/2008/08/01/hardware-of-the-casual-gamer/">blogs.unity3d.com</a>, well, it is&#8230;)</em></p>
<p>Everyone knows the <a href="http://www.steampowered.com/status/survey.html">Valve&#8217;s hardware survey</a>. But what if your target game players are not the traditional &#8220;big budget AAA game&#8221; type? For example, at the moment most Unity Web Player games are oriented to much more casual market, so hardware there might be <em>very</em> different. And indeed, turns out it is quite different.</p>
<p>Without further ado, here&#8217;s the data we have: <a href="http://unity3d.com/webplayer/hwstats/"><strong>Unity Web Player hardware statistics</strong></a>.</p>
<p>It&#8217;s about two million data points since we started gathering it earlier this year.</p>
<p>Some subjective points of interest (I&#8217;ll be using current data for 2008 Q3 here):</p>
<ul>
<li><a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-os.html">Operating systems</a>: Mac OS X is 2.5%, the rest is Windows. 64 bit Windows haven&#8217;t really picked up yet (0.7%). Windows 2000 is dying fast (0.7%). OS X Leopard already took over OS X Tiger.</li>
<li><a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-cpuvendor.html">CPUs</a>: poor Transmeta :) <a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-cores.html">Dual core</a> CPUs are becoming the norm (46%).</li>
<li><a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-gfxcard.html">Graphics cards</a>: quite sad, in fact&#8230; top 15 cards are slow or <em>horribly slow</em>. Capability wise, they are quite good, with <a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-shader.html">about 70%</a> having shader model 2.0 or higher. Shader model 1.x cards are dead. &#8220;<a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-shadergen.html">Can has DX10</a>&#8221; is 2.7%.</li>
<li>Casual machines don&#8217;t have lots of <a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-ram.html">RAM</a>. Nor lots of <a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-vram.html">VRAM</a>.</li>
<li>Most popular nvidia driver? <a href="http://unity3d.com/webplayer/hwstats/pages/web-2008Q3-gfxdriver.html">56.73</a>. Looks like this is the driver that comes integrated in XP SP2&#8230; Now, who says regular people <em>ever</em> update their drivers? Likewise, vga.dll (i.e. standard VGA) is 1.6% of machines; additional 1.5% don&#8217;t report any driver (not sure how that happens&#8230;).</li>
</ul>
<p>So yeah. Casual machines: capabilities quite okay, performance low, low, low. That&#8217;s life.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/08/28/hardware-of-the-casual-gamer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Depth bias and the power of deceiving yourself</title>
		<link>http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/</link>
		<comments>http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 06:52:19 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[d3d]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

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

		<guid isPermaLink="false">http://aras-p.info/blog/2008/02/20/dogfooding-peaninjas-part-1/</guid>
		<description><![CDATA[I decided to make a very small game with Unity. Coincidentally, Danc of Lost Garden fame just announced a small game design challenge called &#8220;Play With Your Peas&#8220;. It comes with a set of cute graphics and a ready-to-be-implemented game design. What more could I want? So it&#8217;s a small very small 2D game without [...]]]></description>
			<content:encoded><![CDATA[<p>I decided to make a very small game with Unity. Coincidentally, Danc of <a href="http://www.lostgarden.com/">Lost Garden</a> fame just announced a small game design challenge called &#8220;<a href="http://lostgarden.com/2008/02/play-with-your-peas-game-prototyping.html">Play With Your Peas</a>&#8220;. It comes with a set of cute graphics and a ready-to-be-implemented game design. What more could I want?</p>
<p>So it&#8217;s a <del datetime="2008-02-20T19:15:28+00:00">small</del> very small 2D game without <em>any</em> next-gen bells and whistles. It can probably be done casually on the side, by allocating an hour here and there. We&#8217;ll see how it goes. Hey, I never <em>actually</em> done any game in Unity, I only make or break some underlying parts&#8230;</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080211a.png' title='Look! No game there!'><img class='alignleft' src='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080211a.thumbnail.png' alt='Look! No game there!' /></a>Of course, first I start with no game, just imported graphics. Hey look, I can do sprites!</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080216a.png' title='Level editing'><img class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080216a.thumbnail.png' alt='Level editing' /></a>Then cook up some base things: define the game grid, throw in some basic user interface on the right hand side, and make it actually do something. This wasn&#8217;t so hard; that already gets me an almost working level building functionality. It does not have fancy block building delay or block deletion yet; that will come later.</p>
<p>Next come basic physics. Danc&#8217;s design calls for simple arcade-like physics (things moving at constant speeds, bouncing off at equal angles, and so on), but in Unity I have a fully fledged <a href="http://unity3d.com/unity/features/physics">physics engine</a> just waiting to be used. Let&#8217;s use that.</p>
<p>The design has sloped ramp pieces, which are hard to approximate using any primitive colliders, so instead I&#8217;ll use convex mesh colliders for them. Now, on this machine I only have Blender, which I totally don&#8217;t know how to use; and I was too lazy to go to PC and use 3ds Max there. What a coder does? Of course, just type in the mesh file in ASCII FBX format. Excerpt:</p>
<blockquote><p>; scaled 2x in Z, by 0.85 in Y<br />
Vertices: -0.5,-0.425,-1.0, 0.5,-0.425,-1.0, -0.5,-0.425,1.0, 0.5,-0.425,1.0,  -0.5,0.425,-1.0, -0.5,0.425,1.0<br />
PolygonVertexIndex: 0,1,-3,2,1,-4,1,0,-5,2,3,-6,0,2,-5,2,5,-5,3,1,-5,5,3,-5
</p></blockquote>
<p>It&#8217;s a left ramp mesh! So much for fancy <a href="http://unity3d.com/unity/features/asset-importing">asset auto-importing</a> functionality, when you don&#8217;t know how to use those 3D apps :)</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080216b.png' title='Physics!'><img class='alignleft' src='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080216b.thumbnail.png' alt='Physics!' /></a><a href='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080216c.png' title='Pea stack!'><img class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2008/02/peas080216c.thumbnail.png' alt='Pea stack!' /></a>After a while I&#8217;ve got peas being controlled by physics, colliding with level and so on. Physics is very bad for productivity, as I ended up just playing around with pea-stacks!</p>
<p>So far there&#8217;s no <em>game</em> yet&#8230; Next up: implement some AI for the peas, so they can wander around, climb the walls, fall down and bounce around. I guess that will be more work and less playing around&#8230; We&#8217;ll see.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/02/20/dogfooding-peaninjas-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Off-Road Velociraptor Safari</title>
		<link>http://aras-p.info/blog/2008/02/05/off-road-velociraptor-safari/</link>
		<comments>http://aras-p.info/blog/2008/02/05/off-road-velociraptor-safari/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 17:43:29 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2008/02/05/off-road-velociraptor-safari/</guid>
		<description><![CDATA[This is just too cool: Off-Road Velociraptor Safari game. Read that again. Who says game industry is all about sequels and safe licenses? You drive a jeep with a spiky ball, and your goal is to chase down raptors and send them to the future, presumably to end world hunger. Or you can do stunts. [...]]]></description>
			<content:encoded><![CDATA[<p>This is just too cool: <em>Off-Road Velociraptor Safari</em> game. Read that again. Who says game industry is all about sequels and safe licenses?</p>
<p>You drive a jeep with a spiky ball, and your goal is to chase down raptors and send them to the future, presumably to end world hunger. Or you can do stunts. And <em>you the driver</em> are a raptor, only you wear a hat and a monocle.</p>
<p>Just go and play it already: <a href="http://raptorsafari.com/"><strong>raptorsafari.com</strong></a>. It&#8217;s free.</p>
<p>Or watch a <a href="http://www.vimeo.com/618534">trailer</a> if you want to miss all the <em>real</em> fun, or read a <a href="http://raptorsafari.com/press-raptor-feathers.php">press release</a>. <em>Of course</em> it&#8217;s made in Unity, in two months from start to finish.</p>
<p>To me, this is a perfect example of focus. Basically there are three things &#8211; 1) vehicle, 2) raptors, 3) physics mayhem &#8211; and that almost describes a game. Yes, there are crates and stunts and achievements and online leaderboards, but that&#8217;s just additional stuff on top of the core game.</p>
<p>Sounds like a good plan for making game prototypes:</p>
<ol>
<li>Think up a game idea and describe it in one concise sentence. The idea may be totally crazy, like in this case. I guess an idea like Velociraptor Safari would not fly in a pitch at any publisher, but that does not matter at this point.</li>
<li>Get a small team of smart people. In Flashbang&#8217;s case, it seems they were 4 to 7 person team.</li>
<li>Choose a game engine/toolset that will allow you to make your game fast. *cough cough*</li>
<li><em>Do it!</em></li>
</ol>
<p>All the above requires is a small smart team and groceries/rent for a couple of months.</p>
<p>Your original idea may be totally crazy, but with the actual working prototype at hand it might <em>just work</em>. Looks like Velociraptor Safari really clicked something on the internets (see <a href="http://kotaku.com/350934/please-go-play-velociraptor-safari">Kotaku</a>, <a href="http://jayisgames.com/archives/2008/01/offroad_velociraptor_safari.php">JayIsGames</a>, <a href="http://www.destructoid.com/off-road-velociraptor-safari-is-out-go-murder-raptors-with-a-jeep-67798.phtml">Destructoid</a>, <a href="http://tigsource.com/articles/2008/01/29/off-road-velociraptor-safari">TIGSource</a>, <a href="http://www.atomicgamer.com/article.php?id=525">AtomicGamer</a>, &#8230;).</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2008/02/05/off-road-velociraptor-safari/feed/</wfw:commentRss>
		<slash:comments>0</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>Splume!</title>
		<link>http://aras-p.info/blog/2007/10/21/splume/</link>
		<comments>http://aras-p.info/blog/2007/10/21/splume/#comments</comments>
		<pubDate>Sun, 21 Oct 2007 05:42:48 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/10/21/splume/</guid>
		<description><![CDATA[Flashbang Studios just launched Splume, probably the first game out there* made with Unity 2.0. It just won our &#8220;Top DOG&#8221; competition by the way. It&#8217;s a cute little gem, or alternatively, &#8220;Puzzle Bobble meets Ageia&#8217;s PhysX engine&#8221;. Lots of levels, user level editor, some AJAX magic and so on, and everything made in about [...]]]></description>
			<content:encoded><![CDATA[<p>Flashbang Studios just launched <a href="http://splume.flashbangstudios.com/">Splume</a>, <del datetime="2007-10-22T13:42:52+00:00">probably the first game out there</del>* made with Unity 2.0. It <a href="http://forum.unity3d.com/viewtopic.php?t=7197">just won</a> our &#8220;Top DOG&#8221; competition by the way.</p>
<p>It&#8217;s a cute little gem, or alternatively, &#8220;Puzzle Bobble meets Ageia&#8217;s PhysX engine&#8221;. Lots of levels, user level editor, some AJAX magic and so on, and everything made in about four weeks. Matthew has some <a href="http://forum.unity3d.com/viewtopic.php?t=7302">technical details</a> for the curious.</p>
<p>Here are some shots and a <a href="http://youtube.com/watch?v=0VuB2XFMHk8">youtube trailer</a> for the lazy ones. The youtube trailer uses music from <a href="http://www.8bitpeoples.com/">8bitpeoples</a> which can&#8217;t be bad :)<br />
<a href='http://aras-p.info/blog/wp-content/uploads/2007/10/splume_teaser_1.jpg' title='Splume shot #1'><img src='http://aras-p.info/blog/wp-content/uploads/2007/10/splume_teaser_1.jpg' alt='Splume shot #1' /></a><a href='http://aras-p.info/blog/wp-content/uploads/2007/10/splume_teaser_2.jpg' title='Splume shot #2'><img src='http://aras-p.info/blog/wp-content/uploads/2007/10/splume_teaser_2.jpg' alt='Splume shot #2' /></a></p>
<p><object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/0VuB2XFMHk8"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/0VuB2XFMHk8" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object></p>
<p>But really, you should just go and play it: <a href="http://splume.flashbangstudios.com/">splume.flashbangstudios.com</a></p>
<p><em>* I stand corrected: <a href="http://www.mrjoy.com/games/6">When Orcs Attack</a> also was made with Unity 2.0, and it was released earlier!</em></p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/10/21/splume/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Unity 2.0 is out</title>
		<link>http://aras-p.info/blog/2007/10/19/unity-20-is-out/</link>
		<comments>http://aras-p.info/blog/2007/10/19/unity-20-is-out/#comments</comments>
		<pubDate>Fri, 19 Oct 2007 08:03:08 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/10/19/unity-20-is-out/</guid>
		<description><![CDATA[Finally, Unity 2.0 is out. Took a bit longer than we expected (but not 3.1415926 times longer, so we&#8217;re all good), but now, after half a year in beta testing, over a dozen alpha/beta releases, it is finally shipped. Feels good! It&#8217;s been in active development for about a year (though some of 2.0 features [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, <a href="http://unity3d.com/unity/whats-new/unity-2.0">Unity 2.0</a> is out. Took a bit longer than we expected (but not 3.1415926 times longer, so we&#8217;re all good), but now, after half a year in beta testing, over a dozen alpha/beta releases, it is finally shipped. Feels good!</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/10/svngraph.png' title='svn commits over time'><img class='alignleft' src='http://aras-p.info/blog/wp-content/uploads/2007/10/svngraph.thumbnail.png' alt='svn commits over time' /></a>It&#8217;s been in active development for about a year (though some of 2.0 features were in development for much longer), with source control commits graph looking roughly like this. We pretty much spent the summer doing 800 svn commits/month with about four major code monkeys :) Now that the release is done I fully expect the graph to drop off to low values again (is it called &#8220;burnout&#8221;?).</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/10/goldengate.jpg' title='San Francisco!'><img class='alignright' src='http://aras-p.info/blog/wp-content/uploads/2007/10/goldengate.thumbnail.jpg' alt='San Francisco!' /></a>Last week there was the first <a href="http://unity3d.com/unite/">Unity conference</a>, and it was a blast. It was like, <em>oh my, it&#8217;s full of people and all about unity!</em> In other words, really really cool.</p>
<p><a href='http://aras-p.info/blog/wp-content/uploads/2007/10/willitlaunch.jpg' title='Will it launch? It has to!'><img class='alignleft' src='http://aras-p.info/blog/wp-content/uploads/2007/10/willitlaunch.thumbnail.jpg' alt='Will it launch? It has to!' /></a>The night before the conference was spent in the hotel, doing last tweaks to the website and launch demos. If the presenters during keynote talk looked confused or exhausted, that&#8217;s a combination of trans-Atlantic flight <em>and</em> this last night of work. In fact, the very last fixes to the website were done during the keynote&#8230; oh well, Murphy&#8217;s law for the win.</p>
<p>Now what? Time to start working on Unity 2.x release :)</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/10/19/unity-20-is-out/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>San Francisco!</title>
		<link>http://aras-p.info/blog/2007/10/09/san-francisco/</link>
		<comments>http://aras-p.info/blog/2007/10/09/san-francisco/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 00:47:44 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/2007/10/09/san-francisco/</guid>
		<description><![CDATA[San Francisco, here we come.]]></description>
			<content:encoded><![CDATA[<p>San Francisco, <a href="http://unity3d.com/unite/">here we come</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/10/09/san-francisco/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lolshadows!</title>
		<link>http://aras-p.info/blog/2007/08/28/lolshadows/</link>
		<comments>http://aras-p.info/blog/2007/08/28/lolshadows/#comments</comments>
		<pubDate>Tue, 28 Aug 2007 18:53:13 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[unity]]></category>
		<category><![CDATA[work]]></category>

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

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

		<guid isPermaLink="false">http://aras-p.info/blog/2007/05/19/megapixel-on-shockwavecom/</guid>
		<description><![CDATA[I just have to blog this: shockwave.com just launched a Unity web game &#8211; MegaPixel. It&#8217;s a pure, abstract, and mega-fun FPS. It&#8217;s set up in a very small space (the levels are basically boxes with several smaller boxes inside), and it pretty much uses a single texture for the whole game, and it does [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://aras-p.info/blog/wp-content/uploads/2007/05/megapixel-3normal.jpg" title="MegaPixel!"><img src="http://aras-p.info/blog/wp-content/uploads/2007/05/megapixel-3normal.thumbnail.jpg" class="alignright" alt="MegaPixel!" /></a>I just have to blog this: shockwave.com just launched a Unity web game &#8211; <a href="http://www.shockwave.com/gamelanding/megapixel.jsp" title="Death to the pixels!">MegaPixel</a>. It&#8217;s a pure, abstract, and mega-fun FPS. It&#8217;s set up in a very small space (the levels are basically boxes with several smaller boxes inside), and it pretty much uses a single texture for the whole game, and it does not use much more than particle effects for <em>everything</em> (the levels, enemies, weapons and everything else is just particles). Pure genius.</p>
<p>I like it! That says a lot, because last time I played FPS was <em>ages</em> ago. Finally, someone made a game that I can like again. <em>How much I&#8217;m biased because it&#8217;s made with Unity&#8230; decide for yourselves :)</em></p>
<p>Now the killer part: the game is designed and developed solely by a 15 year old &#8211; <a href="http://yogware.bluegillstudios.com/site/">Forest &#8220;Yoggy&#8221; Johnson</a>. How cool is that?</p>
<p>Enough talking, just go and <a href="http://www.shockwave.com/gamelanding/megapixel.jsp">play it</a>. And remember that you didn&#8217;t see cool until you get to the robot level!</p>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2007/05/19/megapixel-on-shockwavecom/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>A steam of random things</title>
		<link>http://aras-p.info/blog/2006/08/14/a-steam-of-random-things/</link>
		<comments>http://aras-p.info/blog/2006/08/14/a-steam-of-random-things/#comments</comments>
		<pubDate>Sun, 13 Aug 2006 21:24:00 +0000</pubDate>
		<dc:creator>Aras Pranckevičius</dc:creator>
				<category><![CDATA[demos]]></category>
		<category><![CDATA[opengl]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://aras-p.info/blog/?p=96</guid>
		<description><![CDATA[Awards: Hey, we&#8216;ve got a &#8220;runner up&#8221; award in Apple Design Awards 2006, Best Use of Graphics category! Yeah, a runner up is more like &#8220;the first of the losers&#8221;, but oh well. Got beaten by modo 201, which probably is a fair trade. It&#8217;s just that we thought we&#8217;d be in Best Developer Tool [...]]]></description>
			<content:encoded><![CDATA[<div style="text-align: justify;"><span style="font-weight: bold;">Awards:</span> Hey, <a href="http://unity3d.com">we</a>&#8216;ve got a &#8220;runner up&#8221; award in <a href="http://developer.apple.com/ada/">Apple Design Awards 2006</a>, Best Use of Graphics category! Yeah, a runner up is more like &#8220;the first of the losers&#8221;, but oh well. Got beaten by <span style="font-style: italic;">modo 201</span>, which probably is a fair trade. It&#8217;s just that we thought we&#8217;d be in <span style="font-style: italic;">Best Developer Tool</span> category, but that is apparently for text editors and scripting languages :)</p>
<p><span style="font-weight: bold;">Demos: </span>In the other news, fellow <a href="http://nesnausk.org/members.php">ReJ</a> with TBL just won Assembly 2006 demo competition with an <a href="http://www.pouet.net/prod.php?which=25778">Amiga demo</a>, putting all PC demos faces&#8217; to dust. Check it out. Art direction over hardware capabilities, one more time.</p>
<p><span style="font-weight: bold;">Drivers:</span> why oh why the graphics drivers must be so bad? The other day I was thinking why can&#8217;t they auto-update themselves (with an option to turn it off for corporate users etc.). Now you&#8217;ve got a (not so recent!) driver that is able to parse vertex programs wrong, and a user who does not have a clue that he should update it. It&#8217;s bad enough to have a bug in the first place, but auto-update at least would fix&#8230;</p>
<p>Or you have a driver that says <span style="font-style: italic;">&#8220;I&#8217;m OpenGL 1.2!&#8221;</span> but the 3D texture functions are null. <span style="font-style: italic;">And</span> it&#8217;s the most recent driver for a particular graphics card that you can buy today! <span style="font-style: italic;">And</span> it&#8217;s not even a hard problem! What the developers are thinking &#8211; they go over the required GL 1.2 functionality, see that some is actually missing and decide <span style="font-style: italic;">&#8220;ah, screw it, we&#8217;ll say it&#8217;s 1.2 anyways&#8221;</span>?!</p>
<p>I just don&#8217;t get it. I could use some enlightenment on this.</p></div>
]]></content:encoded>
			<wfw:commentRss>http://aras-p.info/blog/2006/08/14/a-steam-of-random-things/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
