<?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; techniques</title>
	<atom:link href="http://mquandt.com/blog/tag/techniques/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>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>
	</channel>
</rss>

