Understanding C# 2D XNA HLSL – Part 2

Read the first part here

I know a lot of you loved the first part of this breakdown, and now I’m back to continue the explaining!

Breakdown of Effect Parameter

Continuing from the end of the first part: What the effect parameter does here is that it takes our effect and then applies it to all of the textures that you draw then on. This is effective for coloration effects such as black and white, or inverting colors, but if you have an effect that works based on certain coordinates or is constricted similarly, then you need to beĀ  very careful! To avoid issues like that, there is a rather simple solution when you want to apply an aforementioned size/position constricted effect to the screen.

Further Implementation

Adjusting the Effect parameter of the SpriteBatch.Begin() function is not the only way to use HLSL effects in your projects. Another method that you can do is draw all of your textures to one RenderTarget2D (Think of this as an empty texture, or a blank canvas). After you’ve drawn all your textures to that, it’s really easy to apply your effect to “the screen”.

RenderTarget2D MainTexture;

//In the Initialize function set up the rendertarget:
PresentationParameters pp = GraphicsDevice.PresentationParameters;
MainTexture = new RenderTarget2D(GraphicsDevice, pp.BackBufferWidth, pp.BackBufferHeight);

        //Then create a function to draw your game textures to, and draw it all up       

        private void DrawGame(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(MainTexture);
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.Draw(bg, GraphicsDevice.Viewport.Bounds, Color.White);
            spriteBatch.Draw(player, new Vector2(200, 300), new Rectangle(0, 0, 128, 128), Color.White);

            spriteBatch.End();

            GraphicsDevice.SetRenderTarget(null);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            DrawGame(gameTime);

            GraphicsDevice.Clear(Color.Black);

            // Use Immediate mode and our effect to draw the scene again, using our pixel shader.
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

            mainEffect.CurrentTechnique.Passes[0].Apply(); // for every pass that you have you can apply
                                                           // all them to the texture if you want.
            spriteBatch.Draw(MainTexture, Vector2.Zero, Color.White);

            spriteBatch.End();

            base.Draw(gameTime);
        }
    }

Alternatively, you can use the effect parameter in the spriteBatch.Begin() function when drawing MainTexture, because remember: The effect is applied to the texture in every Draw() function call. If you only have to draw one texture and want all the passes applied when drawn, then you can use the Effect parameter.

Why do this?

In a project I was working on I really wanted to have an INFINITE amount of 2D lights in my game, and after countless attempts at getting a high number lights (higher than 5) from all HLSL effects, I found that by drawing a my lights to a texture, and then my game to another, I could then use an HLSL effect to blend my lights together.

 

I hope this helped.

-Tom

Minecraft-Style Engine in XNA 4.0

Hey gang,

So lately I’ve been messing around with creating a minecraft-styled engine in XNA 4.0. Currently I think it’s going really well. Check it out and let me know what you think:

One of the most important things about this project for me is optimization. What’s great about minecraft is that there are so many things on the screen and there is virtually no lag at all. This isn’t just about me making a minecraft clone, I really want to become better at working in large environments, and allowing them to run as fast as they can!

Understanding C# 2D XNA HLSL

Introduction

Firstly, what is HLSL? What can we use it for? HLSL is an acronym for High-Level Shader Language, and because it is a shader language, it runs on the GPU of the computer. With HLSL you can perform many post-processing effects, such as: blur, point lights, black and white, bloom, and pretty much any filter you can think of that can be done in Adobe Photoshop.

When working with HLSL on the Xbox 360, you are limited to using Pixel Shader 2.0 (This way you can support all Xbox’s) rather than 3.0, which isn’t terribly bad, but it could be so much better. You can do a lot with pixel shader 2.0 with up to 64 mathematical operations per-pixel. Because it is a pixel shader, the code that you write will be executed on every single pixel that is on the texture you’re working with. If your game resolution is 720×360, totalling to 259200 pixels, and if you have 3 mathematical operations per pixel (for example you are using sin, cos, and +), totalling to 777600 mathematical operations done for every time this shader code is ran (typically the total amount of times you draw the effect to the screen).

 

Examples

Nearly any filter that can be done in photoshop can be done with a shader. So, check out an example (more to come):

Radial Blur Example
fig. 1.0: Radial Blur

Continue reading “Understanding C# 2D XNA HLSL”

Zong, pong for the Zune

Well, this is a little pong game for the Zune that I whipped up. There’s probably a better way of doing this, but I just ported it from this guy’s source code:

Flaim – PONG in AS3 in ~ 1KB

Now, here is the source code for Zong (you need visual C# and xna 3.0 beta to open and run it):

[Zong.zip – Source Code]

Have fun, and if you can fix the enemy paddle’s shakyness, post a comment!

Thanks