<?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>Fri, 12 Mar 2010 12:34:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='mquandt.com' port='80' path='/blog/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<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 of the [...]]]></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[Games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[directx]]></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 sample [...]]]></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>3</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[Programming]]></category>
		<category><![CDATA[directx]]></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 [...]]]></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>
		<item>
		<title>Action Based Input Manager w/Events in XNA</title>
		<link>http://mquandt.com/blog/2010/01/xna-input-manager-sample/</link>
		<comments>http://mquandt.com/blog/2010/01/xna-input-manager-sample/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 03:45:43 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[sample]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/?p=84</guid>
		<description><![CDATA[I recently completed an action based Input system for my own engine that allows me to create named actions which support the GamePad, Keyboard and Mouse.
The system uses events to notify the game of changes in input state, which makes it really easy to use, and the system supports XML serialisation so key assignments can [...]]]></description>
			<content:encoded><![CDATA[<p>I recently completed an action based Input system for my own engine that allows me to create named actions which support the GamePad, Keyboard and Mouse.</p>
<p>The system uses events to notify the game of changes in input state, which makes it really easy to use, and the system supports XML serialisation so key assignments can be saved and loaded.</p>
<p>Supports:</p>
<ul>
<li>Thumbsticks (Analog)</li>
<li>Triggers (Analog)</li>
<li>GamePad Buttons (incl Trigger “Buttons”)</li>
<li>Keyboard</li>
<li>Mouse (Analog)</li>
<li>Mouse Buttons</li>
</ul>
<p>The system also supports Gamepad, Mouse and Keyboard assignments for each action, so you can support both the GamePad and Keyboard at the same time.</p>
<p>It also supports disabling of certain GamePads, so you can find the active GamePad and only accept input from that one, via a really simply array of booleans.</p>
<p>You can specify a single direction or axis for the Thumbstick and Mouse, so that the events will only be triggered if there is movement “up” on the Thumbstick.</p>
<p>You can download the InputManager and InputAction classes below:</p>
<p><a href="http://mquandt.com/blog/downloads/samples/AxialInput.zip" target="_blank">AxialInput Sample</a></p>
<p>Feel free to use these classes in your own project, although if you do make use of them, it would be nice to get a mention.</p>
<p>If you notice any problems, or have any suggestions/feedback, feel free to post them in the comments.</p>
<p><em>Note/Disclaimer:<br />
This sample/code is provided as is. I am not responsible for any problems you may have, and you use the code at your own risk.<br />
I am available to answer questions about the code through the comment system on this website &#8211; although this is not guaranteed.<br />
This code was intended for personal use, however I have decided to share it with the community to help out newer developers. </em></p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2010/01/xna-input-manager-sample/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rewrite of LPP Article Planned</title>
		<link>http://mquandt.com/blog/2009/12/rewrite-of-lpp-article-planned/</link>
		<comments>http://mquandt.com/blog/2009/12/rewrite-of-lpp-article-planned/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 15:54:25 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Xbox 360]]></category>
		<category><![CDATA[directx]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[xbox 360]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2009/12/rewrite-of-lpp-article-planned/</guid>
		<description><![CDATA[I recently went about making the current Light Pre Pass system run on the XBOX 360, and had to fix some issues that appeared there. As a result, the next article to go up will be a rewrite with all of these fixes included. I should also be able to provide the sample code at [...]]]></description>
			<content:encoded><![CDATA[<p>I recently went about making the current Light Pre Pass system run on the XBOX 360, and had to fix some issues that appeared there. As a result, the next article to go up will be a rewrite with all of these fixes included. I should also be able to provide the sample code at the same time.</p>
<p>This time around I will cover Point, Ambient and Directional lights in the same post, as well as including information about an alternate light buffer format that allows for improved specular + per-material specular.</p>
<p>Expect this either during the weekend of 20-21st Dec, or shortly after that.</p>
<p>Unfortunately I could not test the code on the XBOX the first time around due to subscription issues, however everything is fine now, and I can and will test on both XBOX and my desktop PC beforehand. (Perhaps also other PC configs depending on who I can find online at the time, and what other machines I have on hand <img src='http://mquandt.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2009/12/rewrite-of-lpp-article-planned/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Light Pre Pass in XNA: Basic Implementation</title>
		<link>http://mquandt.com/blog/2009/12/light-pre-pass-in-xna-basic-implementation/</link>
		<comments>http://mquandt.com/blog/2009/12/light-pre-pass-in-xna-basic-implementation/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 13:43:33 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Xbox 360]]></category>
		<category><![CDATA[directx]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/?p=60</guid>
		<description><![CDATA[In this part I will cover how to implement the basic form of the Light Pre Pass renderer, with support for point lights, and the basic Blinn-Phong shader, including Albedo texture support.
As this article is fairly advanced in nature, I have to make certain assumptions about my audience, so that I do not spend half [...]]]></description>
			<content:encoded><![CDATA[<p>In this part I will cover how to implement the basic form of the Light Pre Pass renderer, with support for point lights, and the basic Blinn-Phong shader, including Albedo texture support.</p>
<p>As this article is fairly advanced in nature, I have to make certain assumptions about my audience, so that I do not spend half my time explaining basics. Firstly, you should have an understanding of basic concepts such as Cameras, Fullscreen Quads (including how to render one) and rendering a mesh with custom effects.</p>
<p>This pretty much means that as long as you have done some 3D work before, you should be fine. It would be best if you also knew XNA, as I will be using that to write this implementation, however as long as you can translate from C# and get the basic idea, that should be enough.</p>
<p>As you can see from these requirements, this article is not aimed at beginners, and if you are looking for tutorials on how to get started with XNA for 3D development, I would recommend you visit some great sites such as:</p>
<ul>
<li><a href="http://creators.xna.com">http://creators.xna.com</a> </li>
<li><a href="http://www.thehazymind.com">http://www.thehazymind.com</a> </li>
<li><a href="http://xna-uk.net/blogs/randomchaos/">http://xna-uk.net/blogs/randomchaos/</a> </li>
</ul>
<p>Those sites will help you get started with XNA, and once you are familiar and comfortable with the concepts behind 3D graphics, you can return here to learn an advanced renderer implementation.</p>
<p>My focus in this article will be on the implementation of the renderer, as a result, I will not be referring to the implementation of cameras or scene graphs.</p>
<p>Now that the housekeeping is out of the way, we can begin.</p>
</p>
<p> <span id="more-60"></span>
</p>
<h3>The Renderer in C#</h3>
<p>Light Pre Pass (LPP), or Deferred Lighting, operates in 3 stages.</p>
<ol>
<li>Depth + Normals Rendering </li>
<li>Light Rendering </li>
<li>Materials Rendering </li>
</ol>
<p>These 3 stages accumulate information into render targets, which are used by the next stage, until the Materials stage produces the final image. So the first thing we must do, is set up at least the following Render Targets:</p>
<ul>
<li>Depth (SurfaceFormat.Single) </li>
<li>Normals (SurfaceFormat.Bgra1010102) </li>
<li>Lights (SurfaceFormat.Color) </li>
</ul>
<pre class="brush: csharp;">depth = new RenderTarget2D(gfx, width, height, 1, SurfaceFormat.Single, RenderTargetUsage.DiscardContents);
normals = new RenderTarget2D(gfx, width, height, 1, SurfaceFormat.Bgra1010102, RenderTargetUsage.DiscardContents);
light = new RenderTarget2D(gfx, width, height, 1, SurfaceFormat.Color, RenderTargetUsage.DiscardContents);
final = new RenderTarget2D(gfx, width, height, 1, SurfaceFormat.Color, RenderTargetUsage.DiscardContents);</pre>
<p>We use Bgra1010102 for storage of normals because we want maximum precision for the 3 channels we are using. The closest format that provides 32bits of depth and 3 channels is 1010102, where there are 10 bits for the 3 channels we care about, giving greater precision over the 8 bits in a normal A8R8G8B8 (or Color) surface format.</p>
<p>The Materials, or final pass can be rendered directly to the Backbuffer, or to a Render Target, this depends on your needs, and is completely up to you. I have provided suggested SurfaceFormats above, however you can feel free to use your own, however note that the shaders I provide may not work [correctly] with your chosen format.</p>
<h3>Depth + Normals</h3>
<p>The first stage of the renderer, requires you to render the Depth and Normal values for each pixel to the screen. You can optionally render the position directly, however many post processing techniques use depth information, so why not render it now to re-use later.</p>
<p>First we must setup the render targets on our device, easily done with two lines of code:</p>
<pre class="brush: csharp;">gfx.SetRenderTarget(0, depth);
gfx.SetRenderTarget(1, normals);</pre>
<p>For those who have not worked with multiple render targets before, the number in the above code indicates the render target index, and allows you to un-set and resolve the render target later.</p>
<p>Now you must first clear the render targets. As we are using multiple render targets, a simple call to GraphicsDevice.Clear will not suffice, instead we simply render a fullscreen quad using a cheap shader to write out the clear colours to the render targets.</p>
<pre class="brush: cpp;">struct VS_OUT
{
    float4 Position        : POSITION;
};

VS_OUT vs_main(float3 position : POSITION)
{
    VS_OUT output = (VS_OUT)0;
    output.Position = float4(position, 1);

    return output;
}

struct PS_OUT
{
    float4 Depth : COLOR0;
    float4 Normals : COLOR1;
};

PS_OUT ps_main()
{
    PS_OUT output = (PS_OUT)0;

    output.Depth = 1.0f;

    output.Normals = float4(0, 0, 0, 1);

    return output;
}</pre>
<p>Next you render the objects, using a special shader that writes the Depth and Normals to the two render targets. If you intend to implement Normal Mapping, or a similar technique, this is where you would calculate and combine the Normals. For the purposes of this article, only the basic per-vertex normals will be stored here.</p>
<p>One thing I had to do, was ensure a couple of render states were set correctly, specifically DepthBufferEnable and DepthBufferWriteEnable. Ensure both of these are set to true before continuing.</p>
<p>The Depth and Normals shader is quite simple. First the object is transformed as it would normally be when rendering, and then the Z and W values from the transformed position are passed to the pixel shader, alongside the Normal.</p>
<pre class="brush: cpp;">struct VS_IN
{
    float4 Position   : POSITION;
    float4 Normal     : NORMAL0;
};

struct VS_OUT
{
    float4 Position   : POSITION;
    float4 Depth      : TEXCOORD0;
    float4 Normal     : TEXCOORD1;
};

VS_OUT depthNorm_VS(VS_IN input)
{
    VS_OUT output = (VS_OUT)0;

    float4x4 wvp = mul(World, ViewProjection);

    output.Position = mul(input.Position, wvp);

    output.Depth.xy = output.Position.zw;

    output.Normal = mul(World, input.Normal);

    return output;
}</pre>
<p>If you look at your render targets, you may see a white image for the depth buffer, this is normal, as the differences in depth between most points on an object are miniscule, and close to 1. Your normals buffer however should look something like this:</p>
<p><a href="http://mquandt.com/blog/wp-content/uploads/2009/12/normals.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="normals" border="0" alt="normals" src="http://mquandt.com/blog/wp-content/uploads/2009/12/normals_thumb.png" width="244" height="139" /></a></p>
<p>Inside the pixel shader, the Z value is divided by the W value to get the depth, and that is written to the first render target. Then the Normal is normalised and shifted from a range of [-1, 1] to [0, 1].</p>
<pre class="brush: cpp;">struct PS_OUT
{
    float4 Depth : COLOR0;
    float4 Normals : COLOR1;
};

PS_OUT depthNorm_PS(float4 depth : TEXCOORD0, float4 normal : TEXCOORD1)
{
    PS_OUT output = (PS_OUT)0;

    output.Depth = depth.x / depth.y;

    output.Normals.rgb = 0.5f * (normalize(normal) + 1.0f);

    // Set alpha for both Depth and Normals to 1 (for some reason its required)
    output.Depth.a = 1.0f;
    output.Normals.a = 1.0f;

    return output;
}</pre>
<p>Now that we have our Depth and Normal values stored in the render targets, we can resolve and get their respective textures so that the lights can be rendered using this data. This is quite simple in XNA, just set the render targets on the graphics device to either another render target, or null. In this case, we can set RT0 to the light buffer, and set RT1 to null.</p>
<pre class="brush: csharp;">gfx.SetRenderTarget(0, light);
gfx.SetRenderTarget(1, null);
depthImage = depth.GetTexture();
normImage = normals.GetTexture();</pre>
<p>Be sure to clear the light buffer to TransparentBlack, and then we can move on to rendering the lights.</p>
<p>In this first tutorial, I will implement point lights only. Check back for future tutorials about implementing other types of lights, like Directional Lights, etc.</p>
<p>Rendering the light stage is a little bit more complicated than the Depth + Normals stage. This time around, a number of Render States must be set in the beginning, and even more for each light based on the position of the camera.</p>
<h4>Render States</h4>
<p>The following render states must be set when drawing the lights, to take advantage of alpha blending for blending multiple overlapping lights.</p>
<pre class="brush: csharp;">gfx.RenderState.AlphaBlendEnable = true;
gfx.RenderState.SeparateAlphaBlendEnabled = false;
gfx.RenderState.AlphaBlendOperation = BlendFunction.Add;
gfx.RenderState.SourceBlend = Blend.One;
gfx.RenderState.DestinationBlend = Blend.One;
gfx.RenderState.DepthBufferEnable = false;
gfx.RenderState.DepthBufferWriteEnable = false;</pre>
<p>Here we are disabling the Z-culling feature of the graphics card so that overlapping lights can be drawn, as well as enabling Alpha Blending over all channels of the render target so that the process of combining overlapping lights will be handled by hardware automatically. We also ensure that no modifications to the destination or source values are made during the blending stage, and that Additive blending is used. (Remember that lighting equations add multiple lights together)</p>
<p>Now you run through each light and set the CullMode render state based on where the camera frustum is located. If the frustum is inside or overlaps the light bounding volume (in this case a sphere), the CullMode needs to be set to CullClockwiseFace. CullCounterClockwiseFace should be set if the frustum is completely outside the light bounding volume. Remember to also ensure that the CullMode is set to CullCounterClockwiseFace after all of the lights have been rendered.</p>
<p>In the sample code, I use a Mesh to easily load and store the light volume, which for a Point Light, would be a sphere. A scaling matrix allows for the attenuation to be changed, so be sure to update any matrices as needed.</p>
<p>Some notes about the next code sample:</p>
<ul>
<li>cmanager is my CameraManager, it is used here to set the ViewProjection and InverseViewProjection matrices, which are required to transform the Depth back into a position for lighting. </li>
<li>caller is the Renderer class, which coordinates rendering each stage, as well as setting up and resolving the appropriate buffers. </li>
</ul>
<pre class="brush: csharp;">public void DrawLightDeferred(GraphicsDevice gfx, CameraManager cmanager, Renderer caller)
{
    shader.Begin();

    // Set Matrix params
    cmanager.ApplyCameraParameters(ref shader);
    shader.Parameters.GetParameterBySemantic(&quot;WORLD&quot;).SetValue(world);

    // Set Depth and Normals buffers
    shader.Parameters[&quot;Depth_Tex&quot;].SetValue(caller.GetDepthImage());
    shader.Parameters[&quot;Normals_Tex&quot;].SetValue(caller.GetNormalsImage());

    // Set lighting params
    shader.Parameters[&quot;LightPos&quot;].SetValue(_pos);
    shader.Parameters[&quot;Attenuation&quot;].SetValue(_attenuation);
    shader.Parameters[&quot;SpecPower&quot;].SetValue(SpecularPower);
    shader.Parameters[&quot;LightColor&quot;].SetValue(LightColor.ToVector4());

    for (int j = 0; j &lt; lightMesh.Meshes.Count; j++)
    {
        gfx.Indices = lightMesh.Meshes[j].IndexBuffer;

        for (int k = 0; k &lt; lightMesh.Meshes[j].MeshParts.Count; k++)
        {
            for (int i = 0; i &lt; shader.CurrentTechnique.Passes.Count; i++)
            {
                EffectPass pass = shader.CurrentTechnique.Passes[i];
                pass.Begin();

                gfx.VertexDeclaration = lightMesh.Meshes[j].MeshParts[k].VertexDeclaration;

                gfx.Vertices[0].SetSource(lightMesh.Meshes[j].VertexBuffer,
                    lightMesh.Meshes[j].MeshParts[k].StreamOffset,
                    lightMesh.Meshes[j].MeshParts[k].VertexStride);

                gfx.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                    lightMesh.Meshes[j].MeshParts[k].BaseVertex,
                    lightMesh.Meshes[j].MeshParts[k].StartIndex,
                    lightMesh.Meshes[j].MeshParts[k].NumVertices,
                    lightMesh.Meshes[j].MeshParts[k].StartIndex,
                    lightMesh.Meshes[j].MeshParts[k].PrimitiveCount);

                pass.End();
            }
        }
    }
    shader.End();
}</pre>
<p>Now I need to run through some helper methods I use in the upcoming point light shader. These methods handle transforming a position from Post Projection space, to Screen space, as well as calculating the half pixel offset required by DX9.</p>
<pre class="brush: cpp;">float2 postProjToScreen(float4 position)
{
    float2 screenPos = position.xy / position.w;
    return (0.5f * (float2(screenPos.x, -screenPos.y) + 1));
}

float2 halfPixel()
{
    return -(0.5f / float2(fViewportWidth, fViewportHeight));
}</pre>
<p>These are simple enough, and more importantly, *just work*.</p>
<p>Now for the point light shader. Here the light volume is transformed as needed in a really simple vertex shader:</p>
<pre class="brush: cpp;">struct VS_OUT
{
    float4 Position            : POSITION;
    float4 LightPosition    : TEXCOORD0;
};

VS_OUT vs_main(float4 inPos : POSITION)
{
    VS_OUT output = (VS_OUT)0;

    float4x4 wvp = mul(World, ViewProjection);

    output.Position = mul(inPos, wvp);
    output.LightPosition = output.Position;

    return output;
}</pre>
<p>The following variables are also passed to the shader for lighting calculations:</p>
<pre class="brush: cpp;">float3 LightPos;
float Attenuation;
float SpecPower;
float4 LightColor;
float3 CamPos : VIEWPOSITION;
float3 EyeDepthRay;</pre>
<p>The key code comes in the pixel shader. The first thing needed is to transform the position of the pixel from post projection space to screen space. This is handled by the helper method I mentioned earlier. Then the half pixel offset is deducted from the screen space position, so that the values read from the Depth and Normal buffers are correct.</p>
<pre class="brush: cpp;">// Transform from post-projection to texcoords
float2 screenPos = postProjToScreen(projPos);
// DX9 half pixel offset
float2 texCoord = screenPos - halfPixel();

float depth = tex2D(depthSampler, texCoord);</pre>
<p>Next, read the depth from the Depth buffer, and if the value is not less than 1, we simply write a value of 0 for this pixel, as there is no depth information at that point, and nothing to light. If there is however, the lighting can be calculated for that point.</p>
<pre class="brush: cpp;">// Reconstruct position from screen space + depth
float4 position;
position.x = texCoord.x * 2 - 1;
position.y = (1 - texCoord.y) * 2 - 1;
position.z = depth;
position.w = 1.0f;
position = mul(position, InvViewProjection);
position.xyz /= position.w;</pre>
<p>For more information on how to reconstruct a position based on a depth value, read <a href="http://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/">this</a>. There are also alternative, and improved methods listed there, which can be used depending on your needs.</p>
<p>Next the normal is acquired from the normal buffer, and restored to the [-1, 1] range so that it can be correctly used in the lighting calculations.</p>
<pre class="brush: cpp;">// Restore Normal
float3 normal = tex2D(normSampler, texCoord);
normal = normalize(2.0f * normal - 1.0f);</pre>
<p>Now the lighting can begin. There are two key elements that need to be calculated for our light buffer: N.L and Attenuation. N.L is the basic element in every lighting equation, and simply consists of the dot product between the Normal and the Light Direction.</p>
<p>Attenuation is calculated by simply determining the ratio of distance to light over maximum attenuation, this is then flipped so that 0 is the furthest point from the light. Here I also pre-combine the attenuation and the N.L value. You can of course combine these later when writing out the buffer, ultimately it gives the same result.</p>
<pre class="brush: cpp;">// Attenuation Calcs
float3 lDir = LightPos - position;
float atten = saturate(1 - dot(lDir/Attenuation, lDir/Attenuation));
lDir = normalize(lDir);

// N.L
float nl = dot(normal, lDir) * atten;</pre>
<p>Next we calculate the specular value. As we are using the Blinn-Phong lighting equation later on, the Half Vector is used instead of the reflection Vector, which ends up being a cheaper calculation for us. (Negligible for most modern systems – but visual difference is imperceptible)</p>
<p>For the purposes of this article, I will only include the code from the Blinn-Phong variant, however in the downloadable sample, I provide both methods that can be toggled with a boolean. (Change the technique to change the method)</p>
<p>Remember that this only affects the specular value, so do not worry that this will restrict you to the Blinn-Phong (or just Phong) lighting model.</p>
<pre class="brush: cpp;">float3 halfDir = normalize(lDir + camDir);
spec = pow(saturate(dot(normal, halfDir)), SpecPower);</pre>
<p>Finally we generate the buffer and this is where we combine the light colour with the calculated N.L and Attenuation values.</p>
<pre class="brush: cpp;">return float4(LightColor.r, LightColor.g, LightColor.b, spec) * nl;</pre>
<p>You should get something that looks like this: (Note that due to transparency this may look weird, however the essential part to note is the lights making up the shape of the model)</p>
<p><a href="http://mquandt.com/blog/wp-content/uploads/2009/12/lights.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="lights" border="0" alt="lights" src="http://mquandt.com/blog/wp-content/uploads/2009/12/lights_thumb.png" width="244" height="139" /></a></p>
<p>Now we are entering the home stretch. All that is left to render now is the materials for each object. This is simply a matter of rendering each object again, and using the Light buffer to shade the object. Here is also where the material-flexibility of LPP comes into play, as each object uses its own shader.</p>
<p>To prepare for this stage, simple resolve the light buffer by setting either the backbuffer (null) or a “Final Image” render target as RT0. Then you can get the light texture, and provide it so the objects can use it when rendering.</p>
<p>This is the pixel shader:</p>
<pre class="brush: cpp;">float2 scrCoord = postProjToScreen(input.ScrCoord) - halfPixel();

float4 light = tex2D(lightSampler, scrCoord);

float3 texCol = tex2D(texSampler, input.TexCoord);

float3 lighting = saturate(AmbientLight + (light.rgb * texCol) + light.aaa);

return float4(lighting, 1);</pre>
<p>Here I adjust by the half pixel offset and transform from post projection to screen space inside the vertex shader, so those calculations are as before, however I pass the corrected Texture Coordinate to the pixel shader.</p>
<p>As this material is a Blinn-Phong material, it is a rather simple equation. The “Sum of light colour multiplied by N.L and attenuation” is handled by the Alpha Blending and light shaders, so that simply needs to be multiplied by the texture (Albedo) colour, which is then added to the ambient light term and specular term to complete the lighting equation.</p>
<p>Finally this is done, you now have either a backbuffer, or render target filled with a lit scene.</p>
<p><a href="http://mquandt.com/blog/wp-content/uploads/2009/12/final.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="final" border="0" alt="final" src="http://mquandt.com/blog/wp-content/uploads/2009/12/final_thumb.png" width="244" height="139" /></a></p>
<p>There are many other materials which can be adapted to use the light buffer, and there is also a modification that can be done to the light buffer and final material shaders to allow for a material specular value, however I will leave those to future articles.</p>
<p>I hope this has been informative, and if you have any questions, please post them in the comments. Also be sure to check back for new tutorials covering different light types, materials, and other additions. I hope to get shadows implemented into the system, and also outline combining this with a forward renderer to allow for transparent objects and particles.</p>
<p>The screenshots in this post use 1000 point lights arranged in a 10&#215;10x10 cube around the model.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2009/12/light-pre-pass-in-xna-basic-implementation/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Light Pre Pass Implementation Ready</title>
		<link>http://mquandt.com/blog/2009/11/lpp-ready/</link>
		<comments>http://mquandt.com/blog/2009/11/lpp-ready/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 14:50:33 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[directx]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2009/11/lpp-ready/</guid>
		<description><![CDATA[&#160;

As you can see, it is rendering correctly, and now I can begin writing about the implementation.
Just have to clean some code, maybe improve one or two things. I hope to begin the article series (the previous entry was an intro) after my final exam on friday.
]]></description>
			<content:encoded><![CDATA[<p>&#160;<a href="http://mquandt.com/blog/wp-content/uploads/2009/11/lpp_test1.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Light Pre Pass" border="0" alt="Light Pre Pass" src="http://mquandt.com/blog/wp-content/uploads/2009/11/lpp_test1_thumb.png" width="644" height="378" /></a>
</p>
<p>As you can see, it is rendering correctly, and now I can begin writing about the implementation.</p>
<p>Just have to clean some code, maybe improve one or two things. I hope to begin the article series (the previous entry was an intro) after my final exam on friday.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2009/11/lpp-ready/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Light Pre-Pass in XNA [Part 1]</title>
		<link>http://mquandt.com/blog/2009/11/light-pre-pass-in-xna-part-1/</link>
		<comments>http://mquandt.com/blog/2009/11/light-pre-pass-in-xna-part-1/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 11:54:14 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[directx]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[deferred lighting]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[rendering]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2009/11/light-pre-pass-in-xna-part-1/</guid>
		<description><![CDATA[This is the first part of the article I began writing not too long ago. Unfortunately university assignments and exams halted my progress, however as I am almost done, I thought I might as well put up the first part, and then add more as I get them done once my exams are finished.
I hope [...]]]></description>
			<content:encoded><![CDATA[<p>This is the first part of the article I began writing not too long ago. Unfortunately university assignments and exams halted my progress, however as I am almost done, I thought I might as well put up the first part, and then add more as I get them done once my exams are finished.</p>
<p>I hope you like this introduction, and you return to see the rest of the series. I also hope that this introduction will encourage you to seek out resources, linked or otherwise, on the topic so you can have a try before I post how I did it. Discussion on my implementation/views, and what you have done is welcome and encouraged, feel free to post in the comments and provide feedback.</p>
<h2>Introduction</h2>
<p>Recently I have found the time to get started on the engine design I&#8217;ve had in mind for a while now, and finally get started on some games I want to develop. Since my interest and focus is on 3D rather than 2D at the moment, I decided to go with a deferred renderer, however I remembered back to last year when I read a post by <a href="http://diaryofagraphicsprogrammer.blogspot.com">Wolfgang Engel</a> about a new renderer design, called the <a href="http://diaryofagraphicsprogrammer.blogspot.com/2008/03/light-pre-pass-renderer.html">Light Pre-Pass renderer</a>, that took the ideas of deferred shading, and added back some of the flexibility of forward rendering, at the cost of an extra pass.</p>
<p>Since then, <a href="http://www.crytek.com">Crytek</a> have announced they are using a similar technique in <a href="http://mycryengine.com/">CryEngine 3</a>, and other companies have used the technique, or a similar version in their own games, sometimes going under the name of Deferred Lighting.</p>
<p>For those who have implemented deferred shading before, this will be quite easy to understand, however for those who do not understand the concept of a deferred renderer and deferred shading yet, I will explain it here before I continue.</p>
<h2>Deferred Rendering</h2>
<p>In traditional forward rendering, each light is applied to the affected meshes when those meshes are rendered. This means that inside the material shader for the mesh, each individual light that affects the model must be processed. This has traditionally limited meshes to 3-4 lights, as the instruction counts for earlier shader models have been limiting, and even as those limits are lifted, the time needed to render these lights on every pixel of the mesh (even parts that are not lit) for each mesh, can add up to a substantial time.</p>
<p>Deferred rendering aims to solve this problem by rendering lights and models separately, and therefore reducing the complexity of the shaders for the meshes. The idea is that the meshes are drawn, and all important data such as position, normals, texture colour (diffuse), etc are stored in a series of render targets, taking advantage of the Multiple Render Targets (MRT) feature of modern graphics cards.</p>
<p>Then the lights are then drawn, either using a full screen quad for each light, or simple meshes that represent the shape of the light volume in the world. As these are drawn, the lighting calculations make use of the pre-processed data from the meshes in the other render targets, and so lights are not processed for any unnecessary pixels. This allows for tens-hundreds of lights, as lights are essentially just simple meshes.</p>
<p>There are downsides here however, for one thing, Direct3D9 and the XBOX 360 do not support MultiSample Anti-Aliasing (MSAA) for MRTs, and due to the fact that only one position (or depth) can be stored for each pixel, transparent objects cannot be properly rendered.</p>
<p>The former issue can be resolved with some post processing. A selective blur with edge detect can soften the edges enough to remove aliasing, however the transparency issue will require a second pass using forward rendering. (or more complexity if you choose to use the stippling route – something that I will not be covering)</p>
<p>Material diversity is also an issue, as all lighting calculations are done with a single shader. This means that a single uber-shader must be written to cover all the techniques needed, which is limiting, but if you do not have a diverse selection of materials, this should not be that much of an issue.</p>
<h2>Deferred Lighting aka Light Pre-Pass</h2>
<p>Deferred Shading also has the negative of having a rather fat frame-buffer during the mesh stage, as quite often 4 MRTs are used to store all the required information. Rendering each of these one by one would impart a huge cost, and so MRT support is <strong>required</strong> on the graphics card.</p>
<p>Light Pre-Pass attempts to solve not only this issue, but also the material issue mentioned before. It works by just rendering position/depth and normals during the mesh stage. This can be split into two passes for cards that do not have MRT support, and so therefore this will support DX8.1 cards. The cost of rendering meshes a second time at this point is much better than rendering 4x.</p>
<p>Then the lights are drawn into their own single render target. The standard components of the Blinn-Phong lighting calculation are stored for the light being rendered, and all lights are alpha-blended into the render target.</p>
<p>The lighting components stored are as follows:</p>
<ul>
<li>LightColour.r * N.L * Att</li>
<li>LightColour.g * N.L * Att</li>
<li>LightColour.b * N.L * Att</li>
<li>(H.N)^SpecPower * N.L * Att</li>
</ul>
<p><em>(Att = Attenuation)</em></p>
<p>As you can see, the three channels of colour for the light are stored in the rgb channels of the render target, and the specular component is stored in the alpha channel.</p>
<p>Modifications can be made to this to store the above in a different colour space, however that is outside the scope of this article. (For more information, check out the article on the CIE Colour Space by Pat Wilson from GarageGames in ShaderX7 – also the comments <a href="https://www.blogger.com/comment.g?blogID=398682525365778708&amp;postID=5632530319554432608&amp;pli=1">here</a> for an interesting discussion on using Luminance and/or HSL for storing the light data)</p>
<p>The lights are alpha blended together, and end up as a single lighting value in a pixel in the buffer.</p>
<p>Once this buffer is rendered, the meshes are re-rendered, but this time we simply take the lighting data stored in the existing buffer, and apply that to the material for the mesh. Using LPP we gain the ability to have diverse material types, and each material can have its own shader again.</p>
<p>You no doubt see here that over forward rendering, we can have 10, 20, even 50 lights all lighting a single pixel on the mesh, and we have to draw much less.</p>
<p>So far you can see the following benefits to using Light Pre Pass over Deferred Shading:</p>
<ul>
<li>Lower cost per light due to smaller calculations in the light pass</li>
<li>A greater material variety</li>
<li>Less memory bandwidth usage and texture fetches – at most 2 during the light phase</li>
<li>Does <strong>NOT</strong> require SM3.0 hardware for the 4x MRT support, can actually run on DX8.1 hardware with no MRT support (just split depth + normal rendering)</li>
</ul>
<p>MSAA is something I have not covered for LPP because it technically can be done if you are fine with splitting the depth and normals rendering. If you go the same route as supporting a DX 8.1card, you then only have a single render target at a time, and MSAA can be enabled for all passes. (You can turn it off for the light stage though, not absolutely required there)</p>
<p>I would suggest that if MSAA is enabled, you use the split path of separate depth and normals, and when MSAA is not enabled (and the hardware supports MRTs) you do the combined rendering. A speed up during a depth only write still is not the same as only rendering the mesh once during that stage. I will not be covering this method in this article, as I want to keep it simple for newcomers. This is easy enough to add once you understand how to implement the normal form.</p>
<h2>Implementing</h2>
<h3>Requirements</h3>
<p>For this particular article, I am only going to implement the combined depth and normals path. This means that to properly follow along with this article, you will need a card capable of at least two simultaneous render targets. Most modern cards will do this, and the XBOX 360 will do up to 4 at a time, so that will work fine. If you have a Shader Model 3.0 card, then you are set, although anything before and you would need to check.</p>
<p>Other requirements include:</p>
<ul>
<li>Understanding of the <a href="http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model">Blinn-Phong lighting equation</a> – This is outside the scope of this article. Basic Phong will suffice if you know the different specular calculation.</li>
<li>Visual Studio 2008 (Express will do)</li>
<li><a href="http://creators.xna.com/en-US/downloads">XNA Game Studio 3.1</a> (3.0 will suffice if you only have that, but why not get 3.1? Its free)</li>
<li><a href="http://developer.nvidia.com/object/fx_composer_home.html">FX Composer</a> or <a href="http://developer.amd.com/gpu/rendermonkey/Pages/default.aspx">ATI RenderMonkey</a> &#8211; or anything else that will let you write shaders, these just provide syntax highlighting</li>
<li>An understanding of Vector/Matrix maths</li>
</ul>
<p>Continue to <a href="http://mquandt.com/blog/2009/12/light-pre-pass-in-xna-basic-implementation/">Implementation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2009/11/light-pre-pass-in-xna-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nebulon Now Available</title>
		<link>http://mquandt.com/blog/2009/07/nebulon-now-available/</link>
		<comments>http://mquandt.com/blog/2009/07/nebulon-now-available/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 11:40:20 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Xbox 360]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[dark omen games]]></category>
		<category><![CDATA[nebulon]]></category>
		<category><![CDATA[xblcg]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2009/07/nebulon-now-available/</guid>
		<description><![CDATA[Just letting everyone who reads this know that Nebulon is now available on XBOX LIVE Community Games. The official website for the game is http://nebulon.darkomengames.co.uk and you can go through there to buy online, or find it on your XBOX 360 console.
We are considering bringing this to PC, there are some things that need to [...]]]></description>
			<content:encoded><![CDATA[<p>Just letting everyone who reads this know that Nebulon is now available on XBOX LIVE Community Games. The official website for the game is <a href="http://nebulon.darkomengames.co.uk">http://nebulon.darkomengames.co.uk</a> and you can go through there to buy online, or find it on your XBOX 360 console.</p>
<p>We are considering bringing this to PC, there are some things that need to be done before that can happen, but if DapydTheBard is willing it will probably happen.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2009/07/nebulon-now-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nebulon in Playtest</title>
		<link>http://mquandt.com/blog/2009/06/nebulon-playtesting/</link>
		<comments>http://mquandt.com/blog/2009/06/nebulon-playtesting/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 11:51:49 +0000</pubDate>
		<dc:creator>Michael</dc:creator>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Xbox 360]]></category>
		<category><![CDATA[xna]]></category>
		<category><![CDATA[dark omen games]]></category>
		<category><![CDATA[nebulon]]></category>

		<guid isPermaLink="false">http://mquandt.com/blog/2009/06/nebulon-playtesting/</guid>
		<description><![CDATA[For those of you out there with a Creators Club Premium membership, head on over to http://creators.xna.com and help us (Dark Omen Games) out by playtesting Nebulon, our first game on the service. You can see a trailer for Nebulon in my last post here, and using the normal interface on the Creators Club website, [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you out there with a Creators Club Premium membership, head on over to <a href="http://creators.xna.com">http://creators.xna.com</a> and help us (Dark Omen Games) out by playtesting Nebulon, our first game on the service. You can see a trailer for Nebulon in my last post <a href="http://mquandt.com/blog/2009/05/blogs-have-posts-you-say/">here</a>, and using the normal interface on the Creators Club website, you can access the build of Nebulon we have up there and try it out. Let us know what you think and if you encounter any issues in the associated forum thread.</p>
<p>Hope you enjoy it!</p>
<p>You can find out more about Nebulon <a href="http://darkomengames.co.uk/?p=107">here</a>. We hope to have a game website up shortly with screenshots, videos, and information on both the PC and XBOX 360 versions.</p>
]]></content:encoded>
			<wfw:commentRss>http://mquandt.com/blog/2009/06/nebulon-playtesting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
