2D (Deferred) Lighting

By February 15, 2010 Blog, XNA Games 36 Comments



2D Lighting Posts :

Last weekend i spended most of my time trying to create a lightning effect for my xna game that would support more then three lights at the same time (i had all lightning inside one shader, inside an array) and still support SM2.0. So i began building my own lightning system and the basics of it are now ready. This lightning system will first render four different types of textures:

  • The Color Map of the entire scene
  • The Depth Map of this scene (where needed)
  • The Normal Maps of all the objects inside the scene (where needed)
  • A combined effect that will become my Light Map.

Here are some examples of my current effect in action:



[Following up post effect]

Read more: 2D Lightning Continued

Now it is time for some code and let you try to achieve the same effect in your project and/or game.

Before we begin we need to declare some variables that we will be using inside most of the code segments.

Variables:

private RenderTarget2D _colorMapRenderTarget;
private RenderTarget2D _depthMapRenderTarget;
private RenderTarget2D _normalMapRenderTarget;
private RenderTarget2D _shadowMapRenderTarget;
private Texture2D _shadowMapTexture;
private Texture2D _colorMapTexture;
private Texture2D _normalMapTexture;
private Texture2D _depthMapTexture;

private VertexDeclaration _vertexDeclaration;
private VertexPositionTexture[] _vertices;

private Effect _lightEffect1;
private Effect _lightEffect2;

Before we can use any of these RenderTargets or Effects we must initialize or load them ofcourse. So before you do anything fancy with them, call the following initialization before you are going to render.

Initialization:

PresentationParameters pp = Globals.GraphicsDevice.PresentationParameters;
int width = pp.BackBufferWidth;
int height = pp.BackBufferHeight;
SurfaceFormat format = pp.BackBufferFormat;

_colorMapRenderTarget = new RenderTarget2D(graphicsDevice, width, height, 1, format);
_depthMapRenderTarget = new RenderTarget2D(graphicsDevice, width, height, 1, format);
_normalMapRenderTarget = new RenderTarget2D(graphicsDevice, width, height, 1, format);
_shadowMapRenderTarget = new RenderTarget2D(graphicsDevice, width, height, 1, format);

_lightEffect1 = Globals.ContentManager.Load<Effect>("ShadersLightningShadow");
_lightEffect2 = Globals.ContentManager.Load<Effect>("ShadersLightningCombined");

_vertices = new VertexPositionTexture[4];
_vertices[0] = new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0));
_vertices[1] = new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0));
_vertices[2] = new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1));
_vertices[3] = new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1));
_vertexDeclaration = new VertexDeclaration(Globals.GraphicsDevice, VertexPositionTexture.VertexElements);

Now that we have initialized and loaded the rendertargets and effect files, we can use them during our render process. The following steps will guide you through the rendering setup, altough i have my render setup like this you can always change this to your own needs. As long as you just get the three textures that are needed during the steps after this one.

ColorMap, DepthMap and NormalMap drawing:

// Set the render targets
graphicsDevice.SetRenderTarget(0, _colorMapRenderTarget);

// Clear all render targets
graphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1, 0);

// Draw your scene here

// Reset the render target
graphicsDevice.SetRenderTarget(0, null);
graphicsDevice.SetRenderTarget(0, _normalMapRenderTarget);

// Clear all render targets
graphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1, 0);

// Draw all your normal maps here

graphicsDevice.SetRenderTarget(0, null);
graphicsDevice.SetRenderTarget(0, _depthMapRenderTarget);

// Clear all render targets
graphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1, 0);

// Draw all your depth maps here

// Deactive the rander targets to resolve them
graphicsDevice.SetRenderTarget(0, null);

// Gather all the textures from the Rendertargets
_colorMapTexture = _colorMapRenderTarget.GetTexture();
_normalMapTexture = _normalMapRenderTarget.GetTexture();
_depthMapTexture = _depthMapRenderTarget.GetTexture();

Now you should have three textures containing the scene in color, normal and depth variants. Like these:

[pictureframe image="http://www.soolstyle.com/wp-content/uploads/2010/02/Lightning001.png" align="left" lightbox="true" title="" link="" width="300" height="224"] [pictureframe image="http://www.soolstyle.com/wp-content/uploads/2010/02/Lightning002.png" align="left" lightbox="true" title="" link="" width="300" height="224"] [pictureframe image="http://www.soolstyle.com/wp-content/uploads/2010/02/Lightning003.png" align="left" lightbox="true" title="" link="" width="300" height="224"]

With the normal and depth textures we will begin drawing our lightmap. Our lightmap render function will make use of the shadowmap render target and after the render the generated texture will be returned.

private Texture2D GenerateShadowMap()
{
graphicsDevice.SetRenderTarget(0, _shadowMapRenderTarget);
graphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1, 0);

graphicsDevice.RenderState.AlphaBlendEnable = true;
graphicsDevice.RenderState.SourceBlend = Blend.One;
graphicsDevice.RenderState.DestinationBlend = Blend.One;

// For every light inside the current scene, you can optimize this
// list to only draw the lights that are visible a.t.m.
foreach (var light in LightCollection)
{
_lightEffect1.CurrentTechnique = _lightEffect1.Techniques["DeferredPointLight"];
_lightEffect1.Parameters["lightStrength"].SetValue(light.Power);
_lightEffect1.Parameters["lightPosition"].SetValue(light.GetWorldPosition());
_lightEffect1.Parameters["lightColor"].SetValue(light.Color.ToVector3());
_lightEffect1.Parameters["lightRadius"].SetValue(light.LightRadius);

_lightEffect1.Parameters["screenWidth"].SetValue(graphicsDevice.Viewport.Width);
_lightEffect1.Parameters["screenHeight"].SetValue(graphicsDevice.Viewport.Height);
_lightEffect1.Parameters["NormalMap"].SetValue(_normalMapTexture);
_lightEffect1.Parameters["DepthMap"].SetValue(_depthMapTexture);

_lightEffect1.Begin();
foreach (var pass in _lightEffect1.CurrentTechnique.Passes)
{
pass.Begin();

// Draw the full screen Quad
graphicsDevice.VertexDeclaration = _vertexDeclaration;
graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _vertices, 0, 2);

pass.End();
}
_lightEffect1.End();
}

// Deactivate alpha blending...
graphicsDevice.RenderState.AlphaBlendEnable = false;
// Deactive the rander targets to resolve them
graphicsDevice.SetRenderTarget(0, null);

return _shadowMapRenderTarget.GetTexture();
}

The HLSL code required to render this is as following. Please note that this only supports Point lights at the moment, i am working on implementing more.

LightningShadow.fx

float screenWidth;
float screenHeight;

float lightStrength;
float lightRadius;
float3 lightPosition;
float3 lightColor;

Texture NormalMap;
sampler NormalMapSampler = sampler_state {
	texture = <NormalMap>;
	magfilter = LINEAR;
	minfilter = LINEAR;
	mipfilter = LINEAR;
	AddressU = mirror;
	AddressV = mirror;
};

Texture DepthMap;
sampler DepthMapSampler = sampler_state {
	texture = <DepthMap>;
	magfilter = LINEAR;
	minfilter = LINEAR;
	mipfilter = LINEAR;
	AddressU = mirror;
	AddressV = mirror;
};

struct VertexToPixel
{
	float4 Position : POSITION;
	float2 TexCoord : TEXCOORD0;
};

struct PixelToFrame
{
	float4 Color : COLOR0;
};

VertexToPixel VertexToPixelShader(float4 inPos: POSITION0, float2 texCoord: TEXCOORD0)
{
	VertexToPixel Output = (VertexToPixel)0;

	Output.Position = inPos;
	Output.TexCoord = texCoord;

	return Output;
}

PixelToFrame PointLightShader(VertexToPixel PSIn) : COLOR0
{
	PixelToFrame Output = (PixelToFrame)0;

	float3 normal = tex2D(NormalMapSampler, PSIn.TexCoord).rgb;
	normal = normal*2.0f-1.0f;
	normal = normalize(normal);

	float depth = tex2D(DepthMapSampler, PSIn.TexCoord);

	float3 pixelPosition;
	pixelPosition.x = screenWidth * PSIn.TexCoord.x;
	pixelPosition.y = screenHeight * PSIn.TexCoord.y;
	pixelPosition.z = depth;
	//pixelPosition.w = 1.0f;

	float3 shading;
	if (depth > 0)
	{
		float3 lightDirection = lightPosition - pixelPosition;
		float distance = 1 / length(lightPosition - pixelPosition) * lightStrength;
		float amount = max(dot(normal + depth, normalize(distance)), 0);

                float coneAttenuation = saturate(1.0f - length(lightDirection) / lightRadius);

		shading = distance * amount * coneAttenuation * lightColor;
	}

	Output.Color = float4(shading.r, shading.g, shading.b, 1.0f);
	return Output;
}

technique DeferredPointLight
{
    pass Pass1
    {
	VertexShader = compile vs_2_0 VertexToPixelShader();
        PixelShader = compile ps_2_0 PointLightShader();
    }
}

The result you get should be somewhat similar to the following image:

[pictureframe image="http://www.soolstyle.com/wp-content/uploads/2010/02/Lightning004.png" align="left" lightbox="true" title="" link="" width="300" height="224"]

Our next step involves in combining the Lightning map you just created with the Color Map from our first step. This process will be done through our second shader. This shader will only be a Pixel Shader because i had some problems rendering in inside a full screen quad. The whole image would become blurry and now with only the Pixel Shader in effect results in a clean outcome.

The follow shader is just a simple shader that combines the two textures with each other.

LightningCombined.fx

float ambient;
float4 ambientColor;
float lightAmbient;

Texture ColorMap;
sampler ColorMapSampler = sampler_state {
	texture = <ColorMap>;
	magfilter = LINEAR;
	minfilter = LINEAR;
	mipfilter = LINEAR;
	AddressU = mirror;
	AddressV = mirror;
};

Texture ShadingMap;
sampler ShadingMapSampler = sampler_state {
	texture = <ShadingMap>;
	magfilter = LINEAR;
	minfilter = LINEAR;
	mipfilter = LINEAR;
	AddressU = mirror;
	AddressV = mirror;
};

float4 CombinedPixelShader(float4 color : COLOR0, float2 texCoords : TEXCOORD0) : COLOR0
{
	float4 color2 = tex2D(ColorMapSampler, texCoords);
	float4 shading = tex2D(ShadingMapSampler, texCoords);

	float4 finalColor = (color2 * ambientColor * ambient);

	finalColor += color2 * shading * lightAmbient;

	return finalColor;
}

technique DeferredCombined
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 CombinedPixelShader();
    }
}

The actual drawing:

private void DrawCombinedMaps()
{
    _lightEffect2.CurrentTechnique = _lightEffect2.Techniques["DeferredCombined"];
    _lightEffect2.Parameters["ambient"].SetValue(_ambientPower);
    _lightEffect2.Parameters["ambientColor"].SetValue(_ambientColor.ToVector4());

    // This variable is used to boost to output of the light sources when they are combined
    // I found 4 a good value for my lights but you can also make this dynamic if you want
    _lightEffect2.Parameters["lightAmbient"].SetValue(4);
    _lightEffect2.Parameters["ColorMap"].SetValue(_colorMapTexture);
    _lightEffect2.Parameters["ShadingMap"].SetValue(_shadowMapTexture);

    spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.None);
    _lightEffect2.Begin();
    foreach (var pass in _lightEffect2.CurrentTechnique.Passes)
    {
        pass.Begin();

        spriteBatch.Draw(_colorMapTexture,Vector2.Zero,Color.White);

        pass.End();
    }
    _lightEffect2.End();
    spriteBatch.End();
}

You see that i draw the effect onto the scene just by using a spritebatch and drawing the color map onto the screen. This way i can just use the Pixel shader to draw the effect onto the screen, as i said before the full screen quad blurred my image and made it look bad. I guess there is a fix for this but i didn’t encounter it yet.

Now you should have the desired effect drawn onto your screen like in the images i posted at the beginning of this blog post. Please note that this is just the beginning and i am very sure that i can have some improvements here and stere, but i just wanted to share what i got right now with you all. If you encounter any difficulties applying this effect, please let me know and maybe we can find a solution for it :).

I hope you found this post usefull, until the next time :D.

Spotlights:

I just finished up my SpotLight implementation. It currently looks like this:

[pictureframe image="http://www.soolstyle.com/wp-content/uploads/2010/02/Lightning009.png" align="left" lightbox="true" title="" link="" width="300" height="224"]

36 Comments

  • Vinnie says:

    Edit: Added a screenshot of a Spotlight implementation.

    LightningShadow.fx
    from: float coneAttenuation = pow(distance, lightDecay);
    to: float coneAttenuation = saturate(1.0f – length(lightDirection) / lightRadius);
    and adjusted some variables to reflect this change.

  • Dustin Tigner says:

    I found this very inspirational. I feel like I’m not pushing myself enough and should do more. Thank you for motivating me and please continue to work hard!

    ~Dustin

    • Vinnie says:

      Im glad you like it Dustin and i hope you find implementing this technique not to hard :).

      Just note that the code does require some optimalizations and that it is just a beginning. Take the light for example, use the radius of the lights to see which lights are inside the screen and thus should render and which one’s aren’t.

  • Klinge says:

    Hi

    I really like your effect and tried to replicate it.
    However my _shadowMapRenderTarget.GetTexture() allways returns a texture that is just completely black.
    Do I need to modify anything inside GenerateShadowMap()
    method to make it work properly?
    Or are some of the properties for my light wrong?
    light = new Light() { Color = Color.Red, LightRadius = 1.0f, Power = 0.8f, WorldPosition = new Vector3(100,0,100) };

    Thx in advance and keep up the good work.

    • Klinge says:

      Nevermind, got it working.
      I just needed to increase the values for LightRadius and Power.

      • Vinnie says:

        Ah ok nice to hear you got it working :). I didn’t post a class overview of my lights because i was still working on them.

        While playing with the shader some time ago, i noticed that removing the +depth in the line
        float amount = max(dot(normal + depth, normalize(distance)), 0);
        will make the normal better visible.

        Also if the Spotlight is wanted i can post that as wel.

        Just let me know if there is anything i can help with :).

        Here is a screeny of my current state of the lightning:
        Lightning view

        • Klinge says:

          One thing I would like to know is how you change the intensity of a light. Something like the blinking red light in your video.
          The power variable just changes the radius. I also tried to change the alpha value in the shader but that didnt work.

  • Vinnie says:

    In reply for klinge:

    I just adjust the Power of a Light, like this property:

    public float ActualPower { get; set; }

    Now this property is corrisponding to the following value within the shader:

    lightEffect.Parameters[&quot;lightStrength&quot;].SetValue(light.ActualPower);

    Now in a update call within your light class, you can then just adjust the actualpower of that specific light just like this:

    float time = (float) gameTime.TotalGameTime.TotalMilliseconds*                          gameTime.ElapsedGameTime.Milliseconds*AnimationSpeed*0.0001f;
    _fadePower = (float) (Power*(float) Math.Abs(Math.Sin(_freqentie*time*2*Math.PI)));

    Now you should have a blinking light :).

  • Kristian says:

    Im curious about you did the spot light are you planning to post up snippets or a project, i would love to contribute.

  • Spotlight says:

    I would like to see some snippets or a project on how you did the spotlights thanks!!

  • Lumalalelo says:

    hey !
    really nice from you sharing such a cool thing ! :)
    I am wondering if that normal map way could also work with a 2d tileset (not a fixed scene) …or would this become utterly confused ? ^^

    • Vinnie says:

      In all my examples i only use tilesets. You just render your scene onto a rendertarget and use those textures for the effect and not the tilesets themself. You only use the tilesets to render your scene.

      • Lumalalelo says:

        so i just need to make a normal map
        from my tileset and use the same draw function for the normal map (the one that draws my rectangle to the scene)
        I suppose multiple layers wouldn’t be a problem either, right ? :)

        oh one more question mhh…i was looking for some material to understand your code more in depth (i am new to those kind of effects and understanding your approaches seams still difficult for me ^^)
        Is there some articles in the www for this particular issue (2d) or some book you would recommend ?

        Anyways, keep the good work up and good luck for your project !

    • Vinnie says:

      Yes, you are right. My application also supports multiple layers, so i dont really see any problem there.

      I dont really have a adres you can visit to learn more about it in depth, i just learned it myself by just start coding and see what it does (ofcourse append to wikipedia for some general knowledge about some topics.

      Cheers! :)

      • Lumalalelo says:

        okay ! :)
        i played a little around with your sample(implemented a tile-engine that supports multiple layers)

        Everything works !
        However, i wonder if it is possible, that the point-light itself would only affect certain layers…like i have a tree(second layer) on top of my groundlayer, so that the lightdot inclusive its light radius only affects the ground layer (hidden behind the tree).
        Right now the light is always on top of everything.

        i know that the light uses the Z-axis as its height (my layers don’t have this z-component since it is a 2D game) so i really wonder if there is an easy approach for that issue :)

        • Vinnie says:

          The only easy way for this as i see it right now (quickly), is that you create multiple colormaps from your layers and then only use the one you want for the lights and after it combine all the maps. This way you can have control over what the light affects and what not. Else if you use the depthmaps, the complete black area’s shouldn’t be affected by any light as wel.

          • Lumalalelo says:

            Thank you for your reply, that was really helpfull and i might try it out !

            ..Well i am kind of sorry i am asking so much but i got another (maybe big) questions ^^;

            It’s about the Verticies.
            I tried to get the idea what it is and what it does so i googled around.
            As i understand it it’s to manipulate the polygon edges with help from the vertex shader in 3d games.

            As i understand it in your case is that you use it to define the 3d space for the source of your light for the vertex shader because the pixel
            shader is only capable to manipulate the pixels on the texture and can’t manipulate any 3d stuff.

            So here i copy all the sourcecode snippets that i am not sure of how it works
            (in the comments over the source-snippets i write how i interpret it, which might be utterly wrong :) )

            Btw. I copied this reply from a textfile so it’s propably the best to look at it in such a file, i am sorry for that.

            //How did you come up with those values for the verticies ? ( i get really strange still funny effects when i change it :) )
            //Why did you define 4 Verticies ?
            //What do the Verticies represent (the position for the light source ? )

            Vertices = new VertexPositionTexture[4];
            Vertices[0] = new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0));
            Vertices[1] = new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0));
            Vertices[2] = new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1));
            Vertices[3] = new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1));

            //So this is to finally apply all the Verticies, that you have been defined for the vertex shader ?

            VertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPositionTexture.VertexElements);

            //So this is really new to me (only used the SpriteBatch to draw my stuff up to now)

            GraphicsDevice.VertexDeclaration = VertexDeclaration;

            //As i understand it you use the “Verticies” to project the effect you have been loading from you fx file
            //and apply it onto the “PrimitiveType.TriangleStrip” which propably
            //works as the destination rectangle in the spritBatch.Draw method
            //I tried the other PrimitiveType also but TriangleStip seams to be the only one that works correctly

            GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, Vertices, 0, 2);

            It would really nice if you could help me to understand these parts of the code.
            Thank you very much in advance !

          • Lumalalelo says:

            Sorry for this ugly last post with that many stupid questions about Verticies and stuff !
            I made some researches about those issues and got the hang to it ! :)
            (of course you can delete my last post if you want / if possible)

  • Vinnie says:

    @Lumalalelo. Those vertices are used to draw a quad onto the screen rather then a spritebatch draw. I define four of them for each corner. I used a quad because i couldn’t get the desired results by using the spritebatch. Maybe with a few changes here and there you can work it out, but for now i just keep using the quad. If you really want to learn more about the vertices and the DrawUserPrimitives, you might want to check the msdn site because they can give you more info on the subject then i can :).

  • Fermin says:

    Thank you very much for sharing all your work here. Your game is one of the most awesome looking 2d game i’ve ever seen for XNA, so it’s pure gold to have the code from it !

    Gonna try this out as soon as i have time, but im sure its going to be badass !

  • Marko says:

    Hi,
    First of all, thank you 1000 times, I had a problem with lights in 2D because of SpriteBatch problems with ps_3.0, so I was limited to ps_2.0 (only 2-3 light supported), but yours approach is great (and complicated, at least for me) :D

    But I still have some questions :)
    How do I make a depth view texture?

    And if it’s not a secret, how did you make a flashlight that robot in your game uses? By flashlight I mean the shape of the light, it’s not a circle…

    Thanks one more time :)

    • Vinnie says:

      Hey marko, i am glad that you like it. The depthmap texture you can easely create yourself. It just uses the same rendering as your normal texture, only then with a black and white texture. These black and white areas define the parts that should be visible for the lights or not.

      For the spotlight, i didn’t explain on how to do such a thing in the tutorial here because i wanted the people that use this inside their code also do a part on their own. If you really cant figure it out, i can always help you out :).

      • Marko says:

        Thanks for answering :)

        I figured out how to make depth textures, and now it works :)

        “For the spotlight, i didn’t explain on how to do such a thing in the tutorial here because i wanted the people that use this inside their code also do a part on their own. If you really cant figure it out, i can always help you out .”

        Yeah I really tried in the last week or so to get this thing to work but without success, I don’t like giving up, but this thing just boggles my mind (I have very little experience in game dev (I’m PHP, Java, .NET kind a guy)) :(

        Anyway, I think that I need to do something with these lines of code to get some shape other than circle, but I get some kind of ellipse but it’s no good)
        “pixelPosition.x = screenWidth * PSIn.TexCoord.x;
        pixelPosition.y = screenHeight * PSIn.TexCoord.y;”

        Other than that I tried rotating the light with mouse (like you), but again without success…
        I passed X,Y coordinates of the mouse to the shader (LightningShadow.fx), and with some trigonometry calculations tried rotating it, but again it starts to behave very weird.

        I really don’t like asking for help, but 2D XNA/Shaders community isn’t very big, so if you can at least tell me, am I on the right path, or am I doing it totally wrong. :D

  • Vinnie says:

    Marko,

    You shouldn`t be messing with the pixelposition to get a cone like light. What you should figure out is how to use the Cosines of angles. You have a direction vector and a light vector. Look into the dot product.

    If you take a reading on that topic, you should be able to figure it out :).

  • Jean says:

    Damn, this is very hot…but instead of copy&paste i would like to understand all this in detail… im very new to xna and graphics programming but i already understand the basics… for example i have no idea whats happening with that vertexpositions and why they there… also the hlsl code in fact is a mystery for me…i see i calculate distances and so but…but hell…would you like to help me there or do you know resources that explain all this math? thank you so much!

    • Jean says:

      Okay sorry if i may spam…i’ve now a good idea of color,height and normal…i also figured out the VertexPositionTexture thing… but why there negatives in? i thought the screen reaches from 0 to 1 not from -1 to 1 ?

  • Ryan says:

    I would like to say thank you for creating something like this and allowing the community to learn from your work.

    I am a beginner and am having some trouble though with trying to learn from your code. I currently got up to where you draw the Colormap and I get a purple screen. I am completely lost since I am no Shader expert at all and I am still trying to learn the basics.

    I am getting stuck here in the draw method

    GraphicsDevice.Clear(Color.CornflowerBlue);
    GraphicsDevice.SetRenderTarget(_colorMapRenderTarget);

    GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Transparent, 1, 0);

    //Draw Scene Here
    spriteBatch.Begin();
    spriteBatch.Draw(clash, Vector2.Zero , Color.White);
    spriteBatch.End();
    //reset the render target
    GraphicsDevice.SetRenderTarget(null);

    It only seems to draw the texture when I comment out the line GraphicsDevice.SetRenderTarget(_colorMapRenderTarget);

    Please help D’:

    • Vinnie says:

      First of, take note that this cod is not for xna 4.
      Second, it will be hard to tackle exactly what your problem here is based only on a few lines of code. I do can remember i to had such problem, but i cant recall what was cousing it. You can always check what is happing in the rendertargets:

      public static void DrawDebugRenderTargets(SpriteBatch spriteBatch)
              {
                  // Draw some debug textures
                  spriteBatch.Begin();
      
                  Rectangle size = new Rectangle(0, 0, _colorMapRenderTarget.Width / 4, _colorMapRenderTarget.Height / 4);
                  var position = new Vector2(0, Globals.GraphicsDevice.Viewport.Height - size.Height);
                  spriteBatch.Draw(
                      ColorMapRenderTarget,
                      new Rectangle(
                          (int)position.X, (int)position.Y,
                          size.Width,
                          size.Height),
                      Color.White);
      
                  spriteBatch.Draw(
                      DepthMapRenderTarget,
                      new Rectangle(
                          (int)position.X + size.Width, (int)position.Y,
                          size.Width,
                          size.Height),
                      Color.White);
      
                  spriteBatch.Draw(
                      NormalMapRenderTarget,
                      new Rectangle(
                          (int)position.X + size.Width * 2, (int)position.Y,
                          size.Width,
                          size.Height),
                      Color.White);
      
                  spriteBatch.Draw(
                      ShadowMapRenderTarget,
                      new Rectangle(
                          (int)position.X + size.Width * 3, (int)position.Y,
                          size.Width,
                          size.Height),
                      Color.White);
      
                  spriteBatch.End();
              }
      

      Something like that (xna 4.0 code).

      Sorry that i cant look it up in my own code, as i am using the lighting from my last blog post. I can always help you, but then i need more code :).

  • Gustavo says:

    Hello, very nice post!
    And i agree that is the best over looking xna game that i ever seen!
    i would like to know if you could share some sample showing how did you make the map with colision…
    I’m trying to use farseer engine… but no success yet… i have an object(box) and an secound object(player) and they are working well… but i don’t have any ideas of how create the map…
    how to set where the player can walk…. and how to place the texture togeter

    thank you for any help! And again… your game is great!!!!

    • Vinnie says:

      The collision on the maps are created using the farseer engine (just as you do now). At the generation of my map i look for my wall type (these are all 64*64 tiles) and i will create a collision object for this.

      No clue what you mean by “how to place the texture together”.

      Cheers for liking the game though :).

  • Impressive shading, and thanks a bunch for sharing this out! I’ve just begun experimenting with XNA, and this helped me out a LOT. +1! :D

  • Andrew says:

    Hello :D
    i would love to see the spotlight…i made it on my own but i have some problems, if u have time, please contact me, thanks. Great posts, made me enter this new world of shaders :D .

  • Jos says:

    First of let me thank you for sharing this incredible 2D lighting engine. It has allowed me to really upgrade the visual effects of my games.

    I am however unable to figure out how to implement a spotlight (2D representation of a character holding a flashlight to illuminate the area ahead). The XNA4.0 example seems to be equiped only to handle pointlights.

    How can I create a spotlight/flashlight effect in this system?

    Again, greatly appreciate you sharing this great lighting system.

    • admin says:

      Hey Jos,
      I am glad that you like the lighting :). Hopefully one day in this week i will be able to write a new post about that spotlight part of the code, it isn’t that much code so i reckon i will find some time for it :).

Leave a Reply