<?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>MQuandt.Blog &#187; XNA</title>
	<atom:link href="http://mquandt.com/blog/tag/xna/feed/" rel="self" type="application/rss+xml" />
	<link>http://mquandt.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 25 Jan 2012 14:21:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<cloud domain='mquandt.com' port='80' path='/blog/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>ScriptTD</title>
		<link>http://mquandt.com/blog/2011/10/scripttd/</link>
		<comments>http://mquandt.com/blog/2011/10/scripttd/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 13:41:46 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[channel 9]]></category>
		<category><![CDATA[channel9]]></category>
		<category><![CDATA[coding4fun]]></category>
		<category><![CDATA[msdn]]></category>
		<category><![CDATA[scripttd]]></category>
		<category><![CDATA[tower defense]]></category>
		<category><![CDATA[windows phone 7]]></category>
		<category><![CDATA[wp7]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/?p=148</guid>
		<description><![CDATA[I just realised I never posted about this. ScriptTD is a project I have been working on for the past year now, although we officially launched a couple of months ago, I&#8217;m still working on v2.0. The goal was to create a Tower Defense game engine for Windows Phone 7, allowing people with no coding &#8230; <a href="http://mquandt.com/blog/2011/10/scripttd/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I just realised I never posted about this. <img src='http://mquandt.com/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>ScriptTD is a project I have been working on for the past year now, although we officially launched a couple of months ago, I&#8217;m still working on v2.0. The goal was to create a Tower Defense game engine for Windows Phone 7, allowing people with no coding knowledge to change the data files and art/sounds to create their own Tower Defense game. This was an interesting challenge to work on, and I&#8217;m reasonably happy with the first result, however there is still plenty to add and refine. <img src='http://mquandt.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a href="http://scripttd.codeplex.com/"><img class="aligncenter" title="ScriptTD" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/HomeScreen_thumb%5B1%5D.png" alt="" width="300" height="180" /></a>You can get the source code for the project at <a href="http://scripttd.codeplex.com/" target="_blank">http://scripttd.codeplex.com/</a> and there is quite a bit of information about what each XML file does. I also wrote an article which is located at <a href="http://channel9.msdn.com/coding4fun/articles/ScriptTD-Tower-Defense-Made-Easy" target="_blank">http://channel9.msdn.com/coding4fun/articles/ScriptTD-Tower-Defense-Made-Easy</a> and covers how to extend the code (C#) to create a new weapon type.</p>
<p>For those interested in trying out the game on their Windows Phone 7 devices, you can get it from the following marketplace link:</p>
<p><a href="http://www.windowsphone.com/en-GB/apps/ee836335-27a7-e011-986b-78e7d1fa76f8" target="_blank">http://www.windowsphone.com/en-GB/apps/ee836335-27a7-e011-986b-78e7d1fa76f8</a></p>
<p>Be aware: it is quite challenging, but free for everyone. The game is compiled for WP7.0, so you don&#8217;t have to have Mango to run it.</p>
<p><img class="aligncenter" title="ScriptTD Screenshot 1" src="http://files.channel9.msdn.com/wlwimages/1932b237046e4743a4e79e6800c0220f/gamePlay_thumb%5B5%5D.png" alt="" width="300" height="180" /></p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2011/10/scripttd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>XNA Cross-Platform Editing in Real-time</title>
		<link>http://mquandt.com/blog/2011/04/xna-cross-platform-editing-in-real-time/</link>
		<comments>http://mquandt.com/blog/2011/04/xna-cross-platform-editing-in-real-time/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 05:00:52 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[sample code]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[xbox 360]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/?p=129</guid>
		<description><![CDATA[One of the cool new features appearing in a lot of modern engines is the ability to work in an editor on the PC and have the level changes replicate on a running console build of the game in real-time. For commercial games this often happens over the high speed USB connection, however due to &#8230; <a href="http://mquandt.com/blog/2011/04/xna-cross-platform-editing-in-real-time/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>One of the cool new features appearing in a lot of modern engines is the ability to work in an editor on the PC and have the level changes replicate on a running console build of the game in real-time. For commercial games this often happens over the high speed USB connection, however due to the cross platform support in XNA, we can replicate this [in single player games/modes] using a System-Link connection and the XNA networking libraries.</p>
<p>The first step is deciding which side will create the session and which side will join. Considering we only have the option of working with the Xbox 360, and you might not want to include any debug views or information in your Xbox code, the option I chose is to have the Xbox create the session. The code is compatible on both platforms so if you&#8217;re willing to add some system to find and join an active session, you can easily change this to create the session on the PC. For the purposes of this article the session will only contain two &#8220;Players&#8221; and the Xbox will create whilst the PC side joins.</p>
<h2><span id="more-129"></span>Creating</h2>
<p>We start by creating a session, in XNA you can do this with the <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.net.networksession.create.aspx" target="_blank">NetworkSession.Create()</a> command, which creates a <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.net.networksession.aspx" target="_blank">NetworkSession</a> object that maintains the session. Then specify session.AllowJoinInProgress to be true, this lets you create the session and at any time join or rejoin from the PC side.</p>
<pre class="brush: csharp;">_session = NetworkSession.Create(NetworkSessionType.SystemLink, 1, 2);
_session.AllowJoinInProgress = true;</pre>
<p>Another key thing to note here is that you will want to specify the network session type as SystemLink, this lets you sign in with your Creators Club gamer tag on the Xbox, and use a local player on the PC side &#8211; no extra accounts!<br />
We then specify a maximum of one local gamer on the Xbox side, and a total of two gamers in the session. (Change as needed)<br />
Finally we handle the session.GamerJoined event and in the handler we start the game if the current session state is set to Lobby.</p>
<h2>Receiving</h2>
<p>At this time you might want to also create a PacketReader and PacketWriter, as we will be using these to do our communication. These can be created at any time, and are not tied to a session, so it is a good idea to create them once and re-use over multiple sessions/games.</p>
<p>How you want to receive the data is up to you, however I chose to allow the Xbox game to register some callbacks for named commands. That way the PC side can specify the name of the command and send data along, which can be passed through as a byte array. This is rather simple to setup, you simply maintain a Dictionary&lt;string, Action&lt;byte[]&gt;&gt; that contains all of the callback delegates and names. Then when a packet comes in it will have the name of the callback as well as the byte[] data, which lets you gets the callback from the Dictionary and call it, passing in the data as is.</p>
<p>On the PC side you simply send the callback name, length of the byte array and the bytes themselves, ready for the Xbox to accept and use.</p>
<p>I further split this into &#8220;Commands&#8221; and &#8220;Data&#8221;, to provide a clear separation of things like console commands, and raw data, but both use the same system of a Action&lt;byte[]&gt; delegate callback.</p>
<h2>Joining</h2>
<p>When joining, the PC needs to do two things:</p>
<ol>
<li>Search for sessions</li>
<li>Join a chosen session</li>
</ol>
<p>The <a href="http://msdn.microsoft.com/en-us/library/bb975501.aspx" target="_blank">NetworkSession.Find()</a> method provides a list of available sessions currently running over SystemLink, which is usually going to be just one, however if you&#8217;re working in a larger team with multiple systems on the same network, you might want to list them and display the host gamertag, so that you can choose the right one.</p>
<p>Once you have chosen the network session, you pass that to <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.net.networksession.join.aspx" target="_blank">NetworkSession.Join()</a> which creates a NetworkSession object that you can use just like you do on the server &#8211; except this time you don&#8217;t worry about starting the game.</p>
<h2>Updating</h2>
<p>Once the session has been created and is up and running, on both platforms you need to call session.Update() in your update loop. This handles the networking side of things and gets/sends the packets as needed.</p>
<p>Once you have updated, you can make use of the PacketReader and PacketWriter objects to receive and send packets respectively. To receive the data, you need to first check if there is data available by checking the session.LocalGamers[0].IsDataAvailable flag. If there is data available, you can call session.LocalGamers[0].ReceiveData() passing in the PacketReader which you can then use to parse the packet and call the appropriate callback.</p>
<p>If you have data you want to send, you just need to call session.LocalGamers[0].SendData(), and pass in the PacketWriter with the data you want to send.</p>
<p>In the background XNA handles the network magic, so you just have to worry about handling the data on either end.</p>
<h2>Code</h2>
<p>I didn&#8217;t have time to put up a complete code sample for this article, however I hope you understand the general technique. Code for something like this really needs to be tailored to your purpose. If you are just writing a debug console or tweak system, you can just use the command system mentioned below. However if you want to write a sync system for your editor, with camera sync and everything else, you will probably want to change how you send and receive data to optimise for what you are sending.</p>
<h3>Create</h3>
<pre class="brush:csharp;">_session = NetworkSession.Create(NetworkSessionType.SystemLink, 1, 2);
_session.AllowHostMigration = false;
_session.AllowJoinInProgress = true;
_session.GamerJoined += (s, e) =&gt;
{
    if (_session.SessionState == NetworkSessionState.Lobby)
        _session.StartGame();
};
_session.GamerLeft += (s, e) =&gt; _session.EndGame();</pre>
<h3>Find</h3>
<pre class="brush:csharp;">AvailableNetworkSessionCollection sessions = NetworkSession.Find(NetworkSessionType.SystemLink, 1, null);</pre>
<h3>Join</h3>
<p>(&#8216;session&#8217; is an AvailableNetworkSession taken from the collection in Find)</p>
<pre class="brush:csharp;">_session = NetworkSession.Join(session);</pre>
<h3>Update</h3>
<pre class="brush:csharp;">if (_session != null)
{
    _session.Update();
    if (_writer.Length &gt; 0)
        _session.LocalGamers[0].SendData(_writer, SendDataOptions.None);
    while (_session != null &amp;&amp; _session.LocalGamers[0].IsDataAvailable)
    {
        NetworkGamer sender;
        int numBytes = _session.LocalGamers[0].ReceiveData(_reader, out sender);
        if (numBytes &gt; 0 &amp;&amp; !sender.IsLocal)
        {
            string methodName = _reader.ReadString();
            int numBytes = _reader.ReadInt32();
            var data = _reader.ReadBytes(numBytes);
            Action method;
            if (!string.IsNullOrEmpty(methodName) &amp;&amp; _commands.TryGetValue(methodName, out method))
                method(data);
        }
    }
}</pre>
<h3>Sending</h3>
<pre class="brush:csharp;">public void SendCommand(string methodName, byte[] data)
{
    _writer.Write(methodName.ToLower());
    if (data != null)
    {
        _writer.Write(data.Length);
        _writer.Write(data);
    }
    else
    {
        _writer.Write(0);
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2011/04/xna-cross-platform-editing-in-real-time/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>XNA Tip #1</title>
		<link>http://mquandt.com/blog/2011/01/xna-tip-1/</link>
		<comments>http://mquandt.com/blog/2011/01/xna-tip-1/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 14:15:13 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[alpha blending]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2011/01/xna-tip-1/</guid>
		<description><![CDATA[This is the first in what will probably be a random series of small posts about tips and tricks, and other notes about xna. When implementing the light pre-pass algorithm in XNA 4.0, I found that the alpha channel was messing around with my intermediate render targets. To resolve this, you need to create a &#8230; <a href="http://mquandt.com/blog/2011/01/xna-tip-1/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><i>This is the first in what will probably be a random series of small posts about tips and tricks, and other notes about xna.</i></p>
<p>When implementing the light pre-pass algorithm in XNA 4.0, I found that the alpha channel was messing around with my intermediate render targets.    <br />To resolve this, you need to create a custom blend state object (cache it) with the colour and alpha destination and blend states set to BlendState.One.</p>
<p>This should prevent any modulation based on the alpha value in a texture when sampling.</p>
<p>*<strong>Edit</strong>* Small code sample:</p>
<pre class="brush: csharp;">var _alphaBlend = new BlendState()
            {
                AlphaDestinationBlend = Blend.One,
                AlphaSourceBlend = Blend.One,
                ColorDestinationBlend = Blend.One,
                ColorSourceBlend = Blend.One
            };</pre>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2011/01/xna-tip-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TechEd 2010 Academic Day Slides</title>
		<link>http://mquandt.com/blog/2010/08/teched-2010-academic-day-slides/</link>
		<comments>http://mquandt.com/blog/2010/08/teched-2010-academic-day-slides/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 00:06:55 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Students]]></category>
		<category><![CDATA[TechEd]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[academic day]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[slides]]></category>
		<category><![CDATA[teched 2010]]></category>
		<category><![CDATA[teched australia]]></category>
		<category><![CDATA[windows phone 7]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2010/08/teched-2010-academic-day-slides/</guid>
		<description><![CDATA[As promised, here are my slides for my presentation on Windows Phone 7 during Academic Day at TechEd 2010.]]></description>
			<content:encoded><![CDATA[<p>As promised, here are my slides for my presentation on Windows Phone 7 during Academic Day at TechEd 2010.</p>
<p><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-670fd4ae41402e8a.office.live.com/embedicon.aspx/MSP/TechEd2010^_WP7^_Academic.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/08/teched-2010-academic-day-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reconstructing Position from Depth for Fullscreen Quads</title>
		<link>http://mquandt.com/blog/2010/06/reconstructing-position-from-depth-for-fullscreen-quads/</link>
		<comments>http://mquandt.com/blog/2010/06/reconstructing-position-from-depth-for-fullscreen-quads/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 02:56:35 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[depth]]></category>
		<category><![CDATA[frustum ray]]></category>
		<category><![CDATA[techniques]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/?p=108</guid>
		<description><![CDATA[Recently I found an issue with an older article of mine that covered this topic, so I pulled it down until I could find the time to understand and fix the issue. After a bit of work I have fixed it and present this refresh. The key to deferred rendering and other techniques is the &#8230; <a href="http://mquandt.com/blog/2010/06/reconstructing-position-from-depth-for-fullscreen-quads/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently I found an issue with an older article of mine that covered this topic, so I pulled it down until I could find the time to understand and fix the issue. After a bit of work I have fixed it and present this refresh.</p>
<p>The key to deferred rendering and other techniques is the ability to use a depth map to store world position. As we know a depth map consists of floating point values (optimally) and so normally we would use those values with our Clip Space coordinates and the Inverse of the ViewProjection matrix to get the position in World Space.</p>
<p>However there is another way to do this, and the big benefit is that it does not require a matrix multiplication to do so.</p>
<p>Presented by Crytek during a presentation on Atmospheric Scattering, this method uses just a Multiply + Add to get the position in World Space from our depth value at that point. To do this we need to get the far view frustum corners, in View Space, and pass them to the shader.</p>
<p>  <span id="more-108"></span><br />
<h3>Getting the Corners</h3>
<p>This is easily done in XNA through the BoundingFrustum.GetCorners() method. Note that we only need the far corners, so we can take the last 4 in the 8 element array, and we also need these corners in View space, so be sure to transform them by the View matrix before you pass them through.</p>
<pre class="brush: csharp;">private void getFrustumCorners(out Vector3[] corners)
{
    corners = new Vector3[4];

    Vector3[] temp = CurrentCamera.Frustum.GetCorners();
    for (int i = 0; i &lt; 4; i++)
    {
        corners[i] = Vector3.Transform(temp[i + 4], CurrentCamera.View);
    }
}</pre>
<p>Since we are in the CPU/XNA code, be sure to also pass the depth of the far clip plane, and the camera’s World matrix. (Simply invert the View matrix if you do not already have a World matrix)</p>
<h3>Writing out Depth</h3>
<p>Now for some shader code! First in the depth shader, you need to change how you write out the depth value, instead we take the Linear View Space depth, which means that we need to get the Z value from Position * World * View rather than Position * World * View * Projection.</p>
<pre class="brush: cpp;">float4x4 wv = mul( World, View );
float4 posVS = mul( pos, wv );

output.Position = mul( posVS, Projection );
output.Depth = posVS.z;</pre>
<p>Then in the pixel shader, take this depth value, negate it and divide it by the Far Clipping plane.</p>
<pre class="brush: cpp;">output.Depth = 1.0f - ( -depth / FarClip );</pre>
<p>Now when you want to reconstruct this, we need to find the correct frustum corner inside the vertex shader. (Note: This code only applies if you are rendering a fullscreen quad)</p>
<h3>Preparing and Choosing the Right Corner</h3>
<p>The best way to do this is to pass along the array index as a 3rd value with your texture coordinates. If you do not want to modify the vertex type, you can also apply some maths to determine the right index.</p>
<p>For brevity I will assume that the index is provided with the texture coordinates.</p>
<p>Take that ray and multiply it by the camera World matrix, to move the ray into World space, then pass it to the pixel shader.</p>
<pre class="brush: cpp;">output.FrustRay = mul( FSQ_GetFrustumRay( tcri.z ), CamWorld );</pre>
<h3>Getting the Position</h3>
<p>Now that you have the ray, simply sample the depth texture for the depth value, and multiply it by the ray. Then take that and add it to the camera position to get the point in world space. (Rather than just a direction)</p>
<pre class="brush: cpp;">float depth = 1.0f - tex2D( depthSampler, tc ).x;
float3 pos = CamPosition + depth * frustRay;</pre>
<p>Now you have your position!</p>
<p>I will include the technique to do the same thing with arbitrary world geometry when I write an article on Point Lights or Spotlights. At the moment I am working on implementing shadows, and probably won’t touch those topics until I solve some pressing issues.</p>
<h3>Final Notes</h3>
<p>Here is a code sample for passing the index as a part of the texture coordinate value.</p>
<p>&#160;</p>
<pre class="brush: csharp;">private struct VertexPositionTexCoordRayIndex
{
    private Vector3 position;
    public Vector3 Position
    {
        get { return position; }
        set { position = value; }
    }

    private Vector3 texCoordRayIndex;
    public Vector3 TexCoordRayIndex
    {
        get { return texCoordRayIndex; }
        set { texCoordRayIndex = value; }
    }

    public static int SizeInBytes { get { return sizeof(float) * 6; } }

    public static readonly VertexElement[] VertexElements =
        new VertexElement[] {
            new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0),
            new VertexElement(0, sizeof(float)*3, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.TextureCoordinate, 0)
        };

    public VertexPositionTexCoordRayIndex(Vector3 position, Vector3 texcoordRayindex)
    {
        this.position = position;
        this.texCoordRayIndex = texcoordRayindex;
    }
}</pre>
<pre class="brush: csharp;">VertexPositionTexCoordRayIndex[] verts = new VertexPositionTexCoordRayIndex[4];
verts[0] = new VertexPositionTexCoordRayIndex(new Vector3(-1, 1, 1), new Vector3(0, 0, 0));
verts[1] = new VertexPositionTexCoordRayIndex(new Vector3(1, 1, 1), new Vector3(1, 0, 1));
verts[2] = new VertexPositionTexCoordRayIndex(new Vector3(-1, -1, 1), new Vector3(0, 1, 3));
verts[3] = new VertexPositionTexCoordRayIndex(new Vector3(1, -1, 1), new Vector3(1, 1, 2));</pre>
<p>&#160;</p>
<p>Remember that XNA provides the corners in a different order to just 1,2,3,4, so we can explicitly pass the correct index for the vertex we are working with here, and it will be chosen correctly in the shader.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/06/reconstructing-position-from-depth-for-fullscreen-quads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Status June 2010</title>
		<link>http://mquandt.com/blog/2010/06/status-june-2010/</link>
		<comments>http://mquandt.com/blog/2010/06/status-june-2010/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 22:52:20 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[status]]></category>
		<category><![CDATA[techniques]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2010/06/status-june-2010/</guid>
		<description><![CDATA[Hi all, not dead. Apologies for the lack of updates, I am in the process of finishing an internship required for my university course, and it is a challenge to find good time to tackle some XNA issues and write posts. I am currently working on Directional light shadows for my engine, I have cascaded &#8230; <a href="http://mquandt.com/blog/2010/06/status-june-2010/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hi all, not dead.</p>
<p>Apologies for the lack of updates, I am in the process of finishing an internship required for my university course, and it is a challenge to find good time to tackle some XNA issues and write posts.</p>
<p>I am currently working on Directional light shadows for my engine, I have cascaded shadow maps implemented, and now I am just tackling some issues I have encountered, which is taking a while – I also need to find a good filtering method.</p>
<p>If I get bored of trying to fix those annoying issues, I will probably jump into re-implementing point lights, and spotlights, and write something about those.</p>
<p>Some housekeeping notes:</p>
<p>I encountered a pretty big issue with the “Reconstructing position from depth” technique, and I have taken that article down from the blog for now. At the moment my own code uses the old “Multiply my the Inverse of the View Projection matrix”, and probably will continue to until I have time to solve that problem.</p>
<p>I have also updated this blog to WordPress 3.0, so let me know if you encounter any issues.</p>
<p>Back to work.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/06/status-june-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[LPP] Ambient Lights</title>
		<link>http://mquandt.com/blog/2010/04/lpp-ambient-lights/</link>
		<comments>http://mquandt.com/blog/2010/04/lpp-ambient-lights/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 01:32:01 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[ambient lights]]></category>
		<category><![CDATA[light pre pass]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2010/04/lpp-ambient-lights/</guid>
		<description><![CDATA[Ambient lights are used in modern games to fake the indirect illumination that exists in the real world. By adding a generally very weak light to the scene, we can avoid the 100% black shadows that really should not exist, all at a very low cost compared to proper indirect illumination or baked ambient light &#8230; <a href="http://mquandt.com/blog/2010/04/lpp-ambient-lights/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ambient lights are used in modern games to fake the indirect illumination that exists in the real world. By adding a generally very weak light to the scene, we can avoid the 100% black shadows that really should not exist, all at a very low cost compared to proper indirect illumination or baked ambient light maps.</p>
<p>I have found that the simplest way to integrate these ambient lights into the Light Pre Pass system, and allow for other elements to change the lights throughout the game is to create a new light type that fits into the normal lighting model.</p>
<p>This is probably the simplest type out there, you just create a full screen quad and render it using a shader that writes the colour information directly to the light buffer. All we have to pass to the shader is the colour and intensity. (you could always pre-compute this, but beware of the byte-&gt;int32 auto promotion C# does)</p>
<p> <span id="more-101"></span>
<p>Here is the C# class:</p>
<pre class="brush: csharp;">public class AmbientLight
{
    public Color Color { get; set; }

    public bool Enabled { get; set; }

    private int intensity = 100;

    public int Intensity
    {
        get { return intensity; }
        set { intensity = value; }
    }

    private Effect shader;

    public AmbientLight(Color col, int intensity)
    {
        this.Color = col;
        this.Enabled = true;
        this.intensity = intensity;
    }

    public void LoadContent(ContentManager content)
    {
        shader = content.Load&lt;Effect&gt;(@&quot;Effects\Lights\l_ambient&quot;);
    }

    public void DrawLight(Renderer caller)
    {
        if (!Enabled)
            return;

        shader.Begin();
        shader.Parameters.TrySet(&quot;LightColor&quot;, Color.ToVector3());
        shader.Parameters.TrySet(&quot;Intensity&quot;, intensity);

        shader.CurrentTechnique.Passes[0].Begin();
        caller.FSQ.Draw();
        shader.CurrentTechnique.Passes[0].End();

        shader.End();
    }
}</pre>
<p>and the shader:</p>
<pre class="brush: cpp;">float3 LightColor;
float Intensity;

float4 vs_main(in float4 pos : POSITION) : POSITION
{
    return pos;
}

float4 ps_main() : COLOR
{
    return float4(LightColor * (Intensity / 100), 0);
}

technique AmbientLight
{
    pass p0
    {
        VertexShader = compile vs_2_0 vs_main();
        PixelShader = compile ps_2_0 ps_main();
    }
}</pre>
<p>I am in the middle of a crunch at work, and so future posts will be slow until it is all over. (That is why this one took a while to come out) I have not had the chance to do much work on my own XNA code, let alone tutorials. <img src='http://mquandt.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Thanks for your patience, I cannot wait to get back to XNA. (and I cannot wait for XNA 4.0 with HiDef)</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/04/lpp-ambient-lights/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>XNA 4.0 &#8211; Reach/HiDef &amp; My Article(s)</title>
		<link>http://mquandt.com/blog/2010/03/xna-4-0-reachhidef-my-articles/</link>
		<comments>http://mquandt.com/blog/2010/03/xna-4-0-reachhidef-my-articles/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 12:34:44 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Xbox 360]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[xna 4.0]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2010/03/xna-4-0-reachhidef-my-articles/</guid>
		<description><![CDATA[Shawn Hargreaves just posted this: http://blogs.msdn.com/shawnhar/archive/2010/03/12/reach-vs-hidef.aspx I suggest you have a read through it if you are interested in the kinds of things I post on this blog, especially the Light Pre Pass technique. One of the key parts of Shawn’s article are the changes that will be made to Render Targets, and the bucketing &#8230; <a href="http://mquandt.com/blog/2010/03/xna-4-0-reachhidef-my-articles/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Shawn Hargreaves just posted this: <a href="http://blogs.msdn.com/shawnhar/archive/2010/03/12/reach-vs-hidef.aspx">http://blogs.msdn.com/shawnhar/archive/2010/03/12/reach-vs-hidef.aspx</a></p>
<p>I suggest you have a read through it if you are interested in the kinds of things I post on this blog, especially the Light Pre Pass technique.</p>
<p>One of the key parts of Shawn’s article are the changes that will be made to Render Targets, and the bucketing of the RenderTarget/Texture formats into the Reach and HiDef profiles.</p>
<p>It would be safe to say that future articles here will require the HiDef feature set. I make use of some of the Render Targets that do not exist in Reach, and while there may be a way to use a Reach Render Target, for the purposes of conveying the technique, I will not be adding extra code to support it. I may however note where alternatives can be used, and hint or mention how to use them.</p>
<p>I know I have previously used BGRA formats in my sample, and in future this will become RGBA, no big deal. I won’t change the 3.1 sample for now, but if I need to change other things to upgrade it to 4.0, then that will be “fixed”.</p>
<p>This shouldn’t be much of a problem, if you are going to be using the articles I plan to write, then you’ll have a computer that works with HiDef, or an XBOX.</p>
<p>As a side note, I no longer have a valid Creators Club subscription, so I have not tested the recent Light Pre-Pass article on the XBOX. If anyone has any issues let me know and I will try and look into it. I plan to get a premium subscription soon and test future articles on the XBOX.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/03/xna-4-0-reachhidef-my-articles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Light Pre-Pass Round 2</title>
		<link>http://mquandt.com/blog/2010/03/light-pre-pass-round-2/</link>
		<comments>http://mquandt.com/blog/2010/03/light-pre-pass-round-2/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 12:20:58 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2010/03/light-pre-pass-round-2/</guid>
		<description><![CDATA[Those who have been following this blog know that I wrote an article about implementing a Light Pre-Pass renderer last year. Since then I have made numerous improvements and fixes as I have tried the system over different PC configurations. This time around I will be including those changes into the implementation, and also releasing &#8230; <a href="http://mquandt.com/blog/2010/03/light-pre-pass-round-2/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Those who have been following this blog know that I wrote an article about implementing a Light Pre-Pass renderer last year. Since then I have made numerous improvements and fixes as I have tried the system over different PC configurations.</p>
<p>This time around I will be including those changes into the implementation, and also releasing sample code for educational use. If you feel you have learned enough from the previous article, then feel free to skip this. For those new to the topic, please use this article instead of the older one.</p>
<p> <span id="more-96"></span>
</p>
<p>This article will focus on the theory, and will attempt to be as API neutral as possible. I will be making some references to XNA SurfaceFormats as this article is aimed more towards XNA developers, but for reference here are the matching Direct3D formats:</p>
<table border="0" cellspacing="0" cellpadding="2" width="400">
<tbody>
<tr>
<td valign="top" width="200">SurfaceFormat.Color</td>
<td valign="top" width="200">A8R8G8B8</td>
</tr>
<tr>
<td valign="top" width="200">SurfaceFormat.Bgra1010102</td>
<td valign="top" width="200">A2R10G10B10</td>
</tr>
<tr>
<td valign="top" width="200">SurfaceFormat.Single</td>
<td valign="top" width="200">R32F</td>
</tr>
<tr>
<td valign="top" width="200">SurfaceFormat.HalfSingle</td>
<td valign="top" width="200">R16F</td>
</tr>
</tbody>
</table>
<p>See the sample for an XNA implementation.</p>
<h3>General Overview</h3>
<p>For a number of years now, the concept of Deferred Rendering has been a hot topic in games. The ability to have a large number of lights, with a low cost per light is an attractive option. However deferred rendering suffers from the inability to render transparent objects at the same time as opaque objects. A few “solutions” have appeared in recent years that approach deferred rendering in a different way to allow for some level of transparency, however none have solved the problem completely, and all require extra work in some form.</p>
<p>There are a few different types of Deferred Rendering, however the two key forms are Deferred Shading, and Deferred Lighting. These differ in exactly which stage of rendering is deferred.</p>
<p>Deferred Shading defers the entire shading and lighting process, handling geometry rendering once, and then using an Uber Shader to light and shade the objects. One of the key negatives here is that you are limited in your material selection – although there are a few alternative solutions that can help here. Some other negatives include the “Fat Framebuffer” that this technique requires. As Deferred Shading relies on Multiple Render Targets (MRTs) to render the geometry once and store all important details, we are hit with both a memory cost, as well as limitations in DirectX9 which prevent us from applying multi-sampling (AA) to MRTs.    <br />Negatives aside, Deferred Shading allows us to get the benefit of many lights, and still only render the scene once, which can be good for performance in scenes where the triangle count is high, and you do not need a diverse set of materials.</p>
<p>Deferred Lighting on the other hand defers only the lighting step, and requires an extra pass over the geometry to apply the details. The benefit here is that you can apply a unique material to each of your objects, whilst retaining the ability to have many lights. This technique also makes use of MRTs, however it only uses 2 render targets during the Depth + Normals stage, so if you can afford another pass over geometry, you can split those into two passes and gain the ability to run code on older hardware that does not support MRTs.</p>
<h3>Deferred Lighting Overview</h3>
<p>Deferred Lighting consists of 3 key stages:<img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="LPP Pipeline" border="0" alt="LPP Pipeline" src="http://mquandt.com/blog/wp-content/uploads/2010/03/lpp_pipeline_thumb.png" width="481" height="200" /></p>
<ol>
<li>Render the Depth and World Space Normals of the Geometry </li>
<li>Render the lighting term using the Depth + Normals generated previously </li>
<li>Render the Geometry again, this time with unique materials, making use of the lighting term above. </li>
</ol>
<p>Remember that if you retain your hardware depth stencil, you get a performance increase from the early-z tests that modern hardware provides.</p>
<p>One key optimisation that is used in Deferred Shading is to render the lights using bounding volumes, ie a Sphere for a Point Light. This prevents overdraw for areas that are not lit.</p>
<p>I will be following the steps mentioned above, with the aforementioned optimisation, for the rest of this article.</p>
<h3>Stage 1: Depth + Normals</h3>
<p>The key requirement for any lighting calculation is fragment position, and normal. This means that if we want to determine the contribution a light makes to a particular pixel, we need to know where in world space that pixel is, and the normal at that pixel.</p>
<p>As we are deferring the lighting calculations, we need to store this information in a format we can use later. Now to store a position, we could go the naive route and store one component per channel, i.e. R=X, G=Y and B=Z, however this only gives us 8 bits of precision for each component, and each component is a full 32bit floating point number.</p>
<p>Instead we store the depth of the pixel and later reconstruct the position using the depth, and information from the camera.</p>
<p>Unfortunately, as we are working with XNA, we are restricted to D3D9 technology, and even then cannot use the FOURCC driver hacks that modern GPUs provide. This means that we have to write out the depth buffer to a separate render target instead of making use of the depth buffer the graphics card always creates.</p>
<p>So begin by preparing two render targets, the same size as the backbuffer you are going to draw to in the end. Make the depth target use SurfaceFormat.Single, and the Normals target use SurfaceFormat.Bgra1010102.</p>
<p>Of course when implementing this in a game for Windows, you should always verify that the SurfaceFormats are supported, and in the case of the depth buffer you can fall back to HalfSingle if Single is not supported. The Normal buffer can fall back to SurfaceFormat.Color if the 1010102 format is not supported, and you can always take the depth buffer back to Color if you absolutely need to, however note that you will need to add in extra packing code to make use of the full buffer then.</p>
<p>After that, we need to render the visible scene using a special shader that writes the Depth and Normal information to our render targets.</p>
<p>There are two key things to note here:</p>
<ol>
<li>If you decide to subtract the true depth from 1.0f, ensure you reverse that later on. </li>
<li>You need to remap the Normal from [-1, 1] to [0, 1] so that it stores correctly in the render target </li>
</ol>
<p>To accomplish #2, you simply need to use the following equation:</p>
<pre>output.Normal = (( input.Normal + 1.0f ) / 2.0f )</pre>
<p>Later on we will return this value to the [-1, 1] range by using the reverse of the above equation.</p>
<h3>Stage 2: Lighting</h3>
<p>Now that we have the Depth and Normal for each pixel, we can calculate the lighting from every light that touches each pixel. If you plan to include some form of shadow mapping, this is where you would handle rendering the shadow maps, and make use of them when lighting the object.</p>
<p>You can approach lighting in two ways:</p>
<ol>
<li>Render every type of light as a fullscreen quad. </li>
<li>Render each light as an appropriate light volume [<a href="http://developer.nvidia.com/object/6800_leagues_deferred_shading.html">Hargreaves04</a>] </li>
</ol>
<p>We will focus on #2, which allows us to reduce pixel draw and improve performance dramatically.</p>
<p align="left">Although I will only be implementing a Directional Light in the sample, you can use the following primitives to render each type of light:</p>
<table border="0" cellspacing="0" cellpadding="2" width="400">
<tbody>
<tr>
<td valign="top" width="200">Ambient Light</td>
<td valign="top" width="200">Fullscreen Quad</td>
</tr>
<tr>
<td valign="top" width="200">Directional Light</td>
<td valign="top" width="200">Fullscreen Quad</td>
</tr>
<tr>
<td valign="top" width="200">Point Light</td>
<td valign="top" width="200">Sphere</td>
</tr>
<tr>
<td valign="top" width="200">Spot Light</td>
<td valign="top" width="200">Cone or Box</td>
</tr>
</tbody>
</table>
<p align="left">As you can see, the two light types that do not have a position or volume, are still rendered as fullscreen quads, whilst the other two use approximations of their light volumes to prevent overdraw</p>
<p>In the case of the ambient light, you may choose to implement this as an extra term in your material shader instead, however I choose to implement it as a light object so that I may alter/combine/disable at will.</p>
<p>Here you need to set a new render target, which will hold our Light Buffer. Once that is done, render each visible light volume using a special shader based on the light type.</p>
<p>This is where the magic happens. Inside these special shaders, we reconstruct the world space position of the pixel from the depth value, and using the position and the normal, calculate the lighting term as you would during forward rendering.</p>
<p>There are a couple of ways you can reconstruct the position from the depth value. The most common and obvious way would be to use the X/Y value of the pixel in Post-Projection Space, combined with the depth as Z, and multiply that by the inverse of the ViewProjection matrix. This will give you the position of the pixel in World space, which you can use.</p>
<p>There are other techniques, some which end up cheaper than the matrix multiply mentioned above. For a full overview of most (if not all) of the techniques available for you to use, simply read through these two articles:</p>
<p><a href="http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/">http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/</a> </p>
<p><a href="http://mynameismjp.wordpress.com/2009/05/05/reconstructing-position-from-depth-continued/">http://mynameismjp.wordpress.com/2009/05/05/reconstructing-position-from-depth-continued/</a></p>
<p>In the sample I chose to use the Frustum Ray method, which is a cheaper way to get the position, but requires you to do some processing on the CPU to get the rays ready. In the sample this is calculated every time the camera parameters are set, however realistically you only need to do this any time your bounding frustum changes or moves.</p>
<p>Our light buffer, which is a SurfaceFormat.Color, can take four 8bit integers. The original, and (to my knowledge) recommended layout (from Wolfgang Engel) is to store the <strong>N</strong>.<strong>L</strong> * Color terms in the RGB channels, and the specular term in the Alpha channel. This leaves you with the following layout:</p>
<table border="0" cellspacing="0" cellpadding="2" width="231">
<tbody>
<tr>
<td valign="top" width="31">A</td>
<td valign="top" width="198"><strong>R</strong>.<strong>V</strong> (or <strong>N</strong>.<strong>H</strong> for Blinn-Phong)</td>
</tr>
<tr>
<td valign="top" width="31">R</td>
<td valign="top" width="198"><strong>N</strong>.<strong>L</strong> * Red</td>
</tr>
<tr>
<td valign="top" width="31">G</td>
<td valign="top" width="198"><strong>N</strong>.<strong>L</strong> * Green</td>
</tr>
<tr>
<td valign="top" width="31">B</td>
<td valign="top" width="198"><strong>N</strong>.<strong>L</strong> * Blue</td>
</tr>
</tbody>
</table>
<p>At this point you can also take into account the shadow map for each light, and use that to choose whether this light should illuminate or do nothing to the pixel. Now when rendering the lights, we need to set a couple of Render States to ensure things go smoothly.</p>
<p>First of all, we need to ensure that the depth buffer is disabled. This has to happen because we may need to render lights behind/inside other lights, and if the depth buffer is enabled, the graphics card will reject the contribution from some of those lights via the Early-Z feature.</p>
<p>Since we are using geometry to render the lighting, we need to handle the case when the camera is inside the light volume. Here we change the CullMode render state so that it either culls interior faces when the camera is outside the object, or it culls exterior faces when the camera is inside the object. Normally this would be set to Counter-Clockwise, which remains our default when outside the object.</p>
<p>Simply detect when the camera is inside the object and set the CullMode to Clockwise to handle the other case.</p>
<p>Another issue you may notice with this is when the camera is entering a light volume, especially the point light sphere. At this point, part of the screen is inside the object, and the rest is outside, so we need to set CullMode to None here to handle both cases without creating visual glitches.</p>
<p>Finally we need to enable alpha blending and set the blend mode to Add, this allows multiple lights that illuminate the same pixel to combine correctly (see <a href="http://en.wikipedia.org/wiki/Phong_shading">Phong Shading</a>).</p>
<p>Do not forget to re-enable the Depth Buffer and revert the CullMode to Counter-Clockwise before continuing, otherwise you might encounter hard to debug issues when rendering the materials.</p>
<h3>Stage 3: Materials</h3>
<p>Once the light buffer has been filled with all of the visible lights, you can move on to rendering the final image using each object’s material. First you need to make sure that all of your Render States are back to normal after the changes made during the Lighting stage.</p>
<p>To render the materials, you need to re-render every object that was drawn during the Depth + Normals stage, however this time around each object can use its own shader to draw itself, and can take the Light buffer as a texture, which can then be used as the lighting term when shading.</p>
<p>There are numerous effects that can be used to shade an object. In the sample I will only provide a Blinn-Phong shader, however as long as you understand the basic concepts of lighting in modern graphics, you can adapt the lighting values into any other technique that can use them.</p>
<p>This is where I find the big benefits of this technique appear. By allowing the object to choose its own shader/material, you can regain the diverse range of materials that forward rendering allows, providing your artists with plenty of possibilities. Not only that, but you do not have to manage a monster Uber Shader, balancing it against potentially restrictive instruction/texture count limits. (Depending on your Shader Model)</p>
<p>The sample will show how to implement a Blinn-Phong lighting model, with a textured object.</p>
<p>On the other hand, the big negative of this technique appears here as well. You now have to re-render every object a second time. Depending on your scene, this could be a reasonable performance hit. So ensure you weigh up both options when choosing your renderer for your game, and consider what you will need when choosing.</p>
<h3>Transparency/Anti-aliasing</h3>
<p>Transparency and Anti-Aliasing have traditionally been a major problem when it comes to Deferred Rendering. The need to render a Depth buffer has prevented the ability to do any reasonable form of transparency aside from the basic Invisible/Opaque states. There are a few solutions to this issue, although none solve it perfectly.</p>
<ol>
<li>Render your transparent objects using traditional forward rendering, with a limited number of lights, and composite the transparency scene into your deferred scene. </li>
<li>Use stippling to alternate between layers on a high resolution render target. This is used in the recent articles on Inferred Rendering. </li>
<li>Use Order Independent Transparency/Depth Peeling, which can be fairly expensive. (See DX SDK Feb 2010 Samples) </li>
</ol>
<p>I would recommend using option #1 and constructing your scenes so that the only transparent objects are particles, which can be lit with a small number of lights for little to no visual impact.</p>
<p>Anti-Aliasing has also been a problem for Deferred Renderers, primarily because DirectX 9 does not allow for AA with multiple render targets. DirectX 10 allows this, and fixes the issue, however since my target here is XNA, this is not possible.</p>
<p>Traditionally the AA issue was solved by using an Edge Detection filter + Blur to soften the edges of objects, this is relatively cheap and can be implemented as a post processing effect.</p>
<p>However for those interested in taking advantage of the AA modes of modern graphics cards, with very crisp edges, LPP provides a way to have your cake and eat it. (With a small cost)</p>
<p>As there are only 2 Render Targets needed during the Depth + Normals pass, and one at a time after that, you can split that pass up and render the scene an extra time, this time with AA enabled for each step. Of course if you have high scene complexity this might be extremely expensive and not worth it, but the option is there, and it is up to you and the needs of your game.</p>
<h3>Conclusion</h3>
<p>You now have a backbuffer (or Render Target) filled with your shaded scene, ready for further post processing, or presentation to the user. By using this technique you gain the ability to have thousands of lights in your scene at once, which allows level designers and artists to really let loose with their creativity.</p>
<p>Simply having this sheer number of lights also opens up other possibilities for lighting, including fake indirect lighting, a technique that as not been easy to do dynamically. You can assign point lights to every particle in your scene, and really make your worlds much more vibrant.</p>
<p>Also remember that you have a Depth and Normal buffer available for free (you needed it for LPP anyway) for use in post processing, which allows you to add other techniques like SSAO to your game.</p>
<p>Deferred Rendering seems to be the &quot;cool thing” in game graphics today, and with the Compute Shader/OpenCL becoming readily available, some of these techniques can be adapted to make use of the general purpose capabilities of modern graphics cards.</p>
<p>Whilst there are plenty of benefits, there are also negatives to using this technique, and you really need to think about what you want out of your renderer before making your final decision. There have been plenty of debates in the graphics world about whether Deferred Rendering is better than Forward Rendering, and I am not going to go into one of those today.</p>
<h3>Further Reading</h3>
<p>For more information about Deferred Lighting/Light Pre Pass, you can check out the following books/websites:</p>
<ul>
<li><a href="http://diaryofagraphicsprogrammer.blogspot.com/">http://diaryofagraphicsprogrammer.blogspot.com/</a> </li>
<li>Section8, Chapter 5; ShaderX7, Wolfgang Engel, Course Technology [ISBN: 1584505982] </li>
<li><a title="http://www.bungie.net/images/Inside/publications/siggraph/Engel/LightPrePass.ppt" href="http://www.bungie.net/images/Inside/publications/siggraph/Engel/LightPrePass.ppt">http://www.bungie.net/images/Inside/publications/siggraph/Engel/LightPrePass.ppt</a> (SIGGRAPH 2009) </li>
</ul>
<h3>Sample</h3>
<p>I have written a sample implementation of the Deferred Lighting/Light Pre Pass renderer using XNA 3.1. Feel free to learn from this implementation, and if you have any questions, just ask in the comments.</p>
<p>The code provided in the sample is for Academic Use Only, and cannot be copied into a Commercial program.</p>
<p>This sample shows off 6 directional lights around a single model taken from the DirectX SDK. Feel free to add more lights as you please. I have only implemented Directional lights for this sample, to keep things simple. I will provide information on implementing other lights soon, however in the meanwhile feel free to look at my previous (now obsolete) article for a point light implementation, which should be similar.</p>
<p>You can download the sample <a href="http://cid-670fd4ae41402e8a.skydrive.live.com/self.aspx/Public/LPPSample.zip" target="_blank">here</a>.</p>
<p>Controls:</p>
<p>1 : Show Depth Buffer<br />
  <br />2 : Show Normal Buffer </p>
<p>3 : Show Lights Buffer </p>
<p>4 : Show Material Buffer</p>
<p>W : Move Forward<br />
  <br />S : Move Backward </p>
<p>A : Strafe Left </p>
<p>D : Strafe Right </p>
<p>Left Arrow : Rotate Left </p>
<p>Right Arrow : Rotate Right</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/03/light-pre-pass-round-2/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>An update on LPP + Sample</title>
		<link>http://mquandt.com/blog/2010/02/an-update-on-lpp-sample/</link>
		<comments>http://mquandt.com/blog/2010/02/an-update-on-lpp-sample/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 04:48:41 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[DirectX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[game engine gems]]></category>
		<category><![CDATA[game programming gems]]></category>
		<category><![CDATA[gpu pro]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[sample code]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2010/02/an-update-on-lpp-sample/</guid>
		<description><![CDATA[Hi everyone, first of all apologies for the delay. there has been quite a lot going on in my life, but I am working hard on getting the sample done. This time around I wanted to make sure I had a sample ready to go with the article, especially since the article will focus on &#8230; <a href="http://mquandt.com/blog/2010/02/an-update-on-lpp-sample/">Read more <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Hi everyone, first of all apologies for the delay. there has been quite a lot going on in my life, but I am working hard on getting the sample done. This time around I wanted to make sure I had a sample ready to go with the article, especially since the article will focus on the technique and theory and have little to no code – although I will certainly focus on XNA when it comes to mentioning issues and benefits to certain parts.</p>
<p>One of the main delays was getting the sample code out of my engine, and cleaning it up so it can be used as a learning tool. Unfortunately most of the code was hacked on as I fixed issues in the LPP renderer, and added features.</p>
<p>I have a fair bit of the article written, however recently I was implementing shadows and realised that I never thought about how they would integrate into the system, so I decided to rewrite my own renderer (which should not take long) and at the same time keep the code clean so it can serve as a sample as well.</p>
<p>This means I will probably also have Directional Light shadows in the sample. This then allows me to write about point lights, and spotlights later on, and include shadows for both.</p>
<p>So again, sorry for the delay, I am working hard to get it out soon.</p>
<p>As an aside, I noticed that Game Programming Gems is getting an 8th Edition, something I was not expecting, so with that, GPU Pro, and Game Engine Gems, I might be able to find some more cool things to write about.</p>
<p>Thank You for your patience.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/02/an-update-on-lpp-sample/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

