<?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>ZSpline</title>
	<atom:link href="http://www.zspline.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zspline.net/blog</link>
	<description>Developing games and self</description>
	<lastBuildDate>Mon, 27 May 2013 08:15:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Amps &#8211; Basics</title>
		<link>http://www.zspline.net/blog/2013/04/17/amps-basics/</link>
		<comments>http://www.zspline.net/blog/2013/04/17/amps-basics/#comments</comments>
		<pubDate>Wed, 17 Apr 2013 14:42:13 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Amps]]></category>
		<category><![CDATA[My projects]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2119</guid>
		<description><![CDATA[During the past 4 weeks I implemented the framework for this particle system so Amps reached its first working version. In this article I&#8217;ll describe the basic workflow through a few examples. Before we move on I&#8217;d like to thank Attila Malarik who acted as 24/7 Unity and C# helpline despite crunching at his day [...]]]></description>
				<content:encoded><![CDATA[<p>During the past 4 weeks I implemented the framework for this particle system so Amps reached its first working version. In this article I&#8217;ll describe the basic workflow through a few examples.</p>
<p>Before we move on I&#8217;d like to thank <a href="http://about.me/attilam" target="_blank">Attila Malarik</a> who acted as 24/7 Unity and C# helpline despite crunching at his day job.</p>
<h6>Setting up the emitter</h6>
<div class="myvideotag" style="width: 512px;"><iframe src="http://player.vimeo.com/video/64231225?title=0&amp;byline=0&amp;portrait=0" width="512" height="390" frameborder="0"></iframe></div>
<p>I created an empty game object and added the Amps Emitter component. (All non functional parts of the Amps editor UI were removed for clarity.)</p>
<p>The emitter stack contains a single module which controls the basic properties of the particle system, currently only the number of particles.</p>
<p>After setting the spawn rate with a simple scalar module, I took care of the <em>DeathCondition</em>: if that stack produces a value of 1 for a particular particle then that particle gets killed. Having a constant value wasn&#8217;t very useful here so I set up a simple curve which outputs 1 when the <em>ParticleTime</em> reaches 3. This is the classic functionality of &#8220;kill by age&#8221; but the curve could be controlled by <em>any</em> of the emitter or particle properties, from emitter speed to particle alpha.</p>
<p>The last step was adding a random Vector module to the position stack which defined where the particles were located. I turned on visualization to make it more apparent where the limits are.</p>
<h6>Simple motion</h6>
<p>Although the acceleration and velocity stacks are not yet implemented, there are several ways to make the particles move using only the position stack.</p>
<div class="myvideotag" style="width: 512px;"><iframe src="http://player.vimeo.com/video/64231226?title=0&amp;byline=0&amp;portrait=0" width="512" height="390" frameborder="0"></iframe></div>
<p>When the weight of the vector module is decreased (indicated by the pie meter) the particles start to slide into place. This happens because the stack&#8217;s value is carried over from the previous update and not zeroed out. The less weight the module has the more time it&#8217;s going to take to fully overwrite the stack&#8217;s default value (0, 0, 0).</p>
<p>In the second part of the video I set the blend mode to <em>Add</em> which made the the particles move beyond the point defined by the module: due to the blending mode their position &#8220;grows&#8221; steadily.</p>
<p>Yet another way for movement is animating the X and Z coordinates of the particles by a curve: Here they steadily move sideways on X while their motion on Z reflects the drawn curve. Everything is driven by <em>DeathCondition</em> so the closer they get to fulfilling that condition the further they progress on the curves.</p>
<p>The last example shows how to move particles using two modules: the first one provides the start value while the second &#8220;fades in&#8221; over time, using a curve in its Weight property.</p>
<h6>Samplers</h6>
<p>There is an important rule regarding random values in most modules: they are generated once and then stay the same throughout the life of the related entity (emitter of particle). If we want more control over this aspect we have to use the <em>sampler</em> group of nodes. The only sampler at this time is the <em>Point Sampler</em> module, so let&#8217;s see what can be done with it:</p>
<div class="myvideotag" style="width: 512px;"><iframe src="http://player.vimeo.com/video/64231227?title=0&amp;byline=0&amp;portrait=0" width="512" height="390" frameborder="0"></iframe></div>
<p>It behaves very similarly to the <em>Vector</em> module: it defines a position in different ways. The important addition here is that it can roll the dice again when the sampling condition is met.</p>
<p>First I set up the sampling so a new value was picked at every second and then, to make the transition apparent, I decreased the weight of the module to mix in particle position from the previous update. (As you might have already guessed, the flashing rectangles indicate when a new sample was picked for the highlighted example particle.)</p>
<p>The second example shows how two samplers can be set up in a way that each samples when the other is in full effect thus avoiding any jitter caused by the sudden change in output values.</p>
<p>So this is where the project is at: a lot is to be done but the foundations are working. If you have suggestions, ideas or questions, please <a href="mailto:zoltan.erdokovy@gmail.com">contact me</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2013/04/17/amps-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Amps &#8211; Introduction</title>
		<link>http://www.zspline.net/blog/2013/03/11/amps-introduction/</link>
		<comments>http://www.zspline.net/blog/2013/03/11/amps-introduction/#comments</comments>
		<pubDate>Mon, 11 Mar 2013 09:31:41 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Amps]]></category>
		<category><![CDATA[My projects]]></category>
		<category><![CDATA[Unity]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2103</guid>
		<description><![CDATA[I teamed up with my friend and veteran Unity user Attila Malarik to make a particle system for Unity: It&#8217;s called Another Modular Particle System or &#8220;Amps&#8221;. Attila handles the lower level tasks (framework, resource management, etc), I cover high level system design and UX and when it comes to the middle layer (creating the [...]]]></description>
				<content:encoded><![CDATA[<p>I teamed up with my friend and veteran Unity user <a href="http://www.attilam.com/" target="_blank">Attila Malarik</a> to make a particle system for Unity: It&#8217;s called Another Modular Particle System or &#8220;Amps&#8221;.</p>
<p>Attila handles the lower level tasks (framework, resource management, etc), I cover high level system design and UX and when it comes to the middle layer (creating the reusable building blocks) we will share the work as we go.</p>
<h6>The user interface</h6>
<p>I&#8217;ve just finished the first iteration of the editor window. The controls are not linked to anything yet but the layout reflects the base idea behind Amps:</p>
<p style="text-align: center;"><a href="http://www.zspline.net/blog/wp-content/gallery/amps/amps01.png" rel="lightbox"><img class="decoded aligncenter" alt="http://www.zspline.net/blog/wp-content/gallery/amps/amps01.png" src="http://www.zspline.net/blog/wp-content/gallery/amps/amps01.png" width="512" height="327" /></a></p>
<p>A particle emitter itself is a component on a GameObject. (So a particle system contains exactly one emitter so I&#8217;ll use those terms interchangeably.) The emitter has several <em>stacks</em> defining it&#8217;s behavior as seen on the left most column. Each stack can contain any number of <em>modules</em> and each module has several <em>properties</em>. While simpler property types can be edited right in the property list more complex ones get dedicated <em>value pickers</em>.</p>
<p>Now let&#8217;s see each part a bit closer.</p>
<h6>Stacks</h6>
<p>The <em>Emitter</em> stack is a special one as it contains exactly one module for setting up the particle system. Particle limits, LOD configuration, update rate and similar properties belong here.</p>
<p>The <em>Rendering</em> stack can contain one or more rendering modules which define how the abstract particle data is displayed. Point, arrow, sprite, ribbon and mesh modules are typical examples but it should be possible to extend the system beyond that including skeletal meshes for a very crude crowd simulation.</p>
<p><em>External Influences</em> is about entities outside the particle system which affect it&#8217;s properties. For instance colliders directly change particle position, wind zones affect acceleration, color volumes adjust particle color.</p>
<p>The <em>Spawn Condition</em> stack defines when to spawn particles. If any of the modules in there return &#8216;true&#8217; then a spawn cycle is initiated. Such a cycle lasts as long as the result of the <em>Spawn Duration</em> stack and will produce as many particles as indicated in <em>Spawn Amount</em>.</p>
<p>The next stack group deals with particle removal in a similar fashion: when to kill one and how long it will take for them to die.</p>
<p>The yellow stacks represent the standard set of particle attributes.</p>
<p>Typical usage scenarios for each stacks will be covered in separate articles so now let&#8217;s move on to the second column, the modules list.</p>
<h6>Modules</h6>
<p>Data flows downward between modules: the result of the first one is modified by the second one and so on like an upside down Photoshop layer stack. Also somewhat similar to PS is that modules generally have <em>Weight</em> and <em>Blending</em> mode properties which define how they change the result arriving from above them. Certain types of modules (like math operations) don&#8217;t have blending modes only weight. Another permanent property is the <em>Description</em> field where the user can take notes regarding the function of the module. It is a very important feature which keeps even complex particle systems easy to read.</p>
<p>The properties feed the internal mechanics of the module which &#8211; combined with the result of earlier ones &#8211; produce a single value to be passed on. Internally modules are treated as black boxes: they take a standard set of input parameters, create their own UI representation and eventually produce a vector4. This way third parties will be able to extend the system simply by following a few design rules.</p>
<p>Modules can be added, disabled, duplicated, instanced, rearranged, and deleted in this list view. Their properties are edited in the property list.</p>
<h6>Properties</h6>
<p>A module can contain any number of properties. They are grouped into logical units and frequently used properties are displayed at the top for easier access.</p>
<p>There are several property types: bool, integer (dropdown menus), string, scalar, vector4 and color. (The last one is really just a vector4 represented differently to the user.)<br />
Scalars, vectors and colors can have a constant value, a random constant, a curve or a random curve. These more complex definitions have their dedicated value pickers in the right most column.</p>
<h6>Value pickers</h6>
<p>Here are the currently functional value pickers:</p>
<table align="center">
<tbody>
<tr>
<td>
<div class="wp-caption aligncenter" style="width: 170px"><a title="picker01.png" href="http://www.zspline.net/blog/wp-content/gallery/amps/picker01.png" rel="lightbox"><img class="thumb " id="thumb887" alt="" src="http://www.zspline.net/blog/wp-content/gallery/amps/thumbs/thumbs_picker01.png" width="160" height="34" /></a>
<p class="wp-caption-text">Random scalar</p>
</div>
</td>
<td>
<div class="wp-caption aligncenter" style="width: 123px"><a title="picker02.png" href="http://www.zspline.net/blog/wp-content/gallery/amps/picker02.png" rel="lightbox"><img class="thumb " id="thumb888" alt="" src="http://www.zspline.net/blog/wp-content/gallery/amps/thumbs/thumbs_picker02.png" width="113" height="160" /></a>
<p class="wp-caption-text">Scalar curve</p>
</div>
</td>
<td>
<div class="wp-caption aligncenter" style="width: 120px"><a title="picker03.png" href="http://www.zspline.net/blog/wp-content/gallery/amps/picker03.png" rel="lightbox"><img class="thumb " id="thumb889" alt="" src="http://www.zspline.net/blog/wp-content/gallery/amps/thumbs/thumbs_picker03.png" width="110" height="160" /></a>
<p class="wp-caption-text">Random scalar curve</p>
</div>
</td>
</tr>
<tr>
<td>
<div class="wp-caption aligncenter" style="width: 170px"><a title="picker04.png" href="http://www.zspline.net/blog/wp-content/gallery/amps/picker04.png" rel="lightbox"><img class="thumb " id="thumb890" alt="" src="http://www.zspline.net/blog/wp-content/gallery/amps/thumbs/thumbs_picker04.png" width="160" height="56" /></a>
<p class="wp-caption-text">Vector</p>
</div>
</td>
<td>
<div class="wp-caption aligncenter" style="width: 170px"><a title="picker05.png" href="http://www.zspline.net/blog/wp-content/gallery/amps/picker05.png" rel="lightbox"><img class="thumb " id="thumb891" alt="" src="http://www.zspline.net/blog/wp-content/gallery/amps/thumbs/thumbs_picker05.png" width="160" height="140" /></a>
<p class="wp-caption-text">Random vector</p>
</div>
</td>
<td>
<div class="wp-caption aligncenter" style="width: 95px"><a title="picker06.png" href="http://www.zspline.net/blog/wp-content/gallery/amps/picker06.png" rel="lightbox"><img class="thumb " id="thumb892" alt="" src="http://www.zspline.net/blog/wp-content/gallery/amps/thumbs/thumbs_picker06.png" width="85" height="160" /></a>
<p class="wp-caption-text">Color</p>
</div>
</td>
</tr>
</tbody>
</table>
<p>The color picker is a replacement of the inbuilt one which doesn&#8217;t support high dynamic range values. (The three part color preview strip shows the clamped color, the tonemapped one and the visual alpha.)<br />
I&#8217;ll also have to create our own curve editor because the default is rather limited: unable to display multiple curves at once, presets can&#8217;t be changed, there is no numeric input for the selected key.</p>
<p>And that concludes this introduction to Amps. If you have any questions or suggestions please don&#8217;t hesitate to <a href="mailto:zoltan.erdokovy@gmail.com">contact me</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2013/03/11/amps-introduction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Update</title>
		<link>http://www.zspline.net/blog/2013/02/24/update-2/</link>
		<comments>http://www.zspline.net/blog/2013/02/24/update-2/#comments</comments>
		<pubDate>Sun, 24 Feb 2013 15:10:46 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Amps]]></category>
		<category><![CDATA[One Minute Dungeon]]></category>
		<category><![CDATA[Unity]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2096</guid>
		<description><![CDATA[In the new year I started actively looking for a job abroad so I created a portfolio magazine and updated the article about the now defunct Punisher PSN game with two videos showing the maps and special effects I worked on. Currently I&#8217;m developing a simple but visual effects heavy Unity game called One Minute [...]]]></description>
				<content:encoded><![CDATA[<p>In the new year I started actively looking for a job abroad so I created a <a href="http://zspline.net/files/Zoltan_Erdokovy_Portfolio.pdf" target="_blank">portfolio magazine</a> and updated the article about the now defunct <a href="http://www.zspline.net/blog/the-punisher-no-mercy/" target="_blank">Punisher PSN game</a> with two videos showing the <a href="https://vimeo.com/56643843" target="_blank">maps</a> and <a href="https://vimeo.com/56760174" target="_blank">special effects</a> I worked on.</p>
<p><a rel="lightbox" title="OMD_preview.png" href="http://www.zspline.net/blog/wp-content/gallery/oneminutedungeon/OMD_preview.png"> <img class="thumb alignleft" id="thumb884" alt="" src="http://www.zspline.net/blog/wp-content/gallery/oneminutedungeon/thumbs/thumbs_OMD_preview.png" width="121" height="160" /> </a>Currently I&#8217;m developing a simple but visual effects heavy Unity game called One Minute Dungeon. It&#8217;s really just a real life scenario to learn the ropes and to test what the engine can do vfx wise.</p>
<p>It became clear early on that the stock particle system is very limited, especially when compared to UDK&#8217;s Cascade. Right now I don&#8217;t mind this because the tricks and workarounds I have to come up with force me to learn more about the internal workings of the engine. However in an actual production environment I&#8217;d be very unhappy with the sub-par solution so with a friend of mine we started working on a flexible, modular particle system (AMPS). The high level design is in reasonably good shape so when I&#8217;m done with the UI mockups then I&#8217;ll be able to write a post about the general idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2013/02/24/update-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Happy Holidays</title>
		<link>http://www.zspline.net/blog/2012/12/22/happy-holidays/</link>
		<comments>http://www.zspline.net/blog/2012/12/22/happy-holidays/#comments</comments>
		<pubDate>Sat, 22 Dec 2012 14:46:24 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2067</guid>
		<description><![CDATA[Best wishes for everyone! :)]]></description>
				<content:encoded><![CDATA[<p>Best wishes for everyone! :)</p>
<p><a href="http://www.zspline.net/blog/wp-content/gallery/misc/Holiday2012.jpg"></p>
<p style="text-align: center;"><img class="decoded aligncenter" alt="http://www.zspline.net/blog/wp-content/gallery/misc/Holiday2012.jpg" src="http://www.zspline.net/blog/wp-content/gallery/misc/Holiday2012.jpg" width="512" height="384" /></p>
<p></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/12/22/happy-holidays/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Updates</title>
		<link>http://www.zspline.net/blog/2012/12/04/updates/</link>
		<comments>http://www.zspline.net/blog/2012/12/04/updates/#comments</comments>
		<pubDate>Tue, 04 Dec 2012 14:02:25 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[My projects]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2058</guid>
		<description><![CDATA[Layer exporter for modo is updated, now it should work fine with 601. I also updated my Photoshop panels to CS6. Finally the Dynamic Grid editor extension for Unity had a patch fixing some issues and adding some functionality.]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.zspline.net/blog/2011/07/25/exportlayer-v1-3-for-modo-501/" target="_blank">Layer exporter for modo</a> is updated, now it should work fine with 601.</p>
<p>I also updated my <a href="http://www.zspline.net/blog/my-photoshop-panels-cs5/" target="_blank">Photoshop panels</a> to CS6.</p>
<p>Finally the <a href="http://u3d.as/content/zoltan-erdokovy/dynamic-grid/3iC" target="_blank">Dynamic Grid editor extension for Unity</a> had a patch fixing some issues and adding some functionality.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/12/04/updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Texture Synth filter for FilterForge</title>
		<link>http://www.zspline.net/blog/2012/10/17/texture-synth-filter-for-filterforge/</link>
		<comments>http://www.zspline.net/blog/2012/10/17/texture-synth-filter-for-filterforge/#comments</comments>
		<pubDate>Wed, 17 Oct 2012 10:16:30 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Filter Forge filters]]></category>
		<category><![CDATA[My projects]]></category>
		<category><![CDATA[filter forge]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2048</guid>
		<description><![CDATA[Recently I finished a filter which takes a low resolution, non-tiling image like this: and creates a higher resolution, seamlessly tiling version: You can find the filter here and the documentation here.]]></description>
				<content:encoded><![CDATA[<p>Recently I finished a filter which takes a low resolution, non-tiling image like this:</p>
<p style="text-align: center;"><a title="sample07a.jpg" href="http://www.zspline.net/blog/wp-content/gallery/tutorial_thetexturesynthfilter/sample07a.jpg" target="_blank"> <img id="thumb861" class="thumb aligncenter" src="http://www.zspline.net/blog/wp-content/gallery/tutorial_thetexturesynthfilter/thumbs/thumbs_sample07a.jpg?82418249" alt="" width="160" height="160" /></a></p>
<p>and creates a higher resolution, seamlessly tiling version:</p>
<p style="text-align: center;"><a title="sample07b.jpg" href="http://www.zspline.net/blog/wp-content/gallery/tutorial_thetexturesynthfilter/sample07b.jpg" target="_blank"> <img id="thumb862" class="thumb aligncenter" src="http://www.zspline.net/blog/wp-content/gallery/tutorial_thetexturesynthfilter/thumbs/thumbs_sample07b.jpg" alt="" width="160" height="160" /></a></p>
<p>You can find the filter <a href="http://www.filterforge.com/filters/11002.html" target="_blank">here</a> and the documentation <a href="http://www.zspline.net/blog/the-texture-synth-filter/" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/10/17/texture-synth-filter-for-filterforge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unity web player embedding</title>
		<link>http://www.zspline.net/blog/2012/10/04/unity-web-player-embedding/</link>
		<comments>http://www.zspline.net/blog/2012/10/04/unity-web-player-embedding/#comments</comments>
		<pubDate>Thu, 04 Oct 2012 12:30:51 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[My projects]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2026</guid>
		<description><![CDATA[This is a test for inserting the Unity web player to blog posts: Please view the full post to see the Unity content. If all went well you should be able to the view with LMB drag and zoom with the mouse wheel or RMB drag. The scene uses my latest project, a model viewer [...]]]></description>
				<content:encoded><![CDATA[<p>This is a test for inserting the Unity web player to blog posts:</p>
<p><em>Please view the full post to see the Unity content.</em></p>
<p>If all went well you should be able to the view with LMB drag and zoom with the mouse wheel or RMB drag.</p>
<p>The scene uses my latest project, a model viewer plugin for the Unity editor.</p>
<p><strong>UPDATE</strong>: The plugin is now <a href="http://u3d.as/content/zoltan-erdokovy/model-viewer" target="_blank">available in the asset store</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/10/04/unity-web-player-embedding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unity3d first impressions</title>
		<link>http://www.zspline.net/blog/2012/09/01/unity3d-first-impressions/</link>
		<comments>http://www.zspline.net/blog/2012/09/01/unity3d-first-impressions/#comments</comments>
		<pubDate>Sat, 01 Sep 2012 15:57:07 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[My projects]]></category>
		<category><![CDATA[unity]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=2017</guid>
		<description><![CDATA[I&#8217;m taking a break from the Unreal Engine to spend some time with Unity3d. I started working on a realtime model viewer for this blog but got sidetracked and made a dynamic grid editor extension first, available in the asset store. I yet to mess with the game engine part of Unity but the editor [...]]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m taking a break from the Unreal Engine to spend some time with <a href="http://www.unity3d.com/" target="_blank">Unity3d</a>. I started working on a realtime model viewer for this blog but got sidetracked and made a dynamic grid editor extension first, <a href="http://u3d.as/content/zoltan-erdokovy/dynamic-grid/3iC" target="_blank">available in the asset store</a>.</p>
<p>I yet to mess with the game engine part of Unity but the editor itself is excellent. I&#8217;ve been using UnrealEd for 13 years so it&#8217;s pretty much muscle memory by now but when compared to Unity, it just doesn&#8217;t hold up. The Unreal Engine still has one of the best node based material editor in the industry, something Unity sorely lacks, but otherwise it&#8217;s not even contest.</p>
<p>My favorite editor features so far:</p>
<ul>
<li><em>Editor scripting</em>: From creating game objects to drawing custom gizmos in the viewport, great many things can be coded.</li>
<li><em>Flexible editor GUI</em>: dockable panels, layout presets.</li>
<li><em>Asset management</em>: Like directly importing modo files&#8230; mind -peww- blown.</li>
<li><em>On the fly C# compile</em>: Code in Visual Studio, switch back to Unity, wait for compiling to finish, see results.</li>
</ul>
<p>So I&#8217;m very excited to explore this new toy further.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/09/01/unity3d-first-impressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Answering the social call</title>
		<link>http://www.zspline.net/blog/2012/08/10/answering-the-social-call/</link>
		<comments>http://www.zspline.net/blog/2012/08/10/answering-the-social-call/#comments</comments>
		<pubDate>Fri, 10 Aug 2012 18:44:35 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=1853</guid>
		<description><![CDATA[The start of my active job seeking efforts is marked by the creation of my Twitter account. You can also find me on Google+ or connect through LinkedIn. I&#8217;m usually present in the #techart and the #UDKC IRC channels.]]></description>
				<content:encoded><![CDATA[<p>The start of my active job seeking efforts is marked by the creation of my <a href="https://twitter.com/ZoltanErdokovy" target="_blank">Twitter account</a>. You can also find me on <a href="http://plus.google.com/113179306512174691790" target="_blank">Google+</a> or connect through <a href="http://www.linkedin.com/profile/view?id=7051997" target="_blank">LinkedIn</a>. I&#8217;m usually present in the <a href="http://webchat.freenode.net/?nick=techartist.&amp;channels=techart&amp;uio=Mj10cnVlJjExPTIzNgf7" target="_blank">#techart</a> and the <a href="http://udkc.info/index.php?title=IRC_chat" target="_blank">#UDKC</a> IRC channels.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/08/10/answering-the-social-call/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mallet Pinball: Behind the scenes</title>
		<link>http://www.zspline.net/blog/2012/08/08/mallet-pinball-behind-the-scenes/</link>
		<comments>http://www.zspline.net/blog/2012/08/08/mallet-pinball-behind-the-scenes/#comments</comments>
		<pubDate>Wed, 08 Aug 2012 07:54:58 +0000</pubDate>
		<dc:creator>Zoltan</dc:creator>
				<category><![CDATA[Gavit]]></category>
		<category><![CDATA[My projects]]></category>
		<category><![CDATA[UDK]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.zspline.net/blog/?p=1823</guid>
		<description><![CDATA[About a year ago I wrote an article about the early days of the pinball table, now after several mothballed months it&#8217;s done and here is how it works. The basic control setup A GVMachineController actor is on the map and a kismet node makes sure that the player takes control of it when the [...]]]></description>
				<content:encoded><![CDATA[<p>About a year ago I wrote an <a href="http://www.zspline.net/blog/2011/10/03/gavit-dev-diary-16-basic-pinball/" target="_blank">article about the early days of the pinball table</a>, now after several mothballed months it&#8217;s <a href="https://vimeo.com/46626017" target="_blank">done</a> and here is how it works.</p>
<h6>The basic control setup</h6>
<p>A <em>GVMachineController</em> actor is on the map and a kismet node makes sure that the player takes control of it when the level loads. After that, all input is processed by the machine which then adjusts linked actors (changes position, rotation, etc). For example here is how the right flippers are set up:</p>
<p><span id="more-1823"></span></p>
<p><a title="AirPinballBTS01.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS01.jpg" rel="lightbox"><img id="thumb826" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS01.jpg?41725394" alt="" width="160" height="64" /></a><strong>Machine name</strong> is just a user friendly way of telling multiple controllers apart.<br />
The <strong>Machine components</strong> list is for all the pieces of a machine which can be controlled separately (i.e., linked to a different button or axis). In this case there are 4 of them: left flipper, right flippers, the mallets and the ball. We&#8217;ll get to why the ball is there but first let&#8217;s see the guts of the &#8220;right flippers&#8221; component:</p>
<p><a title="AirPinballBTS02.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS02.jpg" rel="lightbox"> <img id="thumb827" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS02.jpg" alt="" width="160" height="157" /></a>The <strong>Input Source</strong> is now set to &#8220;User&#8221; which enables live input. The other option is &#8220;Matinee&#8221; in which case recorded performance is replayed. Then come the supported input devices where the actual buttons and axes are set.</p>
<p>With the <strong>Allow Recording</strong> flag set to true the incoming input events will be dumped into a text file in JSON format. That file can be converted into a matinee to drive the machine.<br />
Seamless Resume is not relevant right now so let&#8217;s move on to the <strong>Outputs</strong> list: each item in there defines an actor property which will be controlled by the input chosen earlier. This way multiple actors and/or multiple properties can be changed by a single device, in this case the right control key will rotate both right hand side flippers.<br />
The first output is the lower one of them:</p>
<p><a title="AirPinballBTS03.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS03.jpg" rel="lightbox"> <img id="thumb828" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS03.jpg" alt="" width="72" height="160" /></a>In the <strong>Machine Part</strong> property we reference an interpolating actor and specify that we want to work with its <em>Rotation</em> property. (Other supported actor types are light, vehicle, constraint, material instance, forcefield and thruster.)</p>
<p><strong>Button Value Mappings</strong>: Here we define the produced values for the two states of the button: what numbers we should output if the button is pressed or released. They are XYZ vectors just like everything else control related: every input device and actor property is treated as vector3 so they can be mixed and matched. (Although this does not necessarily mean that all members of the vector &#8220;do&#8221; something. For example a joystick will only change X and Y values, Z will stay at 0.)</p>
<p>Since a rotation property was chosen earlier, the XYZ members correspond to Pitch, Yaw and Roll. Now it&#8217;s easy to see what&#8217;s happening: when the button is released then rotation is not modified while pressing a button will change Yaw by 40 degrees. The time it takes to blend between the two states are defined in the next two <strong>Blend To&#8230;</strong>properties.<strong></strong></p>
<p><strong>Button Component Mapping</strong> defines which member in the target actor&#8217;s property is controlled by which member of the output we generate. In this case X and Z values are not used (nothing will change there in the target actor), only the generated Y (Yaw from 0 to 40 degrees) will be applied.</p>
<p>And finally <strong>Button Output Mode</strong> determines <em>how</em> the output values are applied to the target property&#8217;s existing values. Here it&#8217;s set to &#8220;Add&#8221; so the the <strong>Pressed Output</strong>&#8216;s 40 degrees will be added to whatever angle the flipper was placed on the map. Other modes include &#8220;Multiply&#8221; and &#8220;Direct&#8221;. The latter is for replacing the original value with the new one, in which case the <strong>Button Component Remapping</strong> comes in handy: using &#8220;None&#8221; on certain members will make sure that those values wont be modified at all, they don&#8217;t become the default 0 set in Released/Pressed outputs.</p>
<p>And that concludes the lower right flipper&#8217;s setup in the &#8220;Right Flippers&#8221; machine component. The other output in there is for the top right flipper: the basics are the same only the <strong>Pressed Output</strong> value is different to produce a slightly different rotation amount.</p>
<p>The next machine component deals with the two mallets. I won&#8217;t get into their setup but the idea is pretty much the same as with the buttons: take input (mouse movement), massage it until the produced output values are appropriate, add them to the mallet actor&#8217;s positions. The two mallets are two items in the <strong>Outputs</strong> list with the only difference between them is the referenced actors and the range of motion.</p>
<p>The final component is the ball which might seem weird since it&#8217;s controlled by physics not the user. The reason it&#8217;s included is the <strong>Allow Recording</strong> flag which will make sure that the ball&#8217;s motion gets recorded.<br />
The other reason one might want a rigid body here is that user input can be used to apply force or torque to the actor.</p>
<h5>The interactive table elements</h5>
<p>There are three classic interactive pieces on the table: the purple bumpers, the green drop targets and the two slingshots above the flippers.</p>
<p><a title="AirPinballBTS06.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS06.jpg" rel="lightbox"> <img id="thumb831" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS06.jpg" alt="" width="146" height="160" /> </a>The bumpers have rings moving up and down around the mushroom shaped base, but they are just non-colliding decorations, the ball is repelled by an <em>NxForceFieldRadial</em>.</p>
<p>The ball is sensed through the touch event of an invisible, non colliding cylinder around the base: when a KActor passes through the ring moving matinee is played and the force field is turned on for a split second.</p>
<p>Let&#8217;s move on to drop targets: they are animated movers with a Kismet subsequence for each of them:</p>
<p><a title="AirPinballBTS05.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS05.jpg" rel="lightbox"> <img id="thumb830" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS05.jpg" alt="" width="160" height="123" /></a>Animation starts when the interpactor takes damage caused by the ball. (The ball is our  <em>GVKactor</em> class which has speed dependent damage functionality.) The &#8220;Hit&#8221; sequence output is activated which will increase a counter outside this subsequence. That counter is linked to all four drop targets so it&#8217;s value reaching 4 indicates that all targets are down. In that case some points are given and the drop targets are reset.</p>
<p><a title="AirPinballBTS04.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS04.jpg" rel="lightbox"> <img id="thumb829" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS04.jpg" alt="" width="160" height="116" /> </a>Parallel to relaying the impulse to the output, we also start playing a matinee. It contains both the dropping and rising (reset) motions as one curve. However using an event track the matinee pauses itself after the target has dropped: that&#8217;s the &#8220;Target Down&#8221; output on the matinee node. (The <a href="http://en.wikipedia.org/wiki/NOP" target="_blank">NOP</a> nodes don&#8217;t do anything, they are just there for link management purposes.)</p>
<p>So after starting the matinee it pauses itself and it stays paused until the impulse arrives through the &#8220;Reset&#8221; sequence input. (Since the mover is almost fully covered by the floor there is no way the ball could trigger it so there are no safeguards against that scenario.)</p>
<p>Originally drop targets (and also the bumpers) were prefabs but the prefab system is broken in so many ways that it was simpler to just copy-paste my way through this.</p>
<p><a title="AirPinballBTS07.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS07.jpg" rel="lightbox"> <img id="thumb832" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS07.jpg" alt="" width="160" height="119" /> </a>The slingshots are also activated by damage but for some reason here it&#8217;s even less reliable than in the case of the drop targets, as the video clearly shows. However when it does work then a matinee rotates two invisible, colliding cylinders into that triangle shape so they smack the ball. (Otherwise they are pulled back into the body of the slingshot.)</p>
<p>The matinee also changes the &#8220;MorphAmount&#8221; scalar parameter in related material instances which takes care of the cosmetic changes of the mesh using the <em>World Position Offset</em> surface property. The vector displacement is stored as vertex colors: in Luxology modo a morph map is converted to an RGB vmap by a script. In the Unreal material the offset values are unpacked to the proper range then mesh scaling, orientation and mirroring is factored in. Since polygon normals also change in the morphed state, a second normal map is blended in.</p>
<h5>Special effects</h5>
<p>Pinball games usually feature a shiny steel ball but I wanted something a bit different: an almost totally diffuse material without any sharp reflections, like unpolished aluminium.<br />
First I tried turning on <a href="http://udn.epicgames.com/Three/LightEnvironments.html" target="_blank">light environment</a> on the ball but that wasn&#8217;t updated fast enough, the approximated lighting couldn&#8217;t catch up to the ever changing lighting conditions.</p>
<p>That left me with a choice: either place a lot of small, dynamic lights or use a dynamic cubemap reflection to somehow light the ball. The former option has several disadvantages: multiple dynamic lights affecting the ball could really hurt performance, lot of manual work recreating the static environment as dynamic lights and keeping them in sync with any subsequent changes on the map.</p>
<p>Using a reflection had it&#8217;s problems (no shadows, cubemap blurring is not straightforward) but it involved much less manual labor and the performance aspects were easier to fine tune so I went with this option.</p>
<p><a title="AirPinballBTS09.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS09.jpg" rel="lightbox"> <img id="thumb834" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS09.jpg" alt="" width="160" height="158" /> </a>The ball carries a <em>SceneCaptureCubeMapActor</em> which updates a 64&#215;64 (per cubemap side) texture target 20 times a second. I planned to extend the scene capture class so the framerate varies based on distance to camera but the overall performance was reasonable so I never implemented it.</p>
<p>The far plane is set in a way so it renders nothing beyond the immediate vicinity of the table. The rest is filled in by another cubemap, captured only once when the map starts, only showing the environment further away (the skydome and other decorations).</p>
<p><a title="AirPinballBTS10.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS10.jpg" rel="lightbox"> <img id="thumb835" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS10.jpg?6700043" alt="" width="160" height="158" /> </a>The first step of blurring the reflection is done through a post process referenced in the capture actor: depth of field is applied with focus distance and radius of 0. That blur is easy to fine tune and much more efficient than the brute force method possible in the material editor. Unfortunately it produces seams at the edges of the cube and that limits the usefulness of this technique. However with some tweaking it does provide a good enough base which can be processed further in a material where the cubemap is</p>
<p><a title="AirPinballBTS12.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS12.jpg" rel="lightbox"> <img id="thumb837" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS12.jpg" alt="" width="160" height="158" /> </a>blurred by rotating it on each axis and averaging the passes. A single scalar parameter defines the angle of rotation and that value is used to rotate in positive and negative directions, then do the same with half that angle, all that on the three axes which adds up to 12 passes. At 6 the ball looked &#8220;spotty&#8221; while 24 didn&#8217;t make that much of a difference at common view distances.</p>
<p>By the way, for the sampling of the cubemap the surface normal is used instead of the reflection vector. This makes the surroundings &#8220;stick&#8221; to the surface and not &#8220;slide&#8221; on it.</p>
<p><a title="AirPinballBTS13.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS13.jpg" rel="lightbox"> <img id="thumb838" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS13.jpg" alt="" width="160" height="158" /> </a>The final touch is a screen space noise which gets rid the remaining black lines. The strength of the noise (a scalar parameter) defines the amount the ball&#8217;s surface normals are jittered. The noise is animated and it&#8217;s strength decreases as the surface gets further away from the viewer which provides a more even blurring and a somewhat sanded look.</p>
<p>The material has other optional features like dynamic range adjustment for the cubemap, contrast tweaking, emissive map for heating the ball and so on. The most expensive combination costs 194 instructions but that&#8217;s fine considering that the ball is reasonably small on the screen.</p>
<p>The cubemap is reused in the dark ball as a true reflection. The slight blur and the subsequent black seams are there but not very apparent.</p>
<p style="text-align: center;"><a title="AirPinballBTS14.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS14.jpg" rel="lightbox"> <img id="thumb839" class="thumb aligncenter" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS14.jpg" alt="" width="110" height="160" /></a></p>
<p>However there was something missing from these captured cubemaps: specular highlights, i.e., the reflections of light actors. First I added lensflares but they had two problems: they made the scene too busy and the sprites were oriented toward the main camera even during the render to texture process.<br />
<a title="AirPinballBTS15.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS15.jpg" rel="lightbox"> <img id="thumb840" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS15.jpg" alt="" width="160" height="108" /> </a>Next I tried to place white spheres and exclude them from the main render pass so they only show up in reflections. As it turns out that&#8217;s currently not possible so I ended up with a less than elegant solution: one sided spherical caps (so they can&#8217;t be seen from above) with a lensflare texture.</p>
<p>The rails are also reflective but since they are thin and long they use four static cubemaps instead of one. The effect is somewhat subtle so to make it more apparent I replaced the rails with a cuboid:</p>
<p style="text-align: center;"><a title="AirPinballBTS16.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS16.jpg" rel="lightbox"> <img id="thumb841" class="thumb aligncenter" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS16.jpg" alt="" width="160" height="69" /></a></p>
<p>Each cubemap has a spherical falloff defined in the the material instance: radius, hardness and position can be set, the latter is supposed to be the coordinate where the cubemap was captured from. The variable radius allows uneven placement of the reflection areas so interesting places can be sampled at the ideal location.<br />
The cubemap resolution is pretty low to void texture aliasing on the thin bars of the rails.</p>
<p><a title="AirPinballBTS17.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS17.jpg" rel="lightbox"> <img id="thumb842" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS17.jpg" alt="" width="160" height="124" /></a>The final reflective element is the table: it uses a <em>SceneCaptureReflectActor</em> with a post process blurring the reflection a bit, in a similar way as before. However I wanted to give a hard, smooth, glass like look to the counter so there I sharpened the reflection with simple <a href="http://en.wikipedia.org/wiki/Posterization" target="_blank">posterization</a>.</p>
<p>I mentioned the counter <a href="http://www.zspline.net/blog/2011/11/18/gavit-dev-diary-18/" target="_blank">before</a> but here is a quick rundown of its features: it shows the input number in an arbitrary numeric system and to arbitrary digits*. The material can work either as a digital or an analog (rolling) counter, although here I only used the former mode.<br />
(* In practice since floating point precision problems make it impossible to display certain values above 999,999.)</p>
<p><a title="AirPinballBTS18.jpg" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS18.jpg" rel="lightbox"> <img id="thumb843" class="thumb alignright" src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS18.jpg" alt="" width="20" height="160" /></a>The first row of the display is split into three parts: the first and last two digits are just there for decorations, they never change while the middle 6 digits show the score.<br />
The second row follows a similar structure: the two characters at the ends are for simple animations and the center part is for the messages. Both of them have a non-numeric font so the input numbers show up as different shapes. The limited selection of letters explains the displayed words and expressions.</p>
<p>By the way, the border around the display (and all the other borders on the table) are using the <a href="http://www.zspline.net/blog/2012/03/18/nine-slice-material-function-in-udk/" target="_blank">9-slice material function</a>. The other decals are contained by a single texture atlas as several small distance field textures so experimenting with <a href="http://www.zspline.net/blog/2010/07/07/gviz-features-distance-field-based-decals/" target="_blank">different visual effects</a> was simple.</p>
<p>The ice ball supposed to leave decals behind when colliding but they&#8217;re barely visible in replay mode due to <a href="http://www.zspline.net/blog/2012/07/26/guided-rigid-bodies/" target="_blank">problems I discussed earlier</a> so here is a closeup:</p>
<div class="wp-caption aligncenter" style="width: 166px"><a title="AirPinballBTS19.gif" href="http://www.zspline.net/blog/wp-content/gallery/gavit/AirPinballBTS19.gif" rel="lightbox"><img id="thumb844" class="thumb  " src="http://www.zspline.net/blog/wp-content/gallery/gavit/thumbs/thumbs_AirPinballBTS19.gif" alt="" width="156" height="160" /></a>
<p class="wp-caption-text">Melting ice decal.<br />(Click to view animation)</p>
</div>
<p>The melting is also utilizing a distance field and the coverage parameter is animated by a time variable material instance.</p>
<p>And that’s about it. Please feel free to contact me if you have any questions!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zspline.net/blog/2012/08/08/mallet-pinball-behind-the-scenes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
