<?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>Sgt. Conker &#187; Shaders</title>
	<atom:link href="http://www.sgtconker.com/category/xna/shaders/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sgtconker.com</link>
	<description>We are &#34;absolutely fine&#34;</description>
	<lastBuildDate>Wed, 06 Jul 2011 13:29: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>
			<item>
		<title>Nuclex Framework, Community Character Voting and Morph Targets</title>
		<link>http://www.sgtconker.com/2011/02/nuclex-framework-community-character-voting-and-morph-targets/</link>
		<comments>http://www.sgtconker.com/2011/02/nuclex-framework-community-character-voting-and-morph-targets/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 21:58:47 +0000</pubDate>
		<dc:creator>Captain boki</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[FatCow]]></category>
		<category><![CDATA[Nuclex]]></category>
		<category><![CDATA[VoteForGeorge]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/2011/02/nuclex-framework-community-character-voting-and-morph-targets/</guid>
		<description><![CDATA[Markus “Cygon4” Ewald&#160;announces the immediate availability of an intermediate release of his Nuclex Framework, adding: “There are still outstanding issues, but the previous release is already getting a beard and I'm getting reports for issues already solved  ”
Amit Ginni Patpatia of FatCow Games AS fame reminds the community to vote for a character for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.nuclex.org/">Markus “Cygon4” Ewald</a>&#160;<a href="http://twitter.com/#!/Cygon4/status/33875462933454849">announces the immediate availability</a> of an <a href="http://nuclexframework.codeplex.com/releases/view/60431">intermediate release of his Nuclex Framework</a>, <a href="http://twitter.com/#!/Cygon4/status/33875616000385025">adding</a>: “<q cite="http://twitter.com/#!/Cygon4/status/33875616000385025">There are still outstanding issues, but the previous release is already getting a beard and I'm getting reports for issues already solved <img src='http://www.sgtconker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </q>”</p>
<p><a href="http://twitter.com/#!/AmitGinni/status/33904490679640064">Amit Ginni Patpatia</a> of <a href="http://www.fatcowgames.net/">FatCow Games AS</a> fame reminds the <a href="http://networkedblogs.com/dIWpw">community to vote for a character</a> for an upcoming game.</p>
<p>Last but not least <a href="http://twitter.com/#!/mvinetwork/status/33927577106124801">Barnaby Smith</a>&#160;<a href="http://twitter.com/#!/mvinetwork/status/33927577106124801">pokes me</a> about an <a href="http://mvinetwork.co.uk/2011/02/02/xna-morph-targets/">XNA 3.1 Morph Target implementation he put online</a>: “<q cite="http://mvinetwork.co.uk/2011/02/02/xna-morph-targets/">This example uses multiple vertex streams and blends between them using a vertex shader. This approach is a differing method to CPU or VTF based implementations and does not require the calculation of vertex textures, making it quite simple and straightforward.</q>”</p>
<p> <iframe title="YouTube video player" height="390" src="http://www.youtube.com/embed/e6PLtA7wgg0?rel=0" frameborder="0" width="480" allowfullscreen="allowfullscreen"></iframe>
<p><a href="http://mvinetwork.co.uk/2011/02/02/xna-morph-targets/">Source code and more details can be found at his post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2011/02/nuclex-framework-community-character-voting-and-morph-targets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XNA 4.0 Light Pre-Pass</title>
		<link>http://www.sgtconker.com/2011/01/xna-4-0-light-pre-pass-2/</link>
		<comments>http://www.sgtconker.com/2011/01/xna-4-0-light-pre-pass-2/#comments</comments>
		<pubDate>Sun, 23 Jan 2011 09:08:38 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[3D]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Coluna]]></category>
		<category><![CDATA[light pre pass]]></category>
		<category><![CDATA[Rendering]]></category>
		<category><![CDATA[XNA 4.0]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1947</guid>
		<description><![CDATA[Jorge Coluna posted an article on his site about implementing the Light Pre-Pass technique for rendering in XNA 4.0

Read all about it here.
]]></description>
			<content:encoded><![CDATA[<p>Jorge Coluna posted an article on<a href="http://jcoluna.wordpress.com/"> his site</a> about implementing the Light Pre-Pass technique for rendering in XNA 4.0</p>
<p><a href="http://jcoluna.wordpress.com/2011/01/18/xna-4-0-light-pre-pass/"><img class="alignnone" title="Light Pre-Pass in XNA 4.0" src="http://jcoluna.files.wordpress.com/2011/01/shot-lpp-11.jpg" alt="Light Pre-Pass in XNA 4.0" width="467" height="275" /></a></p>
<p>Read all about it <a href="http://jcoluna.wordpress.com/2011/01/18/xna-4-0-light-pre-pass/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2011/01/xna-4-0-light-pre-pass-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Rim Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-rim-lighting/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-rim-lighting/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 20:21:36 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1794</guid>
		<description><![CDATA[by Daniel Greenheck
What should I be familiar with before I go through this tutorial?
- The content discussed in the ambient, diffuse and specular tutorials.
- Dot products, vectors
What is Rim Lighting?
Rim lighting is a shader technique you often see in role-playing games when there's a treasure chest or door which needs to be opened. Around the [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p>What should I be familiar with before I go through this tutorial?<br />
- The content discussed in the <a href="http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/">ambient</a>, <a href="http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/">diffuse</a> and <a href="http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/">specular</a> tutorials.<br />
- Dot products, vectors</p>
<h2>What is Rim Lighting?</h2>
<p>Rim lighting is a shader technique you often see in role-playing games when there's a treasure chest or door which needs to be opened. Around the border of the object there is a soft glow which differentiates it from the rest of the objects in the scene. The concept behind the rim lighting shader is extremely simple: the more a surface faces away from the camera, the more rim lighting it should get. Looking at the sphere below illustrates the point:<br />
<img class="alignnone" title="Sphere" src="http://digitseven.com/images/sphere.jpg" alt="" width="373" height="245" /></p>
<p><span id="more-1794"></span></p>
<p>Here, the rim light is set to be blue while the diffuse light is just a white light at 75% intensity. On the edges of the sphere, the normals of the triangles (remember a normal is the vector pointing perpendicular out of the surface) are more perpendicular to the line of sight, which is going straight into the page. The more perpendicular the normal is to the line of sight, the more rim light the surface receives.<br />
Now what mathematical tool allows us to compare how perpendicular/parallel two vectors are? That's right! The dot product. If you take the dot product of two normalized vectors which are parallel and pointing in the same direction, you get 1. If the vectors are perpendicular, you get zero. Using this knowledge we will know manipulate some shader code to create a rim lighting shader!</p>
<h2>The Rim Lighting Shader</h2>
<p>As usual, I once again present you with the entire specular shader. If you skipped my intro to this article, which I can't blame you for, I'll remind you that I left out the commenting on anything non-specular to save space and make the presentation a little nicer. If you don't know what the other parts of the program do, go back and read the Ambient and Diffuse shaders.</p>
<pre class="brush: plain; title: ;">
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor;
float4 DiffuseColor;
float4 SpecularColor;
float4 RimColor;

float AmbientIntensity;
float DiffuseIntensity;
float SpecularIntensity;
float RimIntensity;         // Intensity of the rim light

float3 DiffuseLightDirection;
float3 CameraPosition;
float3 CameraDirection;
float Shinniness;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

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

    // Get the vector from the camera to the vertex for the specular component by
    // subtracting the world position from the camera
    output.CameraView = normalize( CameraPosition - worldPosition );

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the rim lighting component by subtract the dot product of the normal and camera direction
    // from 1, then taking that to the 2nd power. This will give pixels at more perpendicular angles to the camera
    // a glow effect. Multiply that by rim color and intensity to adjust the color and brightness.
    // - If you take the dot product to a higher power, the glow will be thinner and closer to the edges.
    // - If you take the dot product to a lower power, the glow will be more spread out away from the edges.
    float4 rim = pow( 1 - dot( norm, CameraDirection ), 1.5 ) * RimColor * RimIntensity;

    // Calculate the specular component
    float3 halfAngle = normalize( lightdir + input.CameraView );
    float4 specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    // Calculate the diffuse component
    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseColor * DiffuseIntensity;
    // Calculate the ambient component
    float4 ambient = AmbientColor * AmbientIntensity;

    return rim + ambient + specular + diffuse;
}

technique RimLighting
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<p>The only difference between this and the specular lighting shader is a new variable called CameraDirection, some new variables to control the rim lighting effect and an extra line in the pixel shader. Let's start with the variable.</p>
<h2>New Rim Light Variables</h2>
<pre class="brush: plain; title: ;">
float4 RimColor;
float  RimIntensity;
float3 CameraDirection;
</pre>
<p>The first two variables are self-explanatory: they control the intensity and color of the rim light. CameraDirection is a very simple variable: all it is is a vector which points away from the camera in the direction you are looking. Below is a wonderful 2D drawing of what the camera direction vector is describing; 3D just adds another dimension but in essence is the same. The eye is at the center, the star is the object, and the red arrow is a normalized vector.<br />
<img class="alignnone" title="CameraDirection" src="http://digitseven.com/images/rimcameradirection.jpg" alt="" width="238" height="206" /><img class="alignnone" title="CameraDirection" src="http://digitseven.com/images/rimcameradirection.jpg" alt="" width="238" height="206" /></p>
<p>CameraDirection points TOWARDS the object</p>
<p>And that's really all you need to know in terms of new variables!</p>
<h2>Pixel Shader</h2>
<pre class="brush: plain; title: ;">
float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the rim lighting component by subtract the dot product of the normal and camera direction
    // from 1, then taking that to the 2nd power. This will give pixels at more perpendicular angles to the camera
    // a glow effect. Multiply that by rim color and intensity to adjust the color and brightness.
    // - If you take the dot product to a higher power, the glow will be thinner and closer to the edges.
    // - If you take the dot product to a lower power, the glow will be more spread out away from the edges.
    float4 rim = pow( 1 - dot( norm, CameraDirection ), 1.5 ) * RimColor * RimIntensity;

    // Calculate the specular component
    float3 halfAngle = normalize( lightdir + input.CameraView );
    float4 specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    // Calculate the diffuse component
    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseColor * DiffuseIntensity;
    // Calculate the ambient component
    float4 ambient = AmbientColor * AmbientIntensity;

    return rim + ambient + specular + diffuse;
}
</pre>
<p>The pixel shader is the same except for the line which is accompanied by the massive comment. Let's analyze the statement starting with what's inside the pow() function. Remember back to what I mentioned above about the dot product. When the normal of a surface is perpendicular to the line of sight, it gets the most rim light. The dot product of a perpendicular normal with the line of sight would result in 0, so that is backwards from what we want. When the dot product is 0, we really want the rim light at full intensity. So by subtracting the dot product of the normal and the CameraDirection from one, we get just this. So we get some number between 0 and 1, 1 giving us full intensity rim light and 0 giving us no rim light at all.<br />
Surrounding the dot product inverse is the pow() function. The power function allows us to adjust the falloff of our rim light. Since the amount of light is always between 0 and 1, taking it to a power greater than 1 results in a number less than the original number. For example, .5^2 = .25. This is how light eminating from a light source normally falls off, to the square of the distance. You can play around with the power (I have it set at a medium 1.5) to get the effect you want. The higher the power, the less rim lighting you will get on surfaces whose normals are more parallel to the camera direction than perpendicular. Here is an example of variation of power. The diffuse light is white and the rim light is blue.</p>
<p><img class="alignnone" title="Power" src="http://digitseven.com/images/power.jpg" alt="" width="603" height="280" /></p>
<p>As you can see, the smaller the power, the more spread out the rim light is. The larger the power, the more the light is confined to the edges. Finally, I just take that rim light component and multiply it with the RimColor and RimIntensity variables! And there you have it, glowing edges.</p>
<h2>Conclusion</h2>
<p>Rim lighting is a cool and easy technique to add a fun touch to your game or 3D model. The simple calculation shouldn't put much of a dent in your graphics performance either, although the pow() function is a little processing intensity. You could get around this by removing it entirely, but then you no longer have control over the spread of the light. It's up to you to decide based on your application and hardware limitations. Once again, any questions or comments, feel free to email me at dan@digitseven.com. And be sure to <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a>, which I'll use to keep you posted on new updates to the site. Enjoy!</p>
<p><a href="http://digitseven.com/Documents/RimLight.zip">DOWNLOAD Rim Lighting PROJECT HERE</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-rim-lighting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Texturing</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-texturing/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-texturing/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 19:34:06 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1792</guid>
		<description><![CDATA[by Daniel Greenheck
This tutorial will cover attaching an image (I'll be using the word texture from now on) to a model to give it a much more detailed look.  Texturing is an essential of creating a realistic scene because it  allows us to give objects very fine detail. Without textures, everything  in [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<div class="wp-caption alignnone" style="width: 561px"><img title="A simple box with a stone black texture" src="http://digitseven.com/images/texturedbox.png" alt="" width="551" height="520" /><p class="wp-caption-text">A simple box with a stone black texture</p></div>
<p>This tutorial will cover attaching an image (I'll be using the word <em>texture </em>from now on) to a model to give it a much more detailed look.  Texturing is an essential of creating a realistic scene because it  allows us to give objects very fine detail. Without textures, everything  in the scene would basically be one color, look very flat and just be  generally boring. The right textures can even give an object the  illusion of depth, further increasing the realism. The stone box above  looks like it has deep cracks in it between the blocks, but that's just  an illusion. The entire box is defined using eight vertices. To  geometrically represent those cracks, it would take thousands of  vertices, something that definitely isn't feasible.</p>
<p><span id="more-1792"></span><br />
So how do we  take a texture and apply it to an object? The whole process is quite  simple. If you remember back to the diffuse shader tutorial, we started  using the VertexPositionNormalTexture structure for our vertices. At the  time I told you to ignore the texture part but now we'll be making full  use of this! Following the normal data in the constructor of VertexPositionNormalTexture, it asks for a set of <strong>texture coordinates</strong>:  a Vector2 used to tell  how our shaders how the texture is attached to the model. What are  texture coordinates you ask?</p>
<blockquote>
<h3>An Explanation of Texture Coordinates</h3>
<p>Texture coordinates are very  simple concept. Take a look at this diagram below; it's a breakdown of  the stone box pictured above.</p>
<div><img src="http://digitseven.com/images/coordinatesdiagram.jpg" alt="" /></div>
<p>As I mentioned before, texture coordinates are a Vector2. The horizontal axis of  the image is assigned to the <em>U</em> component and the vertical <em>t</em>o  the<em> V </em>component. Each component represents the proportion of  distance from the origin along that axis. In simpler terms, the value of  U and V each normally range from 0.0 - 1.0, the origin being the  upper-left corner of the image.<br />
When we specify the texture  coordinates for a vertex, we're telling it what part of the texture  attaches there. Looking at the example I provided above, we'll take the  lower-left triangle on the front face. To attach the texture so it  covers the entire face, my texture coordinates would be as follows:</p>
<blockquote><p><em>Upper-Left Front Vertex</em>: The  origin of the image should attach directly to that point, so <strong>(0 , 0)</strong>.<br />
<em>Bottom-Left Front Vertex</em>: The  lower-left corner of the image should attach here, so<strong> (0 , 1)</strong>.<br />
<em>Bottom-Right  Front Vertex</em>: Following the same principle as the first two, <strong>(1 ,  1)</strong>.</p></blockquote>
<p>Just to keep this simple,  I'm using one's and zero's. If you wanted to use just the upper-left  quadrant of the image, (using the same triangle again) I would use these  texture coordinates:</p>
<blockquote><p><em>Upper-Left  Front Vertex</em>: The origin of the image should  attach directly to that point, so <strong>(0 , 0)</strong>.<br />
<em>Bottom-Left Front Vertex</em>: We're only going halfway down the V axis  this time<strong> (0 , .5)</strong>.<br />
<em>Bottom-Right Front Vertex</em>:  The middle of the image should attach here, so <strong>(.5 , .5)</strong>.</p></blockquote>
<p>Since we're only using half the image now, it would give a  stretching effect. Once you get your shader working properly,  experiment with adjust your texture coordinates to see what effects  different values give.</p></blockquote>
<p>The shader will then go through each triangle on the scene, the pixel shader interpolating the texture coordinates between all the vertices of each triangle. That's how you can specify only three attachment points on a triangle, but get the image spread across the entire surface. Once you get the texture coordinates for the pixel, it will sample the texture at those coordinates, returning the pixel color (which you can adjust by the amount of light that hits it, etc.) That's it! Let's take a look at the shader code.</p>
<h2>The All-Purpose Shader</h2>
<p>I've  added the texture code to the shader we've been building up over the  last few tutorials. If you scan the code, you'll  probably notice how <em>little </em>code I added. In fact I only added  about 4 lines of code to implement texturing, none of them being math-oriented either (thank  the heavens). Now we have a basic shader that can  handle ambient, diffuse and specular lighting while also allowing you to  add textures to your models.</p>
<pre class="brush: csharp; title: ;">
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor;
float AmbientIntensity;

float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;

float4 SpecularColor;
float SpecularIntensity;
float Shinniness;
float3 CameraPosition;

// Texturing variables
Texture ModelTexture;        // Our texture which will be mapped onto our object

// Pass coordinates to our texture sampler to get a color for a certain pixel
sampler TextureSampler = sampler_state {
    texture = &lt;ModelTexture&gt; ;
    magfilter = LINEAR;
    minfilter = LINEAR;
    mipfilter= LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;};

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float2 TexCoords : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
    float2 TexCoords :TEXCOORD2;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    output.Normal = mul( input.Normal, World );
    output.CameraView = normalize( CameraPosition - worldPosition );

    // Just pass the texture coordinates to the vertex shader output.
    // When they transfer to the pixel shader, they will be interpolated
    // per pixel.
    output.TexCoords = input.TexCoords;

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Sample our texture at the specified texture coordinates to get the texture color
    float4 texColor = tex2D( TextureSampler, input.TexCoords );

    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );
    float3 halfAngle = normalize( lightdir + input.CameraView );
    float specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseIntensity * DiffuseColor;
    float4 ambient = AmbientIntensity * AmbientColor;

    return texColor * ( diffuse + ambient + specular );
}

technique Texturing
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<h2>Changes to The Vertex In/Out Structures</h2>
<p>Nothing major happened here. All we did was add a <em>float2 </em>to each structure to store our texture coordinates. I've just assigned the next TEXCOORDS semantic that was available. The input structure will contain texture coordinates for the vertices and the output structure will contain the interpolated texture coordinates for the pixel shaders, which is what we want.</p>
<h2>Two New Variables</h2>
<pre class="brush: csharp; title: ;">
// Texturing variables
Texture ModelTexture;        // Our texture which will be mapped onto our object

// Pass coordinates to our texture sampler to get a color for a certain pixel
sampler TextureSampler = sampler_state {
    texture = &lt;ModelTexture&gt; ;
    magfilter = LINEAR;
    minfilter = LINEAR;
    mipfilter= LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;};
</pre>
<p>1. <strong>ModelTexture </strong>- This is where the texture is stored.  We call SetValue() on the XNA side with a reference to Texture or Texture2D to set the texture we want our  shader to sample.</p>
<p>2. <strong>TextureSampler </strong>-  This handy little device allows us to pass in a pair of texture  coordinates and get the color of the texture at that point. It may look  complicated to declare but it really isn't. There's a whole boatload of  arguments )separated by semicolons) you can specify for a <em>sampler </em>but  I've just chosen six here. The first is a reference to the texture we  want to sample, so we put <strong>ModelTexture </strong>between &lt;&gt;. The next  three are filters applied to the texture. If you want to learn what  they do, you'll have to do a little research on your own (Google!). The  next two, <strong>AddressU </strong>and <strong>AddressV</strong>, have several states:</p>
<ul>
<li><em>WRAP </em>- If the values exceed 1, the texture is repeated  along that axis. So if AddressU was set to WRAP and the U coordinate was  5, it would repeat 5 times along the U axis.</li>
<li><em>CLAMP </em>- The  values are clamped between 0 and 1. If they precede 0, they are set to  0. If they exceed 1, they are set to 1.</li>
<li><em>MIRROR </em>- Similar to WRAP, but each consecutive tile is a mirrored from  the last along the axis perpendicular to the mirrored axis.</li>
</ul>
<h2>Vertex Shader</h2>
<p>The only line I added here was passing the vertex shader coordinates to the output structure so they could be interpolated in the pixel shader.</p>
<h2>Pixel Shader</h2>
<p>Once in the pixel shader, we can finally sample our texture for what we need. By calling tex2D() on our texture sampler and the interpolated texture coordinates from our input data, we get back a float4 which represents the color of the texture at that pixel. Perfect! Now what to do with it?<br />
In the previous shaders, everytime I added a new lighting component, I would add it to the total sum. With texture color this is different. The texture color is independent of the light; it is an intrinsic property of the object we are working with. If our box is textured with a stone wall, it's going to be colored like a stone wall if the lights are on or off. By multiplying our texture color by the sum of the lighting components, we can get our desired effect of having a darker color when it's dark and a lighter color when it's bright.</p>
<h2>The XNA Side of Things</h2>
<p>There isn't a whole lot to do on the  XNA side to use our new shader. Make sure to reference to your new  shader and change the technique name to "Texturing" or whatever you chose. Since our shader now  needs a texture, you're also going to need to declare a Texture2D variable. In <em>the  LoadContent() </em>method, load whatever texture you please into the  texture variable from the content pipeline. Then in the main <em>Draw()</em> method of your game, set the value of <strong>ModelTexture </strong>to the Texture2D variable you declared  so the shader knows what texture to draw. You should now have a  textured model on the screen!</p>
<h2>Conclusion</h2>
<p>Congratulations! If you've followed the tutorials to this point, you've  created a shader that basically replicates the functionality of the BasicEffect class in XNA.  "What?! They already wrote this stuff?" Easy there. You may have  replicated some existing functionality, but you now have a superb  understanding of how shaders work ( Hopefully. Or you are just amazingly  confused at what I've been talking about this entire time which is a  very real possibility) and a fully tweakable shader.<br />
By adding  texturing to our all-purpose shader, you can now give an amazing amount  of detail to characters, buildings, cars, trees, weapons or whatever  else might be inhabiting your game world. Texturing gives objects the  illusion of depth and detail without defining extra geometry. If you  continue your shader education, you will find some amazing techniques  used to give the illusion of depth and detail such as bump mapping and  parallax mapping. And guess what? Both of those techniques use special  textures that are sampled in nearly the same way we did with this  shader.<br />
I will be covering more advanced shaders from now on, so  make sure you have the details in the tutorials up to this point down  pat. Feel free to experiment with the code we've written to get a firmer  grasp on what each part of it does. Try to write a shader to give your  model a unique effect not covered here. Good luck and happy programming!</p>
<p><strong>Download source: <a href="http://digitseven.com/Documents/Texturing.zip">Texturing.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-texturing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Specular Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 19:15:52 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1789</guid>
		<description><![CDATA[by Daniel Greenheck
What should I be familiar with before I go through this tutorial?
- The content discussed in the introduction, ambient and diffuse tutorials.
One Thing Before I Begin...
To keep things succinct, I will no longer explain or comment things explained in previous tutorials. Throughout these series of tutorials, I'm going to expect you've gone through [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p><strong><em>What should I be familiar with before I go through this tutorial?</em></strong><br />
- The content discussed in the <a href="http://www.sgtconker.com/2010/09/article-shaders-introduction/">introduction</a>, <a href="http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/">ambient</a> and <a href="http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/">diffuse </a>tutorials.</p>
<h2>One Thing Before I Begin...</h2>
<p>To keep things succinct, I will no longer explain or comment things explained in previous tutorials. Throughout these series of tutorials, I'm going to expect you've gone through the previous tutorials. No sense in beating a dead horse. So if you look at the variables section and only see the Specular variables, rest assured the others are still in the actual program. I just think it will be easier for you as a reader if I only present you with new information. That aside, let's begin!</p>
<h2>What is Specular Lighting?</h2>
<p>Specular lighting in one word: shiny. The world specular in itself  means a mirror-like surface, so you can imagine that anything that has  specular lighting is very reflective, causing it to have shiny  highlights. If you place a polished chrome ball under a direct light  source, you'll probably see a big shiny spot blinding you; this is the  specular highlight. Specular reflections  are caused by the reflection of the actual light source itself. If  the surface isn't flat however, it will warp the light and you'll  usually see it as a small dot of bright light or curved lines of light.  When you're out on a sunny day, look around at smooth, metallic objects  and notice their specular highlights. Try and determine how the light is  coming in and being reflected off the surface to your eye. The more you  understand about real-world lighting, the better you'll understand what  we're trying to replicate in our shaders.</p>
<div><img src="http://digitseven.com/images/595002557_8aa8f72677.jpg" alt="" /><br />
<span style="font-size: xx-small;">The perfect example of specular  lighting. Notice the highlight is really the reflection of the sun.</span></div>
<h2><span id="more-1789"></span></h2>
<h2>The Specular Shader</h2>
<p>As usual, I once again present you with the entire specular shader. If you skipped my intro to this article, which I can't blame you for, I'll remind you that I left out the commenting on anything non-specular to save space and make the presentation a little nicer. If you don't know what the other parts of the program do, go back and read the Ambient and Diffuse shaders.</p>
<pre class="brush: csharp; title: ;">
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor;
float AmbientIntensity;

float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;

// Specular Variables
float4 SpecularColor;
float SpecularIntensity;
float Shinniness;                // Sharpness the specular highlights. Higher number = sharper highlight
float3 CameraPosition;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

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

    // Get the vector from the camera to the vertex for the specular component by
    // subtracting the world position from the camera
    output.CameraView = normalize( CameraPosition - worldPosition );

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the half angle: the half the angle between our light direction and camera view
    float3 halfAngle = normalize( lightdir + input.CameraView );

    // Take the dot product between the normal of the pixel and the half angle. The closer the two
    // vectors are to pointing in the same direction, the higher the dot product. Take that to the [Shinniness]
    // power to make the highlight strong in the middle and fade out as you get towards the edges.
    float specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseIntensity * DiffuseColor;
    float4 ambient = AmbientIntensity * AmbientColor;

    return saturate( diffuse + ambient + specular );
}

technique Specular
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<p>There's four things of interest we've added to the program:</p>
<ol>
<li>Four new variables: <strong>SpecularColor</strong>,  <strong>SpecularIntensity</strong>, <strong>Shinniness </strong>and <strong>CameraPosition</strong>.</li>
<li>In the output  structure, we added a new <em>float3 </em>for CameraView.</li>
<li>In the vertex  shader, we calculate our <strong>CameraView </strong>by subtracting the <strong>WorldPosition </strong>of the vertex from our <strong>CameraPosition.</strong></li>
<li>The pixel shaders  does some calculations to calculate the specular component. They look  pretty confusing right now, but don't worry, we'll break them down.</li>
</ol>
<h2>New Specular Variables</h2>
<pre class="brush: csharp; title: ;">
float4 SpecularColor;
float SpecularIntensity;
float Shinniness;                // Sharpness the specular highlights. Higher number = sharper highlight
float3 CameraPosition;
</pre>
<p>The first two variables are the same as the Ambient and Diffuse variables of similar name: they adjust the color and intensity of the specular light, respectively. The next variable is brand new however: <strong>Shinniness</strong>. This is a floating point number that adjusts the size and sharpness of the specular light. If you have a higher value, you're going to get a very intense, small highlight. If you set it to a lower value, the specular highlight will be broader, but overall not as sharp. Play with different values to get the effect you want. The range of values you'll want to stay within is 10 and 2000, though you can really pick whatever you want.</p>
<p>The next variable is the current position of the camera in the scene, a.k.a. the "eye" you are looking through. Since the specular highlights you see depend on your angle with the object and the light source, we'll need to update this variable every frame. For example: If you walk around a freshly-waxed car, you'll notice the specular highlights on the body and windows don't stay in the same spot. Depending on your position, the sun will be reflected to your eye off different parts of the car and at different angles.</p>
<h2>Adding the CameraView to the Output Structure</h2>
<pre class="brush: csharp; title: ;">
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
};
</pre>
<p>We've added one new parameter to our <em>VertexShaderOutput</em>: CameraView. All we are passing here is a unit vector which represents the direction from the camera to the current vertex.</p>
<h2>Vertex Shader</h2>
<pre class="brush: csharp; title: ;">
VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

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

    // Get the vector from the camera to the vertex for the specular component by
    // subtracting the world position from the camera
    output.CameraView = normalize( CameraPosition - worldPosition );

    return output;
}
</pre>
<p>Compared to the diffuse shader, everything is the almost exactly the same. The only new thing we added is calculating the <strong>CameraView</strong>, which I just mentioned above. We just take the <strong>CameraPosition </strong>and subtract the position of the vertex in <em>world space</em>. Vector algebra determines that this gives the vector from the camera to the vertex. Then we normalize that to get a unit vector. Simple! We'll be using <strong>CameraView </strong>next...</p>
<h2>Pixel Shader</h2>
<pre class="brush: csharp; title: ;">
float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightDir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the half angle: the half the angle between our light direction and camera view
    float3 halfAngle = normalize( lightDir + input.CameraView );
    // Take the dot product between the normal of the pixel and the half angle. The closer the two
    // vectors are to pointing in the same direction, the higher the dot product. Take that to the [Shinniness]
    // power to make the highlight strong in the middle and fade out as you get towards the edges.
    float specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseIntensity * DiffuseColor;
    float4 ambient = AmbientIntensity * AmbientColor;

    return saturate( diffuse + ambient + specular );
}
</pre>
<div><img src="http://digitseven.com/images/specularlighting.png" alt="" /> <img src="http://digitseven.com/images/example.jpg" alt="" /></div>
<p>The  picture on the left is my cartoon depiction of what is going on. We have  an eyeball representing the camera position, the sun representing where the light is coming in from, and a little red box to act as our scene object. I've labeled each vector, all which you can  find in the pixel shader code. Take this time to locate all of them now  so you can follow along as we pick apart the code. The picture on the  right is what the eyeball in the cartoon would actually see.<br />
First, we stored the normalized <strong>DiffuseLightDirection</strong> in <strong>lightDir</strong>.  Anything but a unit vector will give us weird results. We follow that  by normalizing the <em>normal </em>of the current pixel (Remember we're  normalize in the pixel shader because we want the interpolated normal of  the pixel. If normalized in the vertex shader, it would still  interpolate is it went to the pixel shader and therefore wouldn't be a  normalized vector anymore.) and storing that in <strong>norm</strong>. Next, we  calculate the <strong>halfAngle </strong>by adding together <strong>lightDir </strong>and <strong>CameraView </strong>(vector from the camera to the box). If you look at the picture,  you can see <strong>halfAngle </strong>directly bisects the angle from <strong>lightDir</strong> to<strong> </strong><strong>CameraView</strong>. Okay. Now all our variables are defined.  Now we can finally calculate our specular component.<br />
If you  remember, in the diffuse component we took the dot product of the normal  and the light direction to find out how much light actually hit the  surface. The specular light uses the same concept, except it now also  depends on the position of the camera (or "eye"). Instead of taking the  dot product between the normal and the light direction, we're going to  take the dot product of normal and the half angle. Why? Physics break!</p>
<blockquote>
<h3>A Brief Digression on Optics</h3>
<p>If you really want to understand how shaders  work, a very thorough understanding of optical properties is an  absolute must. Knowing the real-world phenomena we are trying to  simulate and how they physically work gives you a much better idea of  what we're trying to accomplish. I'll give you a little optics  background so you can understand what's going on in this tutorial.  However, I would highly suggest looking at more sources to further your  understanding.<br />
<em><strong>When light strikes a surface at a certain  vector, called the angle of incidence, it bounces off the surface,  reflecting across the normal of the point on the surface it hits.</strong></em> If the normals of a surface are all pointing in the <em>same </em>direction  (think mirror), the reflected light will all be reflected at the same  angle, so the light rays will still be parallel to eachother. This keeps  the image intact when it gets reflected back to your eye. If the  normals of the surface are all pointing in <em>different </em>directions  (think rough boulder), the reflected light is scattered in all different  directions, some light rays even bouncing back towards the light  source. The rays are <span style="text-decoration: underline;">no longer parallel to eachother</span>, so  different parts of the image are shooting off in all different  directions. This is why you don't see a reflected image in a boulder  like you do in a mirror. The shinnier the surface, the less scattering  and the closer you get to a mirror. I've provided a picture below that  demonstrates what I've just explained.</p>
<div><img src="http://digitseven.com/images/optics.png" alt="" /></div>
<p>The <strong>Shinniness </strong>variable helps  us define how smooth or rough a surface is. The rougher the surface, the  smaller the value. You'll see why in a minute. In the cartoon diagram  with the red box, the light travels from the sun, reflects across the  normal of the pixel and makes it to our eye. However, our eye isn't  exactly at the receiving end of the reflected ray; it's slightly above.  Yet in the 3D rendering we can see it still gets light. Why is this?  Because in that picture, the box isn't perfectly smooth, so we can  assume that there will be some scattering to the eye. It's really all  just guess and check if you think about it. Comforting isn't it?</p></blockquote>
<p>Now that we know some laws of optics, we can start where we left off. We  take the dot product of <strong>norm </strong>and <strong>halfAngle </strong>to see how  much direct light the eye will get. The larger the angle between the  two, the further away our eye is from the "predicted" path of the  reflected rays; therefore we will get less specular/reflective light. We  take the result of that and take it to the <strong>Shinniness </strong>power. If  you think about an exponential graph, the higher the exponent, the  quicker a number below 1 goes to zero. This is a way to simulate how  rough surfaces can scatter light more than smooth surfaces. A smaller  power, a rougher surface, more scattering. A higher power, a smoother  surface, less scattering. We multiply that result by <strong>SpecularColor </strong>and  <strong>SpecularIntensity </strong>like our other light types and voila! We now  have specular light. We just add the specular component to our final sum  at the end of the pixel shader and our model should now be specularly  lit.</p>
<p>If you want to know how to set the variables from XNA,  be sure to check out the <strong>Diffuse </strong>or <strong>Ambient </strong>light  tutorial.</p>
<h2>Conclusion</h2>
<p>Specular lighting is a step towards the more complicated aspects of  programming shaders. By adding it into your 3D application, you can see  it definitely adds a lot of realism. Once you start getting into  advanced lighting techniques, you really need to know your stuff:  vectors, optics, matrix multiplication, etc. etc. I'll put up some  resources on optics on the <a href="http://digitseven.com/links.aspx">Links</a> page if you want to learn a bit more. There's already some links for  matrices. As these tutorials get more complex, I'll probably be making a  lot more mistakes so be sure to send me an email at <strong>dan@digitseven.com</strong>.  And of course, if you have any questions about anything I've covered,  please email me and I'll do my best to help you out. Also, make sure you <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> on the home page to stay updated with my latest posts Enjoy!</p>
<p><strong>Download the source: <a href="http://digitseven.com/Documents/SpecularLight.zip">SpecularLighting.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Diffuse Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 19:04:11 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1785</guid>
		<description><![CDATA[by Daniel Greenheck
What should I be familiar with before I go through this tutorial?
- The content discussed in the introduction and ambient shader tutorials.
- A simple knowledge of vectors, matrices and dot products (click on the links for Wiki articles) will REALLY help you understand  some of the light calculations going on. although I'll [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p>What should I be familiar with before I go through this tutorial?<br />
- The content discussed in the <a href="http://www.sgtconker.com/2010/09/article-shaders-introduction/">introduction</a> and <a href="http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/">ambient</a> shader tutorials.<br />
- A simple knowledge of vectors, <a href="http://en.wikipedia.org/wiki/Matrix_%28mathematics%29">matrices</a> and <a href="http://en.wikipedia.org/wiki/Dot_product" target="_blank">dot products</a> (click on the links for Wiki articles) will REALLY help you understand  some of the light calculations going on. although I'll do my best to  explain those topics in this tutorial.</p>
<h2>What is Diffuse Lighting?</h2>
<p>Diffuse lighting can best be described as directional light. There are three types of diffuse lighting: directional, point light and spotlight. I have a picture of each below in respective order. Directional light comes down at the same angle no matter where you are standing; the light has no position, just direction. Point light is like a light bulb, it all emanates  from a single point equally in all directions. A spot light is like an oriented floodlight or a flashlight. Diffuse light also creates shadows, but that's a much more advanced topic we won't dive in to until later.</p>
<p><img class="alignnone" title="http://digitseven.com/images/directional.jpg" src="http://digitseven.com/images/directional.jpg" alt="" width="479" height="362" /></p>
<p><span id="more-1785"></span></p>
<p><img class="alignnone" title="Point" src="http://digitseven.com/images/point.jpg" alt="" width="500" height="333" /></p>
<p><img class="alignnone" title="spot" src="http://digitseven.com/images/point_spotlight_dynamic.jpg" alt="" width="640" height="480" /></p>
<h2>The Diffuse Shader</h2>
<p>Once again, here's the entire diffuse shader for you to look at. You can probably notice it has all the same elements of the ambient shader, along with a few extra parts.</p>
<pre class="brush: csharp; title: ;">
// Matrices
float4x4 World;
float4x4 View;
float4x4 Projection;

// Ambient Variables
float4 AmbientColor;
float AmbientIntensity;

// Diffuse Variables
float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD1;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    // Transform our position by the matricies
    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    // Transform the normal from model space to world space
    output.Normal = normalize( mul( input.Normal, World ) );

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Determine the diffuse component by finding the angle between the light and the normal.
    // The smaller the angle between the normal and the light direction, the closer the dot
    // product will be to 1, and the brighter the pixel will be.
    float4 diffuse = dot( DiffuseLightDirection, input.Normal ) * DiffuseIntensity * DiffuseColor;

    // Calculate our ambient component
    float4 ambient = AmbientIntensity * AmbientColor;

    // Return the total light component as a combination of the diffuse and ambient.
    // Saturate it to keep the color between 0 and 1.
    return saturate( diffuse + ambient );
}

technique Diffuse
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        // We upgraded to pixel shader 2.0 so we can used more advanced commands
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<p>So what's the same?</p>
<ol>
<li><span style="text-decoration: underline;">Variables</span>: All three      matrices (<strong>World</strong>, <strong>View</strong>, <strong>Projection</strong>), <strong>AmbientColor </strong>and      <strong>AmbientIntensity </strong>are back.</li>
<li><span style="text-decoration: underline;">Structures</span>: Position      makes an appearance once again.</li>
<li><span style="text-decoration: underline;">Vertex Shader</span>: The      vertices are still transformed using the <strong>World</strong>, <strong>View </strong>and  <strong>Projection </strong>matrices.</li>
<li><span style="text-decoration: underline;">Pixel  Shader</span>: The      ambient lighting component is still calculated.</li>
</ol>
<p>Now, let's take a  look at what's new.</p>
<ol>
<li>We have three new variables for our diffuse light: <strong>DiffuseColor</strong>,  <strong>DiffuseIntensity</strong>, <strong>DiffuseLightDirection</strong>. Direction is the  only new concept here.</li>
<li>A <em>float3 </em>called  Normal has been added to both the input and output structures for the  vertex shader.</li>
<li>In our vertex shader, we do  a transformation on the normal from <em>VertexShaderInput </em>and pass  that on to the pixel shader.</li>
<li>In our pixel  shader, we calculate the diffuse component of the light.</li>
<li>We changed the pixel shader version from 1_1 to 2_0 to allow  us to do more advanced features in the pixel shader (i.e. normalize a  vector).</li>
</ol>
<p>Let's take a look at each of those  additions in detail. First we need to take a little side step to talk  about normals...</p>
<h2>Juat a Normal Kind of Light</h2>
<p>When we did ambient light, it didn't  matter where the light was coming from or how the light hit a certain  face. We just assumed each face was hit by the same amount of light,  giving the effect of everything being the same color. With diffuse  lighting, however, we now have a light coming in at a specific  direction, so each face isn't going to get hit by the same amount of  light. Imagine placing a small object by your desk lamp (and if you  don't have one of those, imagine that too). You'd notice right away that  the side facing the light gets more light than the side facing away,  resulting in a brighter color. This is because the <strong>normal</strong> of the  face aimed towards the light is pointed more directly at the light  source. A normal is a pretty simple concept. Here's a 3D model with the  normals shown as red rays coming out of the faces.<br />
<img src="http://digitseven.com/images/boxnormals.jpg" alt="" /><br />
Each  of those rays is <em>orthogonal </em>to the face it comes out of (fancy  term for perpendicular.) Our model uses normals like these and compares  it with the light direction to see how much light the face should get.  If a normal is pointing either perpendicular or completely away from the  light source, there's not a chance even a ray of light will directly  hit the face. We'll get back to normals later. All you  need to know is <span style="text-decoration: underline;">normals are used for calculating how much light a  face should get.</span> Let's get back into our shader code now.</p>
<h2>Variable Declaration</h2>
<pre class="brush: csharp; title: ;">
// Matrices
float4x4 World;
float4x4 View;
float4x4 Projection;

// Ambient Variables
float4 AmbientColor;
float AmbientIntensity;

// Diffuse Variables
float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;
</pre>
<p>The matrices and ambient variables  we covered in the last tutorial haven't changed at all, so I won't go  over those. However, we've added three new variables for our  diffuse lighting. The first two- <strong>DiffuseColor </strong>and <strong>DiffuseIntensity</strong>-  are analogs to <strong>AmbientColor </strong>and <strong>AmbientIntensity</strong>. They  control the color and brightness our diffuse light, respectively. Our  next variable, however, is brand spankin' new: <strong>DiffuseLightDirection</strong>.  From the name you can probably construe it defines the direction our  light will shine down at. And that's exactly what it is. There's one  peculiarity you should know about defining light direction though:<em><strong> </strong>the light shines down in the opposite direction you define it.</em> So if you want your light to shine straight down on your object,  naturally you would think to assign float3(0, -1, 0) to your <strong>DiffuseLightDirection</strong>.  But nope, that will cause the light to shine straight up.</p>
<h2>The Vertex Shader Input and Output Structures</h2>
<pre class="brush: csharp; title: ;">
struct VertexShaderInput    // Input for the vertex shader
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput    // Output for the vertex shader
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
};
</pre>
<p>Since we now know that we need normals from  our model for our shader, I went ahead and added a <em>float3 </em>(equivalent  of a Vector3 in XNA) to our <em>VertexShaderInput </em>structure to  represent the normal for the vertex. One problem you probably noticed is  that the normals I described above were for <strong>surfaces</strong> not <strong>vertices.</strong> Well this isn't a problem at all! To find the vertex normal, you simply  average the normals of all the faces that that use that vertex. I  described the actual code below when I get into the XNA part, so don't  worry. The normal parameter was also added to the <em>VertexShaderOutput</em>,  but we're going to be doing some work on it in the vertex shader so it  isn't the same as the normal we pass in through <em>VertexShaderInput</em>.  We'll look at the vertex shader next to see how we're actually  modifying the normal.</p>
<h2>Vertex Shader</h2>
<pre class="brush: csharp; title: ;">
VertexShaderOutput VertexShader( VertexShaderInput input )
{
    // Initialize our vertex shader output
    VertexShaderOutput output;

    // Transform our position by the matricies
    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    // Transform the normal from model space to world space
    output.Normal = normalize( mul( input.Normal, World ) );

    return output;
}
</pre>
<p>You'll notice there's a lot of familiar code here already. The transformations  on the vertex position are exactly the same as they were in the ambient  shader. The only new line we added takes the input normal, transforms  it by the <strong>World </strong>matrix and normalizes the result. Let's break  that down... Inside the parentheses, we take the vertex normal we passed  in and multiply it with the <strong>World </strong>matrix. We do this for the  same reason we multiply our position with the <strong>World </strong>matrix: our  normal is defined in <em>model space</em> (relative to the model origin)  and we need to get it into <em>world space</em>, since that's where our  light direction is defined. Our model could be rotated and translated  and all sorts of stuff- which is all taken care of in the <strong>World </strong>matrix-  so we need to apply those transformations to the normal too. After we  get our normal in <em>world space</em>, we normalize it. Don't confuse  "normal" with "normalize" either. A "normal" defines which way a face or  vertex is pointing. "Normalizing" a vector makes it <em>unit length</em>,  or have a length of 1. Unit vectors are used to specify direction  without magnitude. Two normal vectors pointing in the same direction  with different magnitudes would somehow mean that one face is pointing  in a direction with more force than the other, which really makes no  sense at all. After calculating the output normal, we now have  everything we need to calculate diffuse light in our pixel shader.</p>
<h2>Pixel Shader</h2>
<pre class="brush: csharp; title: ;">
float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our light direction
    float3 normLightDirection = normalize( DiffuseLightDirection );

    // Determine the diffuse component by finding the angle between the light and the normal.
    // The smaller the angle between the normal and the light direction, the closer the dot
    // product will be to 1, and the brighter the pixel will be.
    float4 diffuse = dot( normLightDirection, input.Normal ) * DiffuseIntensity * DiffuseColor;

    // Calculate our ambient component like we did with the ambient shader.
    float4 ambient = AmbientIntensity * AmbientColor;

    // Return the total light component as a combination of the diffuse and ambient.
    // Saturate it to keep the color within 1.
    return saturate( diffuse + ambient );
}
</pre>
<p>We've finally made it to the last step of the shader! Once again, we've copied over a lot of stuff  from the ambient lighting pixel shader. In fact, we've copied all of it.  We've also added two things: normalizing our light direction at the  pixel-shader-level forThe only thing we've added is the calculation of  our diffuse component. Since we want per-pixel diffuse lighting, we've  put the calculation for the diffuse component in the pixel shader. To  calculate how much light the pixel gets from our diffuse light, we take  the dot product of the diffuse light direction with the transformed  vertex normal and multiply it with <strong>DiffuseIntensity </strong>and <strong>DiffuseColor</strong>.  Wow, that's a mouthful! First, you might be wondering what a dot  product is. Read this little section first. If you already know what a  dot product is, feel free to skip it.</p>
<blockquote>
<h3>A brief digression on the Dot Product</h3>
<p>The <strong>dot  product</strong> is something we haven't come across yet. What it does is  compare the angle between two vectors and returns a <em>float.</em> If the  vectors are both <em>unit length</em>, you'll get a result between -1 and  1. If they aren't, you'll get a wildly varying value that you really  can't do anything with. A dot product of 20 could mean a billion things.  Now you know why we normalized our light direction and vertex normal.</p>
<p>If Vector1 and Vector2...</p>
<blockquote><p>- are pointing in the exact  same direction then <strong>dot( V1, V2 ) = 1</strong><br />
- are perpendicular to  each other then<strong> dot( V1, V2 ) = 0</strong><br />
- are pointing in exact  opposite directions then <strong>dot( V1, V2 ) = -1</strong></p></blockquote>
</blockquote>
<blockquote><p>Those are just the exact cases. Everything in between will vary  depending on where it's pointing. The closer they are to pointing in the  same direction, the closer to 1. The opposite holds with pointing in  the opposite direction. If you're confused, check out the Links section  on the navigation bar for more information on dot products.</p></blockquote>
<p>Now that we have dot products out of the way, we can finally apply it to our diffuse  calculation. When our normal is pointing in the opposite direction of  the <strong>DiffuseLightDirection </strong>(remember that our light direction is  defined opposite of what you think it should be), our dot product will  be 1. Multiply that with <strong>DiffuseColor </strong>and <strong>DiffuseIntensity </strong>and  we'll end up with our maximum possible value for the diffuse component.  If the normal and light direction are perpendicular, the dot product  will be zero and we'll get no light. This makes sense since a side  perpendicular to a light source isn't going to get hit by light rays.<br />
Phew! Now that we finally have our diffuse and ambient components, all  we do is add them together. Before we return the sum however, we want to  put apply the saturate() function. This caps any component of our pixel  color between 0 and 1. If the dot product was negative, we'd have  negative color values which would throw an error.</p>
<h2>Adding Normals to Our Models</h2>
<p>The biggest change we need on the XNA side is adding our normal  data to ou vertices. For the ambient shader I used the VertexPositionColor  structure for storing my vertices. Unfortunately, this doesn't have  anywhere to store normal information. So I've upgraded the vertices on  my box to VertexPositionNormalTexture,  leaving the texture coordinates blank for now. Remember that shaders  don't care if there's extra information there; they just take what they  need and move on. I'll be covering a texture shader within the next few  tutorials so let's go ahead and use that structure. Now, for calculating  the normals. This can vary greatly depending on what you have: a list  of verticies, a list of indexed vertices, a model. I won't cover the  first case and normally any model you find will already have the normals  in it, so I'm going to give a brief overview of indexed vertices  defined in the <strong>TriangleList </strong>format. I apologize if you defined  your verticies in a different fashion, but don't get too upset. A quick  check over at the <a href="http://forums.xna.com/forums/">XNA Forums</a> or a Google search should help you out with that. Here's a step-by-step  guide on how to calculate normals for indexed vertices which use the <strong>TriangleList </strong>method.</p>
<ol>
<li>Create you vertices and indices as you  normally would.</li>
<li>Loop through your indices <strong>three </strong>at a  time. Since your indicies are defined using a <strong>TriangleList</strong>, you  know each three consecutive indices represent a triangle in your model.</li>
<li>Get  the three vertices from I1, I2 and I3 and name them V1, V2 and V3.</li>
<li>Create  two Vector3's: <strong>VectorA </strong>= <em>V2.Position - V1.Position</em> and <strong>VectorB </strong>= <em>V3.Position - V1.Position.</em></li>
<li>Take the cross product  of <strong>VectorB </strong>with <strong>VectorA </strong>(order matters) and normalize that  result. This will give you your face normal.</li>
<li>Now go back and  add that face normal to V1.Normal, V2.Normal and V3.Normal.</li>
<li>Repeat  for every three indices and voila, each vertex now has it's vertex  normal.</li>
</ol>
<p>By adding the face normal to each vertex that  made up the face, we've effectively averaged together all the face  normals for each vertex, which is the definition of a vertex normal.Once you get that implemented, our models should now  have all the necessary information to draw them with diffuse light.</p>
<h2>Setting Our Shader Variables</h2>
<pre class="brush: csharp; title: ;">

    // Set the parameters of the shader

    diffuseEffect.Parameters[ &quot;World&quot; ].SetValue( Matrix.CreateRotationY( (float)gameTime.TotalGameTime.TotalSeconds )  );

    diffuseEffect.Parameters[ &quot;View&quot; ].SetValue( viewMatrix );

    diffuseEffect.Parameters[ &quot;Projection&quot; ].SetValue( projectionMatrix );

    diffuseEffect.Parameters[ &quot;AmbientColor&quot; ].SetValue( new Vector4( 1, 1, 1, 1 ) );

    diffuseEffect.Parameters[ &quot;AmbientIntensity&quot; ].SetValue( .3f );

    diffuseEffect.Parameters[ &quot;DiffuseColor&quot; ].SetValue( new Vector4( 0, 1, 0, 1 ) );

    diffuseEffect.Parameters[ &quot;DiffuseIntensity&quot; ].SetValue( .8f );
    diffuseEffect.Parameters[ &quot;DiffuseLightDirection&quot; ].SetValue( new Vector3( .7f, 1f, -.8f ) );
</pre>
<p>Nothing has really changed here. We've just tacked on three more SetValue()'s for our three diffuse  variables. Set your <strong>DiffuseColor, </strong><strong>DiffuseIntensity </strong>and <strong>DiffuseLightDirection</strong> (we normalize it here to avoid the calculation in the shader. And  remember, it's opposite of the direction the light shines at!) and  you're almost good to go!</p>
<h2>Drawing Vertices With Our Diffuse Effect</h2>
<p>Once again, not much has changed here. Make sure you change your  VertexDeclaration and DrawUserPrimitives call to VertexPositionNormalTexture so the graphics  card knows we've added normal data. If you skip that, you'll probably  end up with nothing but black blob. Everything should be ready to go  now... so go ahead, hit F5 and watch that cube spin in it's shaded,  rainbowed glory! You should get something similar to this video:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/s1nqiD0nDCY?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/s1nqiD0nDCY?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>Conclusion</h2>
<p>So there we go, another shader down.  By now I hope you're starting to get a feel for how these shaders work  and what goes into them. You should start seeing a pattern as you go  along: vertex shaders transforming data, pixel shaders using the  transformed data to calculate colors. Every vertex shader and pixel  shader you come across is going to work like that for the most part.  I'll be covering specular light in the next tutorial, which will give  you a nice shiny effect on your objects. I might have to ditch the cube  for a sphere... I don't think he'll take kindly to that news... Anyway,  best of luck to you in your programming! If you happen to catch any  errors or need any clarifications, be sure to send me an email at <strong>dan@digitseven.com</strong>,  I'd be more than happy to help. Make sure to <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> to stay updated with my latest tutorials and code uploads!</p>
<p><strong>Download the source: <a href="http://digitseven.com/Documents/DiffuseLight.zip">DiffuseLighting.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Ambient Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 21:21:26 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1780</guid>
		<description><![CDATA[by Daniel Greenheck
Since these are shader tutorials and not XNA tutorials, I'm guessing you already have a basic understanding of these topic
- How to draw a simple model or some vertices in XNA.
- How to add files to the Content Pipeline.
- The content in my Shader Introduction.
A few words to start...
Before someone makes the wise-crack [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p>Since these are shader tutorials and not XNA tutorials, I'm guessing you already have a basic understanding of these topic<br />
- How to draw a simple model or some vertices in XNA.<br />
- How to add files to the Content Pipeline.<br />
- The content in my <a href="http://www.sgtconker.com/2010/09/article-shaders-introduction/">Shader Introduction</a>.</p>
<h2>A few words to start...</h2>
<p>Before someone makes the wise-crack  that ambient lighting is already taken care of in the BasicEffect class  in XNA, I'm going to tell you: ambient lighting is already taken care  of in the <em>BasicEffect </em>class in XNA. The reason I'm giving this  tutorial is because these basic shaders lay the foundation for more  advanced and complex shaders. If you can understand how simple shaders  work, it will help you out <em>profoundly </em>when dealing with complex  topics like bump mapping and projective texturing later on. I highly  recommend avoiding the BasicEffect class if you are completely new to  shaders. Instead focusing on building your foundation of shader  knowledge; it's completely necessary if you ever plan on making anything  beyond a game that looks like Mario 64.<br />
If you don't plan on  using advanced shaders or you already know the basics of HLSL, <strong><a href="http://msdn.microsoft.com/en-us/library/bb203926.aspx">here’s a  tutorial</a></strong> on how to use the BasicEffect class (which is also on  my links page).</p>
<p>Now, for those of you who are still with me! Ambient lighting is  about as simple as it gets, so this will be a good place to start if you  are completely unfamiliar with HLSL. A scene with only ambient lighting  by itself looks like a polar bear in a snow storm, so if you want a  little more detailed effect, I would skip to the diffuse lighting  tutorial. However, in later tutorials, I'll be focusing mainly on the  actual code inside the vertex and pixel shaders; I'm going to assume  you've already read this tutorial and have a basic understanding of  shaders. So consider yourself warned!</p>
<p><span id="more-1780"></span></p>
<h2>What is Ambient Lighting?</h2>
<p>Well I see I’ve blabbed on without even mentioning what we  are programming! Ambient lighting can best be described by going  outside on a cloudy day. If you look around, there is really no direct  light source: you don’t have the sun shining overhead, creating shadows  with every object it hits. In fact, if you look around, there probably  aren’t many shadows to be found (unless there is some artificial light,  then that’s just cheating). Ambient light is the result of the suns rays  bouncing of so many different surfaces that they light parts of the  world that aren’t even directly lit. Go outside on a sunny day sometime and see for yourself. Notice how areas that aren’t being lit by direct light aren’t completely dark. I also like to think of  ambient lighting as <em>global lighting</em>: it manages to light up every  part of the world, the same amount, no matter where it is. An object  lit by only ambient light will look something like this:</p>
<div><img src="http://digitseven.com/images/box1.png" alt="" /></div>
<p>Blah! It's boring and there's no  definition to any corners or edges. Although almost useless by itself,  ambient lighting is a necessary part of any scene to give it some static  light. Now, on to the fun stuff!</p>
<h2>The Ambient Lighting Shader</h2>
<p>I'm just going to show you the entire Ambient Lighting shader right away so you can glance over it. As we go along, I'll explain each part of it, piece-by-piece. So let's get started!</p>
<pre class="brush: plain; title: ;">
    float4x4 World;             // World matrix
    float4x4 View;              // View matrix
    float4x4 Projection;        // Projection matrix

    float4 AmbientColor = float4( 1, 1, 1, 1 );     // Ambient lighting color
    float AmbientIntensity = 0.8;                   // How bright the ambient light is ( 0.0 - 1.0, 0 = No light, 1 = Full Light )

    struct VertexShaderInput    // Input data for vertex shader
    {
        float4 Position : POSITION0;    // Pass in just the position of the vertex to the vertex shader
    };

    struct VertexShaderOutput   // Output data for vertex shader/input data for pixel shader
    {
        float4 Position : POSITION0;    // We'll be passing our transformed position to the pixel shader
    };

    // Vertex Shader

    VertexShaderOutput VertexShaderFunction( VertexShaderInput input )
    {
        VertexShaderOutput output;

        float4 worldPosition = mul( input.Position, World );
        float4 viewPosition = mul( worldPosition, View );
        output.Position = mul( viewPosition, Projection );

        return output;
    }

    // Pixel Shader

    float4 PixelShaderFunction( VertexShaderOutput input ) : COLOR0
    {
        return ( AmbientColor * AmbientIntensity );
    }

    technique Ambient
    {
        pass Pass0
        {
            VertexShader = compile vs_1_1 VertexShaderFunction();
            PixelShader = compile ps_1_1 PixelShaderFunction();
        }
    }
</pre>
<p>As you can tell right  away, there isn’t a whole lot going on here. Here's what we can see in  this shader:</p>
<ol>
<li>The global variabes are  defined at the top.</li>
<li>The input and output  structures for our vertex shader are defined.</li>
<li>The vertex  shader function is right below that.</li>
<li>Followed by the  pixel shader.</li>
<li>And our Ambient technique with a single pass  finishes up the shader.</li>
</ol>
<h2>Variable Declaration</h2>
<pre class="brush: plain; title: ;">
    float4x4 World;                                // World matrix
    float4x4 View;                                 // View matrix
    float4x4 Projection;                           // Projection matrix

    float4 AmbientColor = float4( 1, 1, 1, 1 );    // Ambient lighting color
    float AmbientIntensity = 0.8;                  // How bright the ambient light is ( 0.0 - 1.0, 0 = No light, 1 = Full Light )
</pre>
<p>There are five different global variables needed to make an ambient light shader: Our <strong>World</strong>, <strong>View </strong>and <strong>Projection </strong>matrices along with our <strong>AmbientColor </strong>and  <strong>AmbientIntensity</strong>. The first three will make their appearance in practically every shader you will create. Those three <em>float4x4</em> variables- <strong>World, View </strong>and <strong>Projection- </strong>are placeholders for your matrices. I’m not going to completely dive into  the topic of matrices here since there is a lot of advanced math behind them which  is beyond the scope and focus of this tutorial. If you want to know the  actual mathematics behind them, I would suggest just the always informative <strong><a href="http://en.wikipedia.org/wiki/Matrix_%28mathematics%29">Wikipedia</a></strong> or this link<strong>: </strong><a href="http://www.ziggyware.com/readarticle.php?article_id=100"><strong>Introduction  to Matrices</strong></a>. All you need to know for now is that the matrices  help XNA transform your model from its 3D coordinates you define it in to 2D screen space for your viewing pleasure.</p>
<p>The next two  variables are unique to the ambient shader. <strong>AmbientColor</strong> is pretty self-explanatory:  this stores the color of your ambient light. We use <em>float4</em>, each  component of the float representing a component of our ambient color:  red, green, blue and alpha (a fancy term for transparency). If you look above, I set the ambient color like this:</p>
<pre class="brush: plain; title: ;">
    float4 AmbientColor = float4( 1, 1, 1, 1 );     // Ambient lighting color
</pre>
<p>Unlike in XNA or  C#, you don’t need to specify the new keyword  when you initialize an array. You just have <em>float </em>followed by a comma-delimited list of values in parenthesis. Make  sure the number of items matches the dimensions of the <em>float</em>, or you’ll  get a compile error. You can have <em>float, float2, float3</em>, but no more values  than that. Anything beyond a <em>float4 </em>doesn't have a lot of use in a  shader.</p>
<p><strong>AmbientIntensity: </strong>This  is just a floating point from 0 to 1 which is a proportion of how much  of the <strong>AmbientColor </strong>you want to apply to the object.</p>
<h2>The Vertex Shader Input and Output Structures</h2>
<pre class="brush: plain; title: ;">
struct VertexShaderInput
{
    float4 Position : POSITION0;    // Pass in just the position of the vertex to the vertex shader
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;    // We'll be passing our transformed position to the pixel shader
};
</pre>
<p>Our <em>VertexShaderInput </em>and <em>VertexShaderOutput</em> are extremely simple, so this is a good time to introduce a lot of  idiosyncrasies about shader structures. Let's look at format of the <em>VertexShaderInput</em> structure first. You see it starts with the <em>struct</em> identifier,  followed by the name of the structure. Then we have the infamous curly  brackets followed by a list of parameters the structure holds. This one  only requires a <em>float4 </em>for position. Simple enough.<br />
Now  what's this crazy business hanging off the end of our parameter?<strong> :  POSITION0</strong>? What the heck is this?! This, my friend, is called a  semantic. They tell the graphics card what type of data we're passing in  our shaders. <strong><a href="http://msdn.microsoft.com/en-us/library/bb509647%28VS.85%29.aspx">Here's  a reference list of all the semantics available in HLSL</a></strong> (As you  can see from the link, there's a list for vertex shaders and pixel  shaders; they are two different sets. Keep that in mind.) For position,  you would use the <strong>POSITION[n] </strong>semantic, for color, you would use  the <strong>COLOR[n]</strong> semantic, and so on. You can also see there is a  little number after the semantic. This allows you to pass in more than  one type of the same variable. For instance, if I wanted to pass a set  of texture coordinates and a set of coordinates for my bump map, I would  use the semantics <strong>TEXCOORD0, TEXCOORD1.</strong> They may seem a little  confusing now, but don't worry; in future tutorials you'll see them used  a little more extensively.</p>
<h3>A Note About Semantics</h3>
<blockquote><p>It doesn't matter if you pass in vertices with the type VertexPositionColor, VertexPositionNormalTextured, or even a custom vertex format. The graphics card will always know where the position is stored in your vertex data. When you set the VertexDeclaration of the GraphicsDevice, the VertexElements member (of your vertex structure) has all the data saying which parts of the vertex structure are mapped to which semantics. Every piece of data has a little tag on it defining what it is to keep things nice and organized.</p></blockquote>
<p>The vertex shader output is exactly the  same as <em>VertexShaderInput</em>, so we'll leave it at that. We'll be  modifying our position we pass in from <em>VertexShaderInput</em> and  passing that on to <em>VertexShaderOutput,</em> so it isn't completely  useless. As I mentioned in my shader introduction, remember that you  don't need these structures for your shader to work. You could change  your vertex and pixel shader to this:</p>
<pre class="brush: csharp; title: ;">
float4 VertexShaderFunction( float4 position : POSITION0 ) : POSITION0
{
    float4 worldPosition = mul( position, World );
    float4 viewPosition = mul( worldPosition, View );
    return mul( viewPosition, Projection );
}

float4 PixelShaderFunction( float4 position : POSITION0 ) : COLOR0
{
    return ( AmbientColor * AmbientIntensity );
}
</pre>
<p>and it would work exactly the same as if you used the structures. In this case I would almost prefer the above format over the structures since it is more succinct, but I like to use structures all the time for consistency's sake. It's up to you how you want to handle it. Okay, on to the brains of our shader.</p>
<h2>Vertex Shader</h2>
<pre class="brush: csharp; title: ;">
    // Vertex Shader
    VertexShaderOutput VertexShaderFunction( VertexShaderInput input )
    {
        VertexShaderOutput output;

        float4 worldPosition = mul( input.Position, World );
        float4 viewPosition = mul( worldPosition, View );
        output.Position = mul( viewPosition, Projection );

        return output;
    }
</pre>
<p>Here we have our simple vertex  shader program. Let's look at it step-by-step. First, we declare an  instance of <em>VertexShaderOutput </em>so the vertex shader can return  some data. Remember this structure holds only position, so that's what  the entirety of this vertex shader is going to work with. Next, there  are three lines that are all related to each other: The first, takes the  position based in to our vertex shader which is defined in 3D space and  transforms it into <em>world space</em>. Now we have our world position.  Next, we transform our world position by the view matrix to get in <em>camera  space</em>. Finally, we transform our <em>camera space</em> position into  screen space with the projection matrix.<br />
Let's take a step back  and look at what's really going on with the first line. What is a world  matrix used for? A world matrix takes the vertices and converts them  from <em>object space</em> into <em>world space</em>. What does this mean?  Let's say you have a model of a box, where each side is 2 units long. So  each corner will be defined as 1 unit away from the axes of the object.  The front upper-right corner will be (1,1,1), the back upper-left  corner will be (-1,1,-1) and so on. These coordinates are defined in <em>object  space</em>, relative to the box. Let's say our cube is actually  positioned at (5,5,5) in our world. So really, the front upper-right  corner will be at (6,6,6) in <em>world space</em>, the back lower-left  corner will be (4,6,4). Here's a 2D representation of the concept:</p>
<div><img src="http://digitseven.com/images/worldvsobjectspace.jpg" alt="" /></div>
<p>Since all we needed to do  was transform our 3D position into<em> screen space</em>, we're all ready  for the pixel shader!</p>
<h2>Pixel Shader</h2>
<pre class="brush: csharp; title: ;">
    // Pixel Shader
    float4 PixelShaderFunction( VertexShaderOutput input ) : COLOR0
    {
        return ( AmbientColor * AmbientIntensity );
    }
</pre>
<p>Take a good look at this pixel  shader and admire its beauty. Why? Because this is about as easy as it  can get. Pixel shaders can get pretty beefy when advanced vector math  and texturing sampling comes into play, so enjoy this now. All this pixel shader does is take the <strong>AmbientColor </strong>and multiply it with the <strong>AmbientIntensity</strong>. So if you make your  intensity 0.8 like I did, it will return 80% of each color component,  resulting in a darker color. Experiment with different values and see  how the brightness of the color changes.<br />
You can also see that  we attached a semantic at the top of the pixel shader for <strong>COLOR0.</strong> Remember, there's different semantics for vertex shaders than pixel  shaders! <strong>COLOR0 </strong>maps to the first output color for the pixel  shader, so we'll use that one. If we were refer to <strong>COLOR0 </strong>in the  context of a vertex shader, it would be first storage location for a  color we wanted to apply to our vertices in some way.<br />
You're  probably wondering one last thing: "We never used our transformed  position!? Why even pass in the transformed position then?" Yes indeed,  we definitely did not. In the pixel shader at least. We still had to do  the transformations in the vertex shader, otherwise our graphics card  would have no idea where our vertices would go on the screen. All the  pixel shader does is interpolate the colors between the vertices. Since  we're just using an ambient color, we have the same color for every  pixel. So to answer the final question: no reason at all. In every other  shader, you're going to need the position of the vertex to calculate  values like how much light the pixel is getting. But in this case, we  can get away with leaving the arguments of the pixel shader completely  blank. Once again, I just pass it in for consistency.</p>
<p><em><strong>Okay! We finally finished our shader. Now we just need to get XNA to draw using it...</strong></em></p>
<h2>Preparing XNA for Crazy Shadin'</h2>
<p>Before we get too excited about using shaders, we need to set up XNA so we can render with shaders. First, put the variable declaration for our ambient effect at the top of your game file:</p>
<pre class="brush: csharp; title: ;">
Effect ambientEffect;
</pre>
<p>Now our application has a reference to the effect. Then, in the LoadContent method in your game file, add this:</p>
<pre class="brush: csharp; title: ;">
// Load our ambient effect
ambientEffect = Content.Load&lt;Effect&gt;( &quot;Ambient&quot; );
</pre>
<p>This loads the effect file which I've called "Ambient" from the Content Pipeline into our ambientEffect reference. Make sure your Ambient shader is added to the Content Pipeline or XNA won't be able to find it. There! That's all we needed to set up our application for shaders.</p>
<h2>Setting Global Shader Variables from XNA</h2>
<p>Now that you have your shader all implemented, it needs to be passed information from XNA. Once you set a value of a variable in a shader, it stays at that value until it's set again. If the state of the data never changes- let's say the color will always be red- you only have to set that global variable once when you initialize the shader. That will save you the cost of redundantly setting variables. I like to set all of the global variables per frame. Not setting them all the time can be problematic if you add another model in that uses the same shader but different values. It can get pretty hairy to debug that situation if your code is pretty complex. However, if you're looking to squeeze the last few drops of performance out of your application and you know when a global variable will always remain the same, you can try optimizing that block of code. Here's the XNA code for setting your desired technique and setting the values of the parameters:</p>
<pre class="brush: csharp; title: ;">
    // Set what technique we want to render with
    ambientEffect.CurrentTechnique = ambientEffect.Techniques[ &quot;Ambient&quot; ];

    // Set the parameters of the shader
    ambientEffect.Parameters[ &quot;World&quot; ].SetValue( Matrix.CreateRotationY( (float)gameTime.TotalGameTime.TotalSeconds ) );
    ambientEffect.Parameters[ &quot;View&quot; ].SetValue( viewMatrix );
    ambientEffect.Parameters[ &quot;Projection&quot; ].SetValue( projectionMatrix );
    ambientEffect.Parameters[ &quot;AmbientColor&quot; ].SetValue( new Vector4( 1, 1, 1, 1 ) );
    ambientEffect.Parameters[ &quot;AmbientIntensity&quot; ].SetValue( .8f );
</pre>
<p>This code goes right after you clear the GraphicsDevice in your draw method. In the first line, we are setting the current technique to "Ambient". Nothing special there. You can see in the next five lines of code, we're accessing each global variable from the list of parameters and setting its value. For the <strong>World </strong>matrix, I just set up a simple spin around the Y axis to give a little excitement to it. I have the <strong>AmbientColor </strong>set to white. I want that at 80% brightness, so I set the <strong>AmbientIntensity </strong>to 0.8. Easy as cake!</p>
<h2>Drawing Vertices With Our Ambient Effect</h2>
<pre class="brush: csharp; title: ;">
// Begin the effect
ambientEffect.Begin();
foreach ( EffectPass pass in ambientEffect.CurrentTechnique.Passes )
{
    pass.Begin();

    // Set the vertex declaration so our graphics device knows what to render
    GraphicsDevice.VertexDeclaration = new VertexDeclaration( GraphicsDevice, VertexPositionColor.VertexElements );
    // Draw the box
    GraphicsDevice.DrawUserPrimitives&lt;VertexPositionColor&gt;( PrimitiveType.TriangleList, box.Vertices, 0, box.Vertices.Length / 3 );

    pass.End();
}
ambientEffect.End();
</pre>
<p>Okay, hang in there. We're almost to the end. This is the final bit of code we need to add to our application to draw with shaders. Put this block of code directly after the global-variable-setting code from above. Just an FYI, I'm going to skip the draw stuff in the middle since I've assumed all along you know how to draw things in XNA. Our first line when drawing with shaders is always calling Begin() on the effect. This tells it that you're about to use it for rendering. Next, you create a For loop to iterate through each pass in the shader. Remember in the introduction how I mentioned shaders could have several passes? In this case though we only have one, but put the For loop there anyway just for the sake of it in case I want to add more passes to my shader later. Inside of that For loop, we call Begin() on the pass, draw our stuff, then call End() on the pass to tell it we finished drawing. It loops through the rest of the passes until it's completely done. Finally, you call End() on the effect to tell it we're rendering with it. There! Run your application and you should end up with something like the video below. I created a box in my example, so you should get a solid white (rotating) silhouette of whatever model you use.</p>
<p><strong>The (Almost) Beautiful Result</strong></p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/xth0ukrfQKc?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/xth0ukrfQKc?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>Conclusion</h2>
<p>Well I hope my <em>little </em>(psh, far from it!)  article on ambient shaders helped you get a better grasp on shaders.  We've definitely covered a lot of material, way more than to be expected  for the most basic shader, but that's mainly because I spent the  majority of the time introducing how shaders work and how they are set  up. I know I've said this a million times already, but I'm going to say  it a million times more: The basics covered in this article are  necessary to understand more advanced shaders in the future. Also, in  the next tutorials I'm now going to assume you have this stuff down pat,  so I will focus much more on the actual code inside the vertex and  pixel shader, what it's doing and why it's there, not the shader  "etiquette" and structure. Once again, if you have <em>any </em>questions  at all, feel free to drop me a line at <strong>dan@digitseven.com</strong>. Also,  I've probably made a few mistakes as I went along too, so if you come  across something that doesn't match up I'd like to know so I can fix it. And be sure to head over to the home page and <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> to stay updated when new tutorials and code are released.</p>
<p>Download the XNA Project: <a href="http://digitseven.com/Documents/AmbientLight.zip">Ambient Lighting</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Introduction</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-introduction/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-introduction/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 21:26:16 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[HLSL]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1771</guid>
		<description><![CDATA[by Daniel Greenheck
Introducing the Introduction
I'm not an expert on High Level Shader Language (HLSL) by any means, and that's probably a good thing for those of you who don't know much about it either. When I first started programming shaders, I had a hard time finding anything that could really explain it at a level [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<h2>Introducing the Introduction</h2>
<p>I'm not an expert on High Level Shader Language (HLSL) by any means, and that's probably a good thing for those of you who don't know much about it either. When I first started programming shaders, I had a hard time finding anything that could really explain it at a level that I could understand. This introduction isn't going to go into the graphics pipeline at all, you'll have to search elsewhere for that level of detail. Instead, I'm going to go into the very basics of a shading program and give you an idea of how everything fits together in the bigger picture.</p>
<h2>What is a shader?</h2>
<p>Shaders are simply a means of manipulating data in some way to get a desired result. They operate on two types of data: vertices and pixels. There are two types of shaders dedicated to each: vertex and pixel shaders. Vertex shaders modify vertex positions and other data at the vertex level. Pixel shaders take data between the vertices by interpolating the values between each pixel. The final result is the color of that pixel. Shaders are powerful because you can tell them exactly how you want to manipulate each vertex and each pixel. With all that power comes a lot of complexity, so I'm going to try to break it down a bit so the task doesn't look so daunting. I was afraid of shaders for a while, but eventually I embraced them because they really are quite elegant and beautiful once you get your head around them.</p>
<p><span id="more-1771"></span></p>
<h2>.FX Files</h2>
<p>Pronounced "effects" files, you store you shaders inside of these files which get loaded inside of your program. In your XNA code, you'll specify which shaders from the file you want to use by specifying a technique, which will be explained later. Usually you'll have several effect fiels in your project since you'll be using many different types of shaders for different scenarios.</p>
<h2>Shader Format</h2>
<p>Here's an example structure of a shader file:</p>
<pre class="brush: plain; title: ;">
float var1;      // Variable Declaration
   float var2;
   ...

   struct VSInput   // Structure defining what data your vertex shader needs passed into it
   {
   };
   struct VSOutput  // Structure defining what data you vertex shader outputs to the pixel shader.
   {
   };

   // The vertex shader
   VSOutput VertexShader( VSInput inputData )
   {
   }
   // The pixel shader
   float4 PixelShader( VSOutput inputData )
   {
   }

   // The technique gives you a way of selecting which shaders you want to use and in
   // what combination in case you have more in one file. This technique will expand
   // to include several different passes referencing different vertex and pixel shaders
   // when you get into more advanced shaders.
   technique Diffuse
   {
      pass Pass0
      {
         VertexShader = compile vs_1_1 VertexShader();
         PixelShader = compile ps_1_1 PixelShader();
      }
   }
</pre>
<p>Now most of that may seem like complete jibberish to you, but don't worry, I'll start explaining it piece by piece.</p>
<h2>Variable Declaration</h2>
<p>Just like in a regular XNA or C# program, this is where you are going to declare any global variables used by the shader- things like light direction, world, view and projection matrices, light colors, and any other variables your shader might need. These global variables are especially important because these also act as parameters that can be accessed from XNA or C#, acting as a bridge for you to pass data over from XNA into the shader. You call the effect.Parameters.SetValue() to set the value of a global variable. <a href="http://msdn.microsoft.com/en-us/library/bb509587%28VS.85%29.aspx">Here's a list of all the different intrinsic variable types you can use for your global variables.</a></p>
<h2>Vertex Shader Input and Output Structs</h2>
<p>These were probably the most confusing parts of the shader (for me anyway!), even though they are really extremely simple and intuitive. These structures define what data needs to be passed IN to the vertex shader (VSInput) and what data needs to be passed OUT of the vertex shader (VSOutput) and in to the pixel shader. You'll end up seeing variables such as <em>Position, Color, Texture Coordinat</em>es, listed inside of these structures etc. Look at examples of shaders to see what kind of information is passed between the program and the vertex and pixel shader. The problem I had in understanding these structures is that NOWHERE in my program did I ever actually manually pass in something like that. The magic mystery part is that it's all done under the hood. When you call your Draw() method, it automatically passes in your vertex data and stuffs it into the VSInput (that name is arbitrary by the way) structure. Just think of it as a way of consolidating all of your arguments for your vertex shader. A vertex shader is just a method, and the structure which defines the vertex shader input arguments in one neat little package. If you look at the argument for the vertex shader, you can see it takes in the VSInput structure. Heck, you could even forget about using structures if you wanted to and list each argument separately. That is a little messier though and not really recommended. Okay, moving on.</p>
<h2>Vertex Shader</h2>
<p>The vertex shader is just a method that handles all the manipulation of your vertices. This method is run inside of your graphics card, however, making it blazingly fast. Here you will handle transformations of your vertices into world space (if you don't know what that is, don't worry! It will be covered in the ambient lighting tutorial), calculate the amount of light that hits the vertex, manipulate the texture coordinates. You then take whatever information you calculated, store it in your VSOutput struct, and return it (Notice the return type for the VertexShader is VSOutput. Just like a method in C# or XNA!). That data will be used further down the pipeline in your pixel shader. Don't worry about telling it where to go though, your graphics card handles all of that.<br />
The powerful thing about vertex shaders is that you can really do whatever you want to a vertex. You could add in code that would make the vertex color lighter if it's Y value was higher. You could also even simulate an ocean wave by keeping track of a time variable and using sine functions (that will be a tutorial in the future by the way!). The shader language is very powerful, so use your imagination! After you get some practice under your belt, you'll be able to program whatever you can dream up (until the math makes your brain implode)!</p>
<h2>Pixel Shader</h2>
<p>The pixel shader is a method that handles manipulations of the color of an individual teeny tiny pixel. Based on the information stored in the global variables and the information your vertex shader output, you can do some pretty advanced calculations on each pixel. Just like vertex shaders, under the hood of your beasty graphics card, it runs the pixel shader for each pixel. You're probably confused because you're wondering where it gets the position and other information from. We never specify the position of a pixel in our program or any properties of it! True, but we do for our vertices; models are defined by their set of vertices. So how do you find out the information for a pixel between several vertices? A little thing called interpolation. The pixel shader is pretty smart and knows exactly where the pixel is, how to calculate which way it's facing and all sorts of fun stuff. Once your pixel shader finishes its calculations, it returns a single float4, which stores the alpha, red, green and blue components of the pixel (ARGB). Just think, all this work just to calculate a stinkin' color!</p>
<h2>Techniques and Passes</h2>
<p>A technique is just a simple way of XNA asking "use only these shaders. please" when it draws something. In a technique, you get to define exactly which shaders to use, when to use them, how to layer them on top of eachother, etc. Yes, you heard me right, you can use multiple shaders in one draw call. This is done through the use of passes. A technique is made of several passes. Each pass consists of a vertex shader and a pixel shader. But setting up several passes in a certain order, you can combine a bunch of shaders to create really complex effects. We won't be doing anything along those lines for a while, so you can wipe the sweat of you brow!.</p>
<h2>Vertex Shaders vs. Pixel Shaders</h2>
<p>For several years, there's been an underground battle between vertex and pixel shaders, but the pixel shaders are quickly gaining the higher ground. What the hell am I talking about? It's best explained by a picture, which I have right below here.</p>
<p><img src="http://digitseven.com/images/pixelvsvertex.bmp" alt="" width="578" height="258" /></p>
<p>Now before you get worried about knowing what exactly that picture is, I'm going to tell you not to worry. On the left, we are lighting up a sphere using "per-pixel" lighting. On the right, we have an example of "per-vertex" lighting. Both are pretty intuitive concepts: in the former, the lighting calculations are done on the pixel shader, the later on the vertex shader. As you can see, the pixel shader example looks much better than the vertex shader. This is because for each pixel, we're using it's interpolated position and normal data. Although usually more performance-intensive, most graphics cards these days have plenty of power to handle it. On a vertex shader, it can only determine the color of each vertex. It doesn't know what the colors look like between the vertices, so it just guess. And as anyone can tell you, the right answer is always better than the guessed answer. So if you want smooth lighting, put your calculations on the pixel shader. If your graphics card is just hanging on by a thread, put the lighting calculations in the vertex shader. That might be easier said than done, but don't get too worried; you'll get a hang of this stuff as you make your way through my tutorials.</p>
<h2>The Flow of the Shaders...</h2>
<p>I've provided a "nice" *cough* little picture for you below that gives you an idea of how the whole shader thing works out.</p>
<p><img src="http://digitseven.com/images/shaderintro.bmp" alt="" width="495" height="239" /><br />
Image 1 - A crude step-by-step picture of what happens when you want to draw something.</p>
<p>1) You set all the global variables in your shader to whatever values you want. You'll have to pass in your World, View and Projection matrices to pretty much every single shader. You'll also be passing in colors, color intensities, light directions, light intensities, etc. etc.<br />
2) Here's where we dive under the hood of the graphics card and they hide everything from you. When you call DrawPrimitives() or Model.Draw(), it checks to see which technique you selected earlier. Once you're in that technique, it starts going through all of the passes. You can see in my XNA code on the left, I'm iterating through each pass in the current technique (I know this is a lot right now, but don't worry. The ambient lighting shader will give some concrete examples of all of this.) So now that you have a technique and you're on a certain pass...<br />
3) It calls the vertex shader method. In your pass, you specify which vertex shader you want it to use. Now when you call the vertex shader, you're probably asking "Where the heck is it getting the data that needs to be passed to the vertex shader?" That answer I don't exactly know to be honest. Since it's a little over my head, I just picture that when I make my Draw() call, the graphics card now has a theoretical filing cabinet with all of my vertex data. It starts from the top drawer, goes through the files one by one, passing each onto the vertex shader. Then it goes to the next drawer, goes through each file, etc. Once my filing cabinet has successfully been "Vertex-Shaderized" (fancy isn't it?)...<br />
4) It calls the pixel shader method, once again specified in your pass. After each pixel has run through the shader, you now have a single frame from your 3D application.</p>
<h2>Conclusion</h2>
<p>Well I hope my little introduction to shaders gave you a somewhat basic understanding of how things work and didn't just make you so frustrated that you've smashed your computer and completely given up the technological lifestyle. I didn't cover everything here, but I did that on purpose. There's a lot of technical aspects to shaders that I think are just best left as part of the learning curve, figuring them out as you go along. I hope to provide some those technical details as you travel along that curve. Anyway, if you have any questions at all, feel free to send me an email at dan@digitseven.com. And be sure to head over to the home page and <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> to stay updated when new tutorials and code are released. Good luck and happy programming!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-introduction/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Article: Arbitrarily Shaped Secondary 2D Viewports</title>
		<link>http://www.sgtconker.com/2010/09/article-arbitrarily-shaped-secondary-2d-viewports/</link>
		<comments>http://www.sgtconker.com/2010/09/article-arbitrarily-shaped-secondary-2d-viewports/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 20:42:24 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Arbitrary Shaped]]></category>
		<category><![CDATA[Harry Trautmann]]></category>
		<category><![CDATA[Inkscape]]></category>
		<category><![CDATA[Secondary Viewports]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1760</guid>
		<description><![CDATA[by Harry Trautmann

This tutorial shows a technique to implement a secondary 2D viewport which has a shape that does not need to be rectangular, but can be customized by the programmer. Even moving sprite shapes are possible. Utilized code techniques: secondary rendertarget (of XNA Game Studio 3.1) and an alphamap by a pixelshader (PS 2.0).
This [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by Harry Trautmann</h4>
<p style="text-align: center;"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/ScreenSecondViewport.png"><img class="aligncenter" title="Arbitrary Shaped Viewports" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/ScreenSecondViewport.png" alt="" width="479" height="361" /></a></p>
<p>This tutorial shows a technique to implement a secondary 2D viewport which has a shape that does not need to be rectangular, but can be customized by the programmer. Even moving sprite shapes are possible. Utilized code techniques: secondary rendertarget (of XNA Game Studio 3.1) and an alphamap by a pixelshader (PS 2.0).</p>
<p>This tutorial is for beginner to intermediate level programmers. At least you should know the oo basics and know the nitty-gritty about the XNA framework. Also, basic shader programming is explained somewhere else (e. g. here: <a href="http://www.sgtconker.com/2009/11/crash-course-in-hlsl/">http://www.sgtconker.com/2009/11/crash-course-in-hlsl/</a>)</p>
<h2><span id="more-1760"></span>What is a Secondary Viewport?</h2>
<p>Normally games let the player watch one scene at a given time. In a jump'n'run game the player's avatar is somewhere in the middle of the screen, and the game always displays a cut-out part of the world depending on the avatar´s position. This cut-out part is the primary (main) viewport.</p>
<p>A secondary viewport would be some kind of a window inside of the main viewport that shows either the same scene by another view or a completely different scene.</p>
<h2>What could a secondary viewport be useful for?</h2>
<p>I can think of at least 5 applications:</p>
<ol>
<li>Surveillance cameras: the player can behold faraway places while the screen mainly displays some totally other scene. E. g. this could be useful in multiplayer games where one could be able to place such cameras inside of the enemy´s base for spy actions.</li>
<li>Dimension gates: through the door you see a scene of some fantasy land that gets real when you enter.</li>
<li>Microscope: works by applying some magnifying factor.</li>
<li>Mirrors: as the player´s avatar walks by, the secondary viewport shows it horizontally mirrorred and somewhat displaced.</li>
<li>Special FX: do you remember the intro of some old James Bond movie, where some scenes where shown inside of the shape of a dancer? In principle this can be done with a secondary viewport, when the alpha map is a moving sprite.</li>
</ol>
<p>These are just some suggestions for where secondary viewports are useful. Nevertheless this tutorial concentrates on showing how the shape of the viewport can be free from a rectangular nature.</p>
<h2>Principle</h2>
<p>The secondary viewport consists of a secondary <em>RenderTarget</em> object and an alphamap. The alphamap consists of a texture which defines its shape and a pixelshader that modulates pixels by the alphamap texture. The drawing process of the secondary viewport follows these steps:</p>
<ol>
<li>The spectated scene gets rendered onto the secondary rendertarget.</li>
<li>A texture of the secondary rendertarget is kept. It will be drawn later on.</li>
<li>Then the main scene is drawn onto the videocard´s own rendertarget (main rendertarget).</li>
<li> Finally the texture of the spectated scene is drawn onto the main rendertarget by applying the alphamap as a shader effect.</li>
</ol>
<h2>Create the Background Scene</h2>
<p>First we need a scene that we can spectate by the secondary viewport. Understanding the scene implementation itself is not required to comprehend the rest of the tutorial. So to avoid too much confusion we keep the scene code rather simple and encapsulate it mostly into the Star class. Since it is really easy to understand we just skim over some hotspots. Here (<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/SecondaryViewport-SceneOnly.zip">SecondaryViewport-SceneOnly.zip</a>) is the code that produces the plain scene. In case you are unsure, if some code belongs to the scene or to the viewport implementation, you can compare this project and the project we will build for the viewport to see the differences.</p>
<h3>Idea</h3>
<div class="wp-caption aligncenter" style="width: 492px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/ScreenSceneOnly.png"><img class=" " title="Scene Only" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/ScreenSceneOnly.png" alt="" width="482" height="361" /></a><p class="wp-caption-text">Figure 1: Only the Scene - no secondary viewport yet</p></div>
<p>A field of randomly sized, randomly moving sprite stars will do the trick. The <em>Game1</em> object will have an array of <em>Star</em> objects that will get updated and drawn. Figure 1 shows the resulting scene that yet misses the secondary viewport.</p>
<h3>The <em>Star</em> class</h3>
<p>To keep the scene code as far as possible separated from the code that actually implements the secondary viewport, we have the <em>Star</em> class. A <em>Star</em> object keeps track of its position, rotation, moving speed, moving direction and has a unique (also random) color. Each <em>Star</em> object can only move inside of a rectangular area that gets set in the constructor.</p>
<p>Only few things are notably about this class. First all objects share the same texture graphic. The first created <em>Star</em> object loads the static <em>Texture2D</em> member during its constructor call. The same thing applies to the <em>Random</em> value generator.</p>
<pre class="brush: csharp; title: ;">
protected static Texture2D _texStar = null;
protected static Random _randGen = null;
</pre>
<p>These static objects get created in the constructor call of the first Star object.</p>
<pre class="brush: csharp; title: ;">
if (_texStar == null)
        _texStar = game.Content.Load&lt;Texture2D&gt;(&quot;textures//star&quot;);
if (_randGen == null)
        _randGen = new Random();
</pre>
<p>Then in Update, the movement direction of a Star object gets reversed when the position collides with one of the initially set movement boundaries.</p>
<pre class="brush: csharp; title: ;">
if (_pos.X &lt;= _bounds.X || _pos.X &gt;= _bounds.X + _bounds.Width) {
        _move.X *= -1.0f;
        _pos.X = MathHelper.Clamp(_pos.X, _bounds.X, _bounds.X + _bounds.Width);
}// fi
if (_pos.Y &lt;= _bounds.Y || _pos.Y &gt;= _bounds.Y + _bounds.Height) {
        _move.Y *= -1.0f;
        _pos.Y = MathHelper.Clamp(_pos.Y, _bounds.Y, _bounds.Y + _bounds.Height);
}// fi
</pre>
<p>Last, also in Update, the rotation gets clipped to some value inside of the range 0 to 2 pi.</p>
<pre class="brush: csharp; title: ;">
_rot += (float) (_rotInc * gametime.ElapsedGameTime.TotalMilliseconds);
if (_rot &lt; 0.0f) {
        _rot = MathHelper.TwoPi + (_rot % MathHelper.TwoPi);
} else {
        _rot = _rot % MathHelper.TwoPi;
}// fi
</pre>
<h2>Creating the Scene</h2>
<p>The Game1 object has an array of Star objects.</p>
<pre class="brush: csharp; title: ;">
protected Star[] _stars;
</pre>
<p>It gets created inside of the LoadContent method. Each Star´s movement gets limited to the main window´s ClientBounds rectangle.</p>
<pre class="brush: csharp; title: ;">
Rectangle rcWin = new Rectangle(0, 0, Window.ClientBounds.Width,
                                             Window.ClientBounds.Height);
_stars = new Star[_StarCount];
for (int i = 0; i &lt; _StarCount; i++)
        _stars[i] = new Star(this, rcWin);
</pre>
<p>Note, that in LoadContent a font gets loaded ("Arial" should be available on any Windows system). It´s used for drawing some coordinates on the screen so the user can orientate easier.</p>
<pre class="brush: csharp; title: ;">
_font = Content.Load&lt;SpriteFont&gt;(&quot;fonts\\Arial10&quot;);
</pre>
<h2>Updating the Scene</h2>
<p>Straightforward. For each Star its Update method gets called.</p>
<pre class="brush: csharp; title: ;">
for (int i = 0; i &lt; _StarCount; i++)
        _stars[i].Update(gameTime);
</pre>
<h2>Drawing the Scene</h2>
<p>Each Star has its Draw method called and now and then we draw some coordinate values.</p>
<pre class="brush: csharp; title: ;">
GraphicsDevice.Clear(Color.White);
_spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate,
        SaveStateMode.None);
        // The stars know how to draw by themselves.
        for (int i = 0; i &lt; _StarCount; i++)
                _stars[i].Draw(_spriteBatch);
        // For easier orientation draw some coordinate values.
        float chunksW = Window.ClientBounds.Width / 5;
        float chunksH = Window.ClientBounds.Height / 5;
        for (int x=0; x &lt; 5; x++)
                for (int y = 0; y &lt; 5; y++) {
                        _spriteBatch.DrawString(_font, x.ToString() + &quot;/&quot; + y.ToString(),
                                new Vector2(chunksW * (0.5f + x), chunksH * (0.5f + y)), Color.Black);
                }// for
        _spriteBatch.End();
</pre>
<h2>Create the Alphamap Texture</h2>
<p>Now that we have a scene, let´s create the texture for the alphamap. This texture defines the actual shape of the secondary viewport. The texture gets interpreted as a grayscale image. The darker a pixel is in this image, the more transparent the pixel of an image onto which the alphamap gets applied will be. This means a pixel of the alphamap that is completely black, will modulate an incoming pixel to be completely transparent and a pixel of the alphamap that is completely white will modulate an incoming pixel to be completely opaque (i. e. retaining its original color value).<br />
Notes:</p>
<ul>
<li>The alpha value of a pixel in the alphamap texture gets ignored completely. Of course you could use the alpha value of the pixels instead of grayscale, but its easier to see the shape of the map in the image editor by using grayscale.</li>
<li> You can use any image editor to create the alphamap. Personally I favour <a href="http://www.inkscape.org/">Inkscape</a> which can be used by a GNU license. If you never worked with a vector graphics editor before you may find the following tips useful when creating the alphamap texture.</li>
</ul>
<h3>1. Show the layers</h3>
<p>Select the main menu option "Layer / Layers..." (figure 2). It displays the "Layers" window where you can see the layers of the current Inkscape image. Think of a layer being like a transparent sheet on an overhead light projector. The "plus" button creates a new layer, the "minus" button deletes the selected layer. By clicking on the "eye" symbol everything drawn on that layer gets hidden or shown. Create a new layer and rename it by clicking on its name e. g. as "background".</p>
<div class="wp-caption aligncenter" style="width: 438px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/inkscape_1_1_layers.png"><img title="Inkscape Layers" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/inkscape_1_1_layers.png" alt="" width="428" height="412" /></a><p class="wp-caption-text">Figure 2: Main menu option &quot;Layer / Layers...&quot; in Inkscape.</p></div>
<h3>2. Create a black background</h3>
<p>Select the "background" layer. Then click on the black color at the bottom of the Inkscape window to have black assigned as the color that fills any shape you will draw. On the left side of the Inkscape window you find the "Toolbox" toolbar. Click the "square" button ("Create rectangles and squares") and draw a square onto the image. The results should look similar to figure 3.</p>
<div class="wp-caption alignnone" style="width: 476px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_2_1.png"><img class=" " title="Black BAckground" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_2_1.png" alt="" width="466" height="502" /></a><p class="wp-caption-text">Figure 3: Step 2, drawing a rectangular background for the alphamap.</p></div>
<h3>3. Create a sphere</h3>
<p>Create another layer (e. g. called "alphashape"). Make sure, that layer is selected. Select the white color at the bottom of the Inkscape window. Then click the "circle" tool ("Create circles, ellipses, and arcs") in the toolbox and draw a spherical object inside of the black background rectangle. The results should look similar to figure 4.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_3_1.png"><img class="alignnone" title="Figure 4: Step 3, rectangular background with sphere on it." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_3_1.png" alt="Figure 4: Step 3, rectangular background with sphere on it." width="464" height="502" /></a></p>
<h3>4. Apply a gradient to the sphere shape</h3>
<p>First show the "Fill and Stroke" colors by selecting the main menu option "Object / Fill and Stroke...". Above the "Layers" window another window named "Fill and Stroke" should be displayed now. Make sure the "Fill" tab and inside of the drawing area the white sphere are selected (You may need to click the 'select' tool ("Select and transform objects") in the toolbox first to select the sphere). Now click the 'gradient' tool ("Create and edit gradients") in the toolbox. Then press the left mouse button in the center of the white sphere and drag the cursor towards its edge. The results should look similar to figure 5. Since we want to have most of our alphamap opaque, we have to modify the gradient. Press the "Edit..." button ("Edit the stops of the gradient") of the 'tool controls' bar (figure 6). In the appearing "Gradient editor" window press the "Add stop" button. Behold new control points appearing on the gradient lines (figure 7). Close the gradient editor window and click on one of these new points to have it selected in the "Fill and Stroke" window. Now set the "Opacity, %" gauge to "100.0" (figure 8). Finally press the left mouse button onto the new gradient point and drag it towards the edge of the spherical object (figure 9).</p>
<div class="wp-caption alignnone" style="width: 476px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_1.png"><img class=" " title="Figure 5: Step 4a, a simple gradient applied to the sphere." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_1.png" alt="" width="466" height="501" /></a><p class="wp-caption-text">Figure 5: Step 4a, a simple gradient applied to the sphere.</p></div>
<div class="wp-caption alignnone" style="width: 593px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_2.png"><img title="Figure 6: Step 4b, the gradient edit button." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_2.png" alt="" width="583" height="83" /></a><p class="wp-caption-text">Figure 6: Step 4b, the gradient edit button.</p></div>
<div class="wp-caption alignnone" style="width: 432px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_3.png"><img title="Figure 7: Step 4c, the new points on the gradient lines." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_3.png" alt="" width="422" height="258" /></a><p class="wp-caption-text">Figure 7: Step 4c, the new points on the gradient lines.</p></div>
<div class="wp-caption alignnone" style="width: 700px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_4.png"><img title="Figure 8: Step 4d, modify new gradient step." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_4.png" alt="" width="690" height="247" /></a><p class="wp-caption-text">Figure 8: Step 4d, modify new gradient step.</p></div>
<div class="wp-caption alignnone" style="width: 396px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_5.png"><img title="Figure 9: Step 4e, repositioning gradient step points." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_5.png" alt="" width="386" height="252" /></a><p class="wp-caption-text">Figure 9: Step 4e, repositioning gradient step points.</p></div>
<h3>5. Export the image as PNG</h3>
<p>Select the black background rectangle we created in the second step. Select the main menu entry "File / Document Properties...". Inside of the appearing "Document Properties" window in the "Custom size" box press the little plus button and then the "Resize page to drawing or selection" (figure 10). Close the "Document Properties" window. Select the main menu option "File / Export Bitmap...". Press the "Page" button to have the size of the exported bitmap fixed to the page size. Press the "Browse..." button and enter a filename and storage location for the bitmap file. Also do not forget to select PNG as file format and have the filename have a ".png" suffix. Press "Save" to close the file selection dialog. Finally press the "Export" button to actually have the image exported.</p>
<div class="wp-caption alignnone" style="width: 588px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_6.png"><img class=" " title="Figure 10: the button to have the page resized is a little bit hidden." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/Inkscape_4_6.png" alt="" width="578" height="389" /></a><p class="wp-caption-text">Figure 10: the button to have the page resized is a little bit hidden.</p></div>
<h3>6. Import the texture into the Visual C# Project</h3>
<p>Back in the MS VC# IDE do not forget to add the alphamap image to the "Content" in the project explorer.</p>
<h2>Implement the Viewport</h2>
<p>Note that in this sample the main scene and the spectated scene are the same. Therefore it is not necessary to render the scene twice. Instead the main scene gets rendered once onto the texture of the secondary rendertarget, and then this texture gets rendered twice. Otherwise, if there would be many complex objects in the scene (though obviously not the case in this tutorial), the need to render the scene itself twice could become a serious performance hit.</p>
<p>The idea in this sample is to draw a magnified cut-out of the main scene as the secondary viewport. With the mouse you can steer the cut-out rectangle.</p>
<h3>New Members of Game1</h3>
<p>The Game1 class gets some new members that are necessary for the secondary viewport.<br />
The actual secondary rendertarget. Note that this is a memory space inside of the graphics card memory.</p>
<pre class="brush: csharp; title: ;">
protected RenderTarget2D _rendtarg2;
</pre>
<p>This Texture2D object that will hold the alphamap texture that we created in the last step:</p>
<pre class="brush: csharp; title: ;">
protected Texture2D _texAlphamap;
</pre>
<p>The member that will hold the compiled pixel shader effect:</p>
<pre class="brush: csharp; title: ;">
protected Effect _fxAlphamap;
</pre>
<p>A Rectangle member will hold the rectangular cut-out of the main scene that defines the source of the secondary viewport:</p>
<pre class="brush: csharp; title: ;">
protected Rectangle _rcSrc;
</pre>
<h3>Changes to the Game1 class</h3>
<p>In <em><strong>Initialize</strong> </em>the cursor gets shown to make tracing the cut-out source easier for the user.</p>
<pre class="brush: csharp; title: ;">
IsMouseVisible = true;
</pre>
<p>In <strong><em>LoadContent</em></strong> we need to load the alphamap texture and shader effect.</p>
<pre class="brush: csharp; title: ;">
_texAlphamap = Content.Load&lt;Texture2D&gt;(&quot;textures\\alphamap&quot;);
_fxAlphamap = Content.Load&lt;Effect&gt;(&quot;shaders\\AlphaMapping&quot;);
</pre>
<p>Also in <em>LoadContent </em>the secondary rendertarget is created here by calling CreateRenderTarget:</p>
<pre class="brush: csharp; title: ;">
CreateRenderTarget();
[/csharp

Note that the secondary rendertarget always needs to be of the current size of the &lt;em&gt;GraphicsDevice&lt;/em&gt;´s backbuffer. Therefore, if you implement some screen resolution / fullscreen mode switches you will also have to call &lt;em&gt;CreateRenderTarget &lt;/em&gt;again to fit the secondary rendertarget to the new size of the backbuffer.

In &lt;strong&gt;&lt;em&gt;Update &lt;/em&gt;&lt;/strong&gt;the positional change of the mouse cursor defines the source position of the secondary viewport. The &lt;em&gt;MathHelper.Clamp&lt;/em&gt; calls make sure that the source rectangle does cover space outside of the main window.
[csharp]
        // Keep track of where the mouse is and update the viewport source.
        MouseState mouse = Mouse.GetState();
        float factor = 0.33f;
        int w = (int)Math.Round(Window.ClientBounds.Width * factor);
        int h = (int)Math.Round(Window.ClientBounds.Height * factor);
        int w2 = (int)Math.Round(Window.ClientBounds.Width * factor * 0.5f);
        int h2 = (int)Math.Round(Window.ClientBounds.Height * factor * 0.5f);
        _rcSrc = new Rectangle(mouse.X - w2, mouse.Y - h2, w, h);
        _rcSrc.X = (int)MathHelper.Clamp(_rcSrc.X, 0, Window.ClientBounds.Width – w);
        _rcSrc.Y = (int)MathHelper.Clamp(_rcSrc.Y, 0, Window.ClientBounds.Height - h);
</pre>
<p>The most and most important changes to <em>Game1 </em>appear in <em><strong>Draw</strong></em>.</p>
<p>As stated above, the main scene only gets rendered once – and not onto the main rendertarget, but onto the secondary rendertarget (<em>_rendtarg2</em>). So before drawing our scene we need to set the secondary rendertarget as the current one. In order to be able to reset the main rendertarget to be the current one, we have to keep a reference in the local variable <em>rtTemp</em>.</p>
<pre class="brush: csharp; title: ;">
RenderTarget2D rtTemp = null;
rtTemp = (RenderTarget2D)_graphics.GraphicsDevice.GetRenderTarget(0);
_graphics.GraphicsDevice.SetRenderTarget(0, _rendtarg2);
</pre>
<p>After regularly drawing the scene, we keep a <em>Texture2D </em>of what we just drew. But since <em>GetTexture </em>is only possible on a <em>RenderTarget2D </em>that is not the current one, we first have to reset to the original rendertarget.</p>
<pre class="brush: csharp; title: ;">
_graphics.GraphicsDevice.SetRenderTarget(0, rtTemp);
texTemp = _rendtarg2.GetTexture();
</pre>
<p>Now we´re ready to assemble the graphical output as it is to be seen by the user. So we clear the (original) rendertarget to black (just to be safe) and paint the <em>Texture2D </em>that we just rendered on it. Note that the texture gets tinted into some light blue so that it´s easier to distinguish it from the secondary viewport graphics.</p>
<pre class="brush: csharp; title: ;">
GraphicsDevice.Clear(Color.Black);
_spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate,
                              SaveStateMode.None);
_spriteBatch.Draw(texTemp,
                         Vector2.Zero, null,
                         new Color(225, 245, 255, 255),
                         0.0f, Vector2.Zero,
                         Vector2.One,
                         SpriteEffects.None, 0.0f);
_spriteBatch.End();
</pre>
<p>Finally the secondary viewport will be rendered atop of the main scene. Note that the drawing code is outsourced into a method of its own: <em>Draw2ndViewport</em>. Why? Admitted, in this sample it does not make much sense. But assuming you write a program build atop of this sample, which needs to have more than one secondary viewport (e. g. an ingame monitor wall with say 4 monitors showing what goes on elsewhere), it is easier to have a method dedicated to draw a single secondary viewport.<br />
So what does Draw2ndViewport need as input?</p>
<ol>
<li> rcOut defines the output rectangle of the secondary viewport, i. e. Its size and where it gets drawn at. We calculate this Rectangle just before the call of Draw2ndView.</li>
<li> rcSrc defines the rectangular cut-out source of the secondary viewport. Remember that we calculated this Rectangle in Update.</li>
<li> rcScreen is a Rectangle holding the size of the screen onto which the secondary viewport is to be drawn. It gets used for calculating mapping factors from incoming image space to output space. Here it is set to the main window´s extends. We calculate this Rectangle just before the call of Draw2ndView.</li>
<li> tex is the reference to the texture to be drawn. If drawing cut-out´s of a scene, then a single texture reference can be reused for this parameter.</li>
</ol>
<p>So the Draw2ndView call looks like this:</p>
<pre class="brush: csharp; title: ;">
Rectangle outrect = new Rectangle(
                     (int)Math.Round(Window.ClientBounds.Width * 0.25f),
                     0,
                     (int)Math.Round(Window.ClientBounds.Width * 0.5f),
                     (int)Math.Round(Window.ClientBounds.Height * 0.5f));
Rectangle screenrect = new Rectangle(0, 0,
                     Window.ClientBounds.Width, Window.ClientBounds.Height);
Draw2ndViewport(outrect, _rcSrc, screenrect, texTemp);
</pre>
<p>For now treat <em>Draw2ndViewport </em>as a black box. After explaining the pixelshader its workings are easier to understand, and we come back to it.</p>
<h3>How the Pixelshader works</h3>
<p>The alphamap pixelshader ("AlphaMapping.fx") has three parameter members that need to be set outside, before the effect can be applied.</p>
<ol>
<li><em>float4 srcRect</em>: these 4 <em>float</em> values defines the source area inside of the incoming image. The values can be between <em>0.0f</em> and <em>1.0f</em> as usual for texel coordinates.</li>
<li><em>float4 destRect</em>: these 4 float values define the destination area inside of the shaded image. These values too are to be inside of <em>0.0f</em> and <em>1.0f</em>.</li>
<li><em>texture AlphaMap</em>: is to hold the reference to the alphamap texture.</li>
</ol>
<p>The shader has two samplers, the first for the incoming image and the other for the alphamap.</p>
<pre class="brush: csharp; title: ;">
sampler IncomingSampler;
sampler AlphaMapSampler = sampler_state {
        Texture = &lt;AlphaMap&gt;;
        MinFilter = Linear;
        MagFilter = Linear;
        MipFilter = Linear;
        AddressU  = Mirror;
        AddressV  = Mirror;
};
</pre>
<p>The actual work of modulating pixels of the incoming image by corresponding pixels of the alphamap texture happens inside of the <em>PS_AlphaMap</em> function.</p>
<pre class="brush: csharp; title: ;">
float4 PS_AlphaMap(float2 texCoord: TEXCOORD0) : COLOR
</pre>
<p>The function receives texture coordinate inside of the texture image to be processed. Again these two float values are between<em> 0.0f</em> and <em>1.0f</em>. It returns four <em>float </em>values defining the color that the pixel at that coordinate position is to have.<br />
First we get whatever color is at the original position of the incoming texture image. <em>colOut </em>will hold the color value that <em>PS_AlphaMap</em> returns.</p>
<pre class="brush: csharp; title: ;">
float4 colOut = tex2D(IncomingSampler, texCoord);
</pre>
<p>Then we check, if the incoming coordinate is inside of the output area to be modulated by the alphamap.</p>
<pre class="brush: csharp; title: ;">
if ((texCoord[0] &gt;= destRect[0]) &amp;&amp; (texCoord[0] &lt; (destRect[0] + destRect[2])) &amp;&amp;
      (texCoord[1] &gt;= destRect[1]) &amp;&amp; (texCoord[1] &lt; (destRect[1] + destRect[3]))){
</pre>
<p>If it is not inside of the destination area, the read color is assured to stay like it is. Therefore the a value is set to opaque.</p>
<pre class="brush: csharp; title: ;">
} else {
      colOut.a = 0.0f;
}// fi
</pre>
<p>But if the coordinate is inside of the destination area, its color value gets modulated by the alphamap before returning it. Then it is necessary to respect that the source of the output color could be some other pixel than the one we currently have the coordinates for in <em>texCoord</em>. Depending on the size of the incoming texture image and the size of the destination rectangle the new source coordinate gets calculated and stored in <em>newSrc</em>. Remember that all these values are relative share values between <em>0.0f</em> and <em>1.0f</em>. Afterwards <em>colOut </em>is filled with the color of the pixel at this new coordinates in the incoming texture image.</p>
<pre class="brush: csharp; title: ;">
float2 newSrc;
float shareX = (texCoord[0] - destRect[0]) / destRect[2];
float shareY = (texCoord[1] - destRect[1]) / destRect[3];
newSrc[0] = srcRect[0] + shareX * srcRect[2];
newSrc[1] = srcRect[1] + shareY * srcRect[3];
colOut = tex2D(IncomingSampler, newSrc);
</pre>
<p>Now we have to read the color value of the alphamap that corresponds to the incoming coordinates relative to the destination rectangle size.</p>
<pre class="brush: csharp; title: ;">
float2 mappedTC;
float4 colAlphaMap;
mappedTC[0] = ((texCoord[0] - destRect[0]) / destRect[2]);
mappedTC[1] = ((texCoord[1] - destRect[1]) / destRect[3]);
colAlphaMap = tex2D(AlphaMapSampler, mappedTC);
</pre>
<p>Finally the current incoming color value gets modulated by the alphamap color value. This is done by simply multiplying the a parts of the colors and leaving the r, g, b of the incoming value as they are. Note that since the alphamap texture should be grayscale the r, g, b values should be the same for a single pixel in the alphamap texture. Therefore in the pixelshader only the r value of a pixel´s color is processed, r and b get ignored.</p>
<pre class="brush: csharp; title: ;">
colOut.a = colOut.a * colAlphaMap.r;
</pre>
<p>Finally in the technique <em>AlphaMapShader </em>the <em>Pass0 </em>defines that the <em>AlphaMapSampler </em>and the <em>PS_AlphaMap</em> functions are to be used.</p>
<pre class="brush: csharp; title: ;">
technique AlphaMapShader {
        pass Pass0 {
                AlphaBlendEnable = True;
                SrcBlend = SrcAlpha;
                DestBlend = InvSrcAlpha;
                Sampler[0] = (AlphaMapSampler);
                PixelShader = compile ps_2_0 PS_AlphaMap();
        }// Pass0
} // AlphaMapShader
</pre>
<h3>Draw 2nd Viewport</h3>
<p>So back in <em>Game1 </em>we only need to explain what <em>Draw2ndView </em>does. Actually it only sets  the parameters of the pixelshader and draws the given texture image by applying the alphamap shader – all wrapped in the <em>SpriteBatch</em>´s <em>Begin </em>and <em>End </em>methods.<br />
Setting the AlphaMap shader parameter:</p>
<pre class="brush: csharp; title: ;">
_fxAlphamap.Parameters[&quot;AlphaMap&quot;].SetValue(_texAlphamap);
</pre>
<p>For setting the srcRect shader parameter we first need to have the source rectangle mapped to share values between 0.0f and 1.0f relative to the texture´s size.</p>
<pre class="brush: csharp; title: ;">
float[] srcRect = new float[4] {
        (float) rcSrc.X / (float)tex.Width,
        (float) rcSrc.Y / (float)tex.Height,
        (float) rcSrc.Width / (float)tex.Width,
        (float) rcSrc.Height / (float)tex.Height
};
_fxAlphamap.Parameters[&quot;srcRect&quot;].SetValue(srcRect);
</pre>
<p>Setting the <em>destRect </em>shader parameter also needs mapping the values to share values, but this time relative to the output screen´s size.</p>
<pre class="brush: csharp; title: ;">
float[] destRect = new float[4];
destRect[0] = (rcOut.X + rcScreen.X) / (float)rcScreen.Width;
destRect[1] = (rcOut.Y + rcScreen.Y) / (float)rcScreen.Height;
destRect[2] = (rcOut.Width) / (float)rcScreen.Width;
destRect[3] = (rcOut.Height) / (float)rcScreen.Height;
_fxAlphamap.Parameters[&quot;destRect&quot;].SetValue(destRect);
</pre>
<p>After setting these parameters drawing the given texture by applying the shader is straightforward just like with other shaders.</p>
<pre class="brush: csharp; title: ;">
_fxAlphamap.CurrentTechnique = _fxAlphamap.Techniques[&quot;AlphaMapShader&quot;];
_fxAlphamap.Begin();
_fxAlphamap.CurrentTechnique.Passes[0].Begin();
        _spriteBatch.Draw(tex,
                        new Vector2(),
                        null,
                        Color.White,
                        0.0f, Vector2.Zero,
                        Vector2.One,
                        SpriteEffects.None, 0.0f);
_fxAlphamap.CurrentTechnique.Passes[0].End();
_fxAlphamap.End();
</pre>
<p>Figure 11 shows what the result looks like.</p>
<div class="wp-caption alignnone" style="width: 489px"><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/ScreenSecondViewport.png"><img class=" " title="Figure 11: the scene with a magnifying secondary viewport." src="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/ScreenSecondViewport.png" alt="" width="479" height="361" /></a><p class="wp-caption-text">Figure 11: the scene with a magnifying secondary viewport.</p></div>
<p>Find the sample code here: <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/SecondaryViewport.zip">SecondaryViewport.zip</a>.</p>
<h2>Ideas for Extensions</h2>
<p>Homework for you!</p>
<ul>
<li>The mousewheel could steer the zoom. The zoom is controlled by the size of the rectangle defining the cut-out of the main scene.</li>
<li>Of course the spherical form of the alphamap is only a suggestion. It´s easy to reproduce, therefore it seemed appropriate for this tutorial. Actually having a completely customized alphamap shape is what this tutorial is about – go ahead and change it to whatever form you like!</li>
<li>As mentioned in the intro, the alphamap could also be a moving 2D sprite. I extended the sample of this tutorial to reflect, how this could be established. You can get the code here: <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/harry/SecondaryViewport-MovingSprite.zip">SecondaryViewport-MovingSprite.zip</a>.</li>
</ul>
<h2>License</h2>
<p>This text and any referred code is licensed under a "Creative Commons Attribution 3.0 Unported" license, which can be read here: <a href="http://creativecommons.org/licenses/by/3.0/">http://creativecommons.org/licenses/by/3.0/</a></p>
<p>The author of all text, any code and any assets found in this tutorial likes to be referred by Harry Trautmann, <a href="http://codemachinery.net">http://codemachinery.net</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-arbitrarily-shaped-secondary-2d-viewports/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Article: Derived Effect Classes in XNA 4</title>
		<link>http://www.sgtconker.com/2010/08/article-derived-effect-classes-in-xna-4/</link>
		<comments>http://www.sgtconker.com/2010/08/article-derived-effect-classes-in-xna-4/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 05:04:58 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Content Pipeline]]></category>
		<category><![CDATA[Dave Carlile]]></category>
		<category><![CDATA[Derives Effects]]></category>
		<category><![CDATA[Effects]]></category>
		<category><![CDATA[XNA 4.0]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1569</guid>
		<description><![CDATA[by Dave Carlile

One of the nice API changes in XNA 4.0 is the simplified syntax used when drawing with an Effect. In previous versions you would draw things like this:

effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
        pass.Begin();
        // draw your stuff
   [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by Dave Carlile</h4>
<p style="text-align: center;"><img class="aligncenter" title="Derived Effects" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/derivedEffects.png" alt="" width="484" height="305" /></p>
<p>One of the nice API changes in XNA 4.0 is the simplified syntax used when drawing with an Effect. In previous versions you would draw things like this:</p>
<pre class="brush: csharp; title: ;">
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
        pass.Begin();
        // draw your stuff
        pass.End();
}
effect.End();
</pre>
<p>Now you can draw things like this, with EffectPass.Apply handling all the magic:</p>
<pre class="brush: csharp; title: ;">
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
        pass.Apply();
        // draw your stuff
}
</pre>
<p>Related to this is the new Effect.OnApply virtual method which gets called by EffectPass.Apply. By overriding this method in a derived class you can do things like perform pre-shader calculations and set shader parameters from properties. This is how BasicEffect and the other new standard shaders work, and it would be nice to be able to duplicate that functionality in our own derived effects.<br />
Ideally we would like to be able to do something like this:</p>
<pre class="brush: csharp; title: ;">
        MyEffect effect = Content.Load&lt;MyEffect&gt;(“myeffect”);
        effect.World = Matrix.Identity;
        effect.Color = Color.Blue;
        ...
        effect.Apply();
        ...
</pre>
<p>The first line is where we begin running into issues. In order to load a derived class using the content pipeline you have to write your own content processor, reader, and writer, for every single class.  You might think that you could load an Effect instance using the content manager, then create an instance of your derived Effect class and pass in the code. Unfortunately, there is no way to get at the code in the Effect instance (okay, that is <a href="http://blogs.msdn.com/b/shawnhar/archive/2010/05/07/effect-compilation-and-content-pipeline-automation-in-xna-game-studio-4-0.aspx">not entirely true</a>, but this solution requires the full Game Studio install).<br />
If you want to store the class properties (e.g. MyEffect.World, MyEffect.Color) as content then extending the content pipeline for each class is your best option.  But what if you don't need to store the properties?  What if you just want a cleaner interface to your shaders?  Extending the pipeline each time for these cases seems like a lot of unnecessary work.</p>
<h1>A Solution</h1>
<p>This remainder of this tutorial will show you how to load any derived Effect class from the content pipeline without having to extend the pipeline for each class.  To accomplish this we're going to create a content pipeline extension library that will compile the effect into an intermediate object that will let us get at the compiled code. We will also create a game library that will define the intermediate class so we can get to it at run time.  And finally we’ll add an extension method that will do the work of loading our derived Effect class.<br />
<span id="more-1569"></span></p>
<h1>Setup</h1>
<p>Let's start by opening Microsoft Visual Studio 2010 Express for Windows Phone and setting some things up. It’s important that you name things correctly, so make sure you use the names given while you follow these steps:</p>
<ul>
<li>Create a new Windows Game (4.0) project, call it DerivedEffectsTutorial.</li>
<li>Add a new Windows Game Library (4.0) project to the solution, call it DerivedEffects.</li>
<li>Add a new Content Pipeline Extension Library (4.0) project, call it DerivedEffects.Pipeline.</li>
<li>Reference the DerivedEffects game library in both the DerivedEffects.Pipeline and DerivedEffectsTutorial projects.</li>
<li>Reference the DerivedEffects.Pipeline in the DerivedEffectsTutorialContent project which Visual Studio generated for you.</li>
</ul>
<p>Make sure you can build the solution. All three projects should compile with no errors.</p>
<h1>Extend the Pipeline</h1>
<p>Now that everything is set up, the first thing we're going to do is extend the content pipeline so we can compile a shader in such a way as to provide us access to the compiled code at run time. This requires these steps:</p>
<ul>
<li>Create an intermediate class to store compiled shader code.</li>
<li>Implement a ContentProcessor to compile the code and store it an instance of the intermediate class. Note that we don't need to define a content importer because we can use the existing effect importer.</li>
<li>Implement a ContentTypeWriter to write out the intermediate class at compile time.</li>
<li>Implement a ContentTypeReader to read the intermediate class at run time.</li>
</ul>
<h1>Intermediate Class</h1>
<p>First we need to create an intermediate class to hold the effect code after it's compiled by the content processor. Some types of content require a different class at compile time versus run time for various reasons. But in this case the same class will work for both. Since this class is used at both compile time and run time it needs to live in the DerivedEffects game library.<br />
Visual Studio created a Class1.cs file when we added the game library project. Right click on the file in Solution Explorer, select Rename, and change the name to DerivedEffect.cs.  You should be prompted to change the name of the class to match, click “Yes”.<br />
Now open the file.  You should see the empty DerivedEffect class defined in the DerivedEffects namespace. Make the class public so it looks like this:</p>
<pre class="brush: csharp; title: ;">
namespace DerivedEffects
{
        public class DerivedEffect
        {
        }
}
</pre>
<p>Now add a private member to store the compiled code.</p>
<pre class="brush: csharp; title: ;">
        private byte[] compiledCode;
</pre>
<p>Add a constructor which accepts the code as a parameter and stores it in the private member.</p>
<pre class="brush: csharp; title: ;">
public DerivedEffect(byte[] compiledCode)
{
        this.compiledCode = compiledCode;
}
</pre>
<p>And finally add a public property to provide access to the code.</p>
<pre class="brush: csharp; title: ;">
public byte[] CompiledCode { get { return compiledCode; } }
</pre>
<p>The final class should look like this:</p>
<pre class="brush: csharp; title: ;">
namespace DerivedEffects
{
        public class DerivedEffect
        {
                private byte[] compiledCode;

                public DerivedEffect(byte[] compiledCode)
                {
                        this.compiledCode = compiledCode;
                }

                public byte[] CompiledCode { get { return compiledCode; } }
        }
}
</pre>
<p>Make sure everything still compiles before moving on to the next step.</p>
<h1>Content Processor</h1>
<p>The content processor's job is to compile the shader code and return an instance of our intermediate DerivedEffect class.  Since it is used at compile time it lives in the DerivedEffects.Pipeline project. Visual Studio created a ContentProcessor1.cs file for us when we added the pipeline extension project. Right click on the file in Solution Explorer, select Rename, and change the name to DerivedEffectProcessor.cs.  You should be prompted to change the name of the class to match, click “Yes”.<br />
Now open the file and you should see the empty DerivedEffectProcessor class defined in the DerivedEffects.Pipeline namespace. The class should look like this (with generated comments removed for brevity):</p>
<pre class="brush: csharp; title: ;">
using TInput = System.String;
using TOutput = System.String;

namespace DerivedEffects.Pipeline
{
        [ContentProcessor(DisplayName = &quot;DerivedEffects.Pipeline.ContentProcessor1&quot;)]
        public class DerivedEffectProcessor : ContentProcessor&lt;TInput, TOutput&gt;
        {
                public override TOutput Process(TInput input, ContentProcessorContext context)
                {
                        throw new NotImplementedException();
                }
        }
}
</pre>
<p>The Process method takes an input type and returns out output type. The input type in our case is the EffectContent class which is output by the default effect importer (this is the “Effect - XNA Framework” content importer you see when you select an .fx file in solution explorer and look at the file properties).</p>
<p>The output type is the intermediate DerivedEffect class we defined earlier.</p>
<p>Change the TInput and TOutput aliases to the fully qualified names of our input and output types.</p>
<pre class="brush: csharp; title: ;">
using TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.EffectContent;
using TOutput = DerivedEffects.DerivedEffect;
</pre>
<p>Alternatively you can remove the aliases and replace all instances of TInput with EffectContent, and all instances of TOutput with DerivedEffect.</p>
<p>Change the ContentProcessor attribute to give the processor a better name.  This is the name that shows up in the Content Processor property when you select an .fx file in Solution Explorer.</p>
<pre class="brush: csharp; title: ;">
[ContentProcessor(DisplayName = &quot;Effect – Derived Effects&quot;)]
</pre>
<p>Now, replace the contents of the Process method with this code to compile the effect.</p>
<pre class="brush: csharp; title: ;">
EffectProcessor compiler = new EffectProcessor();
CompiledEffectContent compiledContent = compiler.Process(input, context);
</pre>
<p>This creates an EffectProcessor instance, passes the EffectContent input to the Process method to compile the effect, and returns a CompiledEffectContent instance which will allow us access to the compiled code.<br />
Now we need to create an instance of our intermediate content class, passing it the compiled effect code – remember TOutput is the alias we defined previously for our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
return new TOutput(compiledContent.GetEffectCode());
</pre>
<p>And that's it for the content processor. The final code should look like this (again, with the generated comments removed):</p>
<pre class="brush: csharp; title: ;">
using TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.EffectContent;
using TOutput = DerivedEffects.DerivedEffect;

namespace DerivedEffects.Pipeline
{
        [ContentProcessor(DisplayName = &quot;Effect – Derived Effects&quot;)]
        public class DerivedEffectProcessor : ContentProcessor&lt;TInput, TOutput&gt;
        {
                public override TOutput Process(TInput input, ContentProcessorContext context)
                {
                        EffectProcessor compiler = new EffectProcessor();
                        CompiledEffectContent compiledContent = compiler.Process(input, context);
                        return new TOutput(compiledContent.GetEffectCode());
                }
        }
}
</pre>
<p>Now make sure everything still builds before continuing on. If there are problems, double check that you've set up the references correctly.</p>
<h1>Content Writer</h1>
<p>Next up is the content writer.  This class is responsible for writing an instance of the DerivedEffect class to an .xnb file during compile time.  Since the content writer is executed at compile time, where does it go?  That's right, the pipeline extension library.  Right click on the DerivedEffects.Pipeline project and select Add/New Item. Make sure XNA Game Studio 4.0 is selected in the Installed Templates list on the left, then choose Content Type Writer, name it DerivedEffectWriter.cs, and press the Add button.<br />
In the DerivedEffectWriter class, start by changing the TWrite alias to our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
using TWrite = DerivedEffects.DerivedEffect;
</pre>
<p>Remove all of the code from the Write method and replace it with this:</p>
<pre class="brush: csharp; title: ;">
output.Write(value.CompiledCode.Length);
output.Write(value.CompiledCode);
</pre>
<p>These two lines write out the length of the compiled code array, followed by the code itself. Later on when we implement the content reader it will be able to read in the length first so it  knows how many bytes of code to read.<br />
Next, replace all the code in the GetRuntimeReader method with this:</p>
<pre class="brush: csharp; title: ;">
return typeof(DerivedEffectReader).AssemblyQualifiedName;
</pre>
<p>This line returns the name space, class name, and assembly name for the DerivedEffectReader class. It basically tells the pipeline which content reader to use when it needs to read in our DerivedEffect class.<br />
Note that we haven't defined our content reader class yet, so there will be errors if we try to compile at this point. That will be taken care of next, but first, here is what the final content writer should look like:</p>
<pre class="brush: csharp; title: ;">
using TWrite = DerivedEffects.DerivedEffect;

namespace DerivedEffects.Pipeline
{
        [ContentTypeWriter]
        public class DerivedEffectWriter : ContentTypeWriter&lt;TWrite&gt;
        {
                protected override void Write(ContentWriter output, TWrite value)
                {
                        output.Write(value.CompiledCode.Length);
                        output.Write(value.CompiledCode);
                }

                public override string GetRuntimeReader(TargetPlatform targetPlatform)
                {
                        return typeof(DerivedEffectReader).AssemblyQualifiedName;
                }
        }
}
</pre>
<h1>Content Reader</h1>
<p>We can compile an effect and write the code out to an .xnb file.  Now we need to be able to read it back from the file, which is the content reader's job.  The content reader is used at run time, which means it goes into the game library.  Right click on the DerivedEffects project and select Add/New Item. Make sure XNA Game Studio 4.0 is selected in the Installed Templates list on the left, then choose Content Type Reader, name it DerivedEffectReader.cs, and press the Add button.<br />
Change the TRead alias to our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
using TRead = DerivedEffects.DerivedEffect;
</pre>
<p>Now replace the contents of the Read method with this code:</p>
<pre class="brush: csharp; title: ;">
int size = input.ReadInt32();
byte[] code = input.ReadBytes(size);
</pre>
<p>Recall that the content writer first wrote out the length of the code, then the code.  The reader first reads in the length of the code so it knows how many bytes to read, after which it proceeds to read that many bytes into an array.<br />
And finally, the read method needs to return a new instance of our DerivedEffect class – remember that TRead is the alias we defined for our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
return new TRead(code);
</pre>
<p>The final content reader looks like this:</p>
<pre class="brush: csharp; title: ;">
using TRead = DerivedEffects.DerivedEffect;

namespace DerivedEffects
{
        public class DerivedEffectReader : ContentTypeReader&lt;TRead&gt;
        {
                protected override TRead Read(ContentReader input, TRead existingInstance)
                {
                        int size = input.ReadInt32();
                        byte[] code = input.ReadBytes(size);
                        return new TRead(code);
                }
        }
}
</pre>
<p>Now you should be able to compile successfully again. Make sure that is the case before moving on.</p>
<h1>Testing the Content Pipeline Changes</h1>
<p>That brings us to the end of the content pipeline extension. We've created a content processor to compile the effect, a content writer to save it out to an .xnb file at compile time, and a content reader to read it back in at run time.<br />
Allegedly we can now compile an effect file and load it into a DerivedEffect instance at run time using the content manager.  Let's make sure everything is working so far.<br />
To start with we need an .fx file. Right click on the DerivedEffectsTutorialContent project and select Add/New Item. Choose Effect File, name it MyEffect.fx, and press the Add button. You don't need to change anything in the file.<br />
Select the file in Solution Explorer. Find the Content Processor property in the file properties; click the down arrow to show the available content processors. You should see our new content processor “Effect – Derived Effects” - select it. If you don't see it, verify that you've correctly referenced the DerivedEffects.Pipeline project in the DerivedEffectsTutorialContent project (refer back to the Setup section for instructions on setting up all of the references).<br />
Open the Game1 class in the DerivedEffectsGame project. Add a using statement.</p>
<pre class="brush: csharp; title: ;">
using DerivedEffects;
</pre>
<p>Declare a new member in the Game1 class.</p>
<pre class="brush: csharp; title: ;">
DerivedEffect myEffectCode;
</pre>
<p>And a line to the LoadContent method in order to load the derived effect.</p>
<pre class="brush: csharp; title: ;">
myEffectCode = Content.Load&lt;DerivedEffect&gt;(&quot;myeffect&quot;);
</pre>
<p>Now comes the big moment – compile the project. If everything compiles then the compile time part of the content manager is working correctly. If not, you'll need to go back through the tutorial and find out what you missed.<br />
Now we need to test the run time – go ahead and run the game. If it works you'll see the beautiful cornflower blue window appear. If the content manager has a problem, such as not being able to locate the content reader for DerivedEffect, it will throw an exception.<br />
You can also set a breakpoint and examine myEffect.CompiledCode to see that it is indeed loaded with what you can assume is compiled shader code.<br />
At this point we could create an Effect object by passing the CompiledCode to the Effect constructor, like this:</p>
<pre class="brush: csharp; title: ;">
Effect effect = new Effect(GraphicsDevice, myEffect.CompiledCode);
</pre>
<p>And that is why we've done everything we have up to this point – the need to get access to the compiled code so we can pass it to the Effect constructor.  If the existing Effect class would expose a property like this we could do what we're trying to do without involving the content pipeline at all.  I'm sure the powers that be have a good reason for not exposing it, but it makes things a little awkward.<br />
Now we need to work on loading our own effect descendent. Based the previous line of code, you've probably already figured out what we need to do.</p>
<h1>Derived Effect Class</h1>
<p>Let's start by creating our derived effect class.  Right click on the DerivedEffectsTutorial game project, select Add/Class, name it MyEffect.cs, and press the Add button.<br />
You'll need to add a couple of using statements.</p>
<pre class="brush: csharp; title: ;">
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
</pre>
<p>You'll also need to have the class descend from Effect, and create one of the Effect constructors. It should look like this:</p>
<pre class="brush: csharp; title: ;">
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DerivedEffectsTutorial
{
        class MyEffect:Effect
        {
                public MyEffect(GraphicsDevice graphicsDevice, byte[] effectCode)
                        : base(graphicsDevice, effectCode)
                {
                }
        }
}
</pre>
<p>Now back in the Game1 class, add a new class member.</p>
<pre class="brush: csharp; title: ;">
MyEffect effect;
</pre>
<p>And add a line to LoadContent to create a MyEffect instance.</p>
<pre class="brush: csharp; title: ;">
effect = new MyEffect(GraphicsDevice, myEffectCode.CompiledCode);
</pre>
<p>The LoadContent method should look like this:</p>
<pre class="brush: csharp; title: ;">
protected override void LoadContent()
{
        myEffectCode = Content.Load&lt;DerivedEffect&gt;(&quot;myeffect&quot;);
        effect = new MyEffect(GraphicsDevice, myEffectCode.CompiledCode);
}
</pre>
<p>And there you have it, an instance of your very own shader class derived from Effect! It will work anywhere you would normally use an effect.  You can override OnApply and have it do things when EffectPass.Apply is called, add your own properties, and so on.<br />
But, now we need to kick it up a notch.</p>
<h1>BAM!</h1>
<p>In the beginning we decided we'd like to be able to do this.</p>
<pre class="brush: csharp; title: ;">
MyEffect effect = Content.Load&lt;MyEffect&gt;(“myeffect”);
</pre>
<p>Well, we can't do that using this solution, but how about this instead?</p>
<pre class="brush: csharp; title: ;">
MyEffect effect = Content.LoadDerivedEffect&lt;MyEffect&gt;(&quot;myeffect&quot;);
</pre>
<p>We can accomplish this by adding an extension method to the ContentManager class, so let's get started.<br />
Add a new class to the DerivedEffects game library, call it ContentManagerExtensions.  Make sure the class is static and public.</p>
<pre class="brush: csharp; title: ;">
public static class ContentManagerExtensions
{
}
</pre>
<p>Add some using statements.</p>
<pre class="brush: csharp; title: ;">
using System.Reflection;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
</pre>
<p>Add the LoadDerivedEffect extension method to the class.  Notice the use of generics, and that the allowed classes must be derived from Effect.</p>
<pre class="brush: csharp; title: ;">
public static T LoadDerivedEffect&lt;T&gt;(this ContentManager content, string assetName)
  where T:Effect
{
}
</pre>
<p>Inside the function, we need to be able to get to the graphics device. We can do that by finding the graphics device service.</p>
<pre class="brush: csharp; title: ;">
IGraphicsDeviceService graphicsDeviceService =
    (IGraphicsDeviceService)content.ServiceProvider.GetService(typeof(IGraphicsDeviceService));
</pre>
<p>This uses the content manager's ServiceProvider property to look for the graphics device service.<br />
Next we load the compiled effect code.</p>
<pre class="brush: csharp; title: ;">
DerivedEffect effect = content.Load&lt;DerivedEffect&gt;(assetName);
</pre>
<p>This is the same code we used before to load the DerivedEffect instance, but we're now using the asset name that was passed to LoadDerivedEffect.<br />
Now comes the interesting part. It would be nice if we could do this:</p>
<pre class="brush: csharp; title: ;">
return new T(graphicsDeviceService.GraphicsDevice, effect.CompiledCode);
</pre>
<p>Unfortunately, you can't do that with generics – you can only create objects with parameterless constructors. But, we can use reflection to find and call the constructor we want.</p>
<pre class="brush: csharp; title: ;">
Type classType = typeof(T);

ConstructorInfo classConstructor = classType.GetConstructor(
                BindingFlags.Instance | BindingFlags.Public, null,
                new Type[] { graphicsDeviceService.GraphicsDevice.GetType(),
                        effect.CompiledCode.GetType() },
                null);
</pre>
<p>This code first gets the type for the generic class (e.g. MyEffect). It then uses that to locate the constructor that takes GraphicsDevice and byte[] parameters.  Once we have that we can create and return and instance of the class by calling the constructor and passing the graphics device and compiled code.</p>
<pre class="brush: csharp; title: ;">
return (T)classConstructor.Invoke(new object[]
    { graphicsDeviceService.GraphicsDevice, effect.CompiledCode });
</pre>
<p>The final code should look like this:</p>
<pre class="brush: csharp; title: ;">
namespace DerivedEffects
{
        public static class ContentManagerExtensions
        {
                public static T LoadDerivedEffect&lt;T&gt;(this ContentManager content, string assetName)
                        where T : Effect
                {
                        IGraphicsDeviceService graphicsDeviceService =
                                (IGraphicsDeviceService)content.ServiceProvider.GetService(
                                        typeof(IGraphicsDeviceService));

                        DerivedEffect effect = content.Load&lt;DerivedEffect&gt;(assetName);

                        Type classType = typeof(T);
                        ConstructorInfo classConstructor = classType.GetConstructor(
                                BindingFlags.Instance | BindingFlags.Public, null,
                                new Type[] { graphicsDeviceService.GraphicsDevice.GetType(),
                                        effect.CompiledCode.GetType() }, null);

                        return (T)classConstructor.Invoke(new object[]
                                { graphicsDeviceService.GraphicsDevice,
                                        effect.CompiledCode });
                }
        }
}
</pre>
<p>Now to make sure it's working, go back to the Game1 class, remove the DerivedEffect member and replace all of the code in LoadContent with:</p>
<pre class="brush: csharp; title: ;">
effect = Content.LoadDerivedEffect&lt;MyEffect&gt;(&quot;myeffect&quot;);
</pre>
<p>The project should compile and run with no errors, and you now have an instance of your derived effect class.</p>
<h1>What Next?</h1>
<p>The downloadable code included with this tutorial extends the example with a more fully implemented MyEffect class, including OnApply and pre-shader calculations, as well as some drawing code that uses it. Going through all of that here would make a long tutorial prohibitively long.<br />
It was mentioned earlier that the DerivedEffects and DerivedEffects.Pipeline libraries are reusable. All you need to do in your new game projects is reference DerivedEffects.Pipeline in your game's content project, and DerivedEffects in your game project, and make sure the run time library is distributed with your game.  That's all there is to it.</p>
<h1>Finale</h1>
<p>This was a lot of work to do something that should be simple. If the Effect class exposed the compiled effect code this would boil down to just the content manager extension method. But since it doesn't, we can leverage the content pipeline to help us out by providing the data we need.<br />
Implementing derived effects can really improve code readability and reuse, especially with the latest Effects API changes. Hopefully this method of loading your derived classes through the content pipeline makes it that much easier to use them.  Happy sub-classing!</p>
<p><strong>Download sample code:</strong> <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/DerivedEffectsTutorial.zip">DerivedEffectsTutorial.zip</a> (<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_license.txt">license</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/08/article-derived-effect-classes-in-xna-4/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

