Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a 2D game that ends up being too dark on some laptops, so I figured I'd use a shader so people could brighten it up if need be. Unfortunately, once I got it in there nothing would fade in or out, they'd just pop in and out.

Here's my FX file

float intensity;

sampler TextureSampler : register(s0);

float4 Glow(float2 texCoord:TEXCOORD0):COLOR0
{
    float4 Color;
    Color = tex2D(TextureSampler, texCoord.xy);
    Color.rgb *= intensity;
    return Color;
}

technique Technique1
{
    pass Glow
    {
        PixelShader=compile ps_2_0 Glow();
    }
}

Even after commenting out the Color.rgb *= intensity; line it still removes all fading effects.

I'm using the sprite batch to draw, and I begin and end it a few times because I use different BlendStates

brightnessShader.Parameters["intensity"].SetValue(brightness);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, brightnessShader, Matrix.CreateScale(scale));
...
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Additive, null, null, null, brightnessShader, Matrix.CreateScale(scale));
....
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, brightnessShader, Matrix.CreateScale(scale));
...
spriteBatch.End();    

I'm using XNA 4.0.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

SpriteBatch passes in both a colour (containing an alpha/transparency value) and a texture coordinate. You need to use the colour parameter. Here is the XNA SpriteBatch pixel shader (from XNA 2.0)

void SpritePixelShader(inout float4 color : COLOR0, float2 texCoord : TEXCOORD0)
{
    color *= tex2D(TextureSampler, texCoord);
}

So your shader would need to be something like this:

void SpritePixelShader(inout float4 color : COLOR0, float2 texCoord : TEXCOORD0)
{
    color *= tex2D(TextureSampler, texCoord);
    color.rgb *= intensity;
}

Also be aware of premultiplied alpha, which was added in XNA 4.0. Simply multiplying the RGB values may give you a result that is different to what you actually want to achieve.

Probably a better solution to your problem would be to render your entire scene as normal to a render target, and then gamma-correct that render target using a post-process pixel shader.

share|improve this answer
    
Thanks for the advice! What is the difference (code-wise) between a regular shader like I'm using and a post-process pixel shader? Is it simply that I only run it when I'm displaying the render target after everything's been drawn to it? Also, I was under the impression that changing gamma wasn't available in XNA 4.0. Is there a way that you know of? –  Califer Jul 2 '11 at 23:08
    
@Califer there's no difference in the way that shading works. You're still running a standard pixel shader. The difference is in the way you render. You render your entire scene to a render target, and then you render that render target as a full-screen quad to the screen, via your post-process pixel shader. The "Bloom Postprocess" sample demonstrates how to do this for bloom. All you have do to is find out an algorithm for doing gamma correction. –  Andrew Russell Jul 3 '11 at 3:58
    
(Alternately, I'm pretty sure most graphics cards offer gamma correction at the output stage - but, you're quite right, XNA doesn't give you a method to access this.) –  Andrew Russell Jul 3 '11 at 3:59
    
(Of course if you're happy to do color.rgb *= intensity; as your brightness fix-up, then you're still probably better off doing this as a post-process effect.) –  Andrew Russell Jul 3 '11 at 4:02
    
Sorry for the late response. Post-process was exactly what I needed! –  Califer Jul 6 '11 at 1:46
add comment

If your source bitmap is compressed with DXT1 you'll only get 1bit of alpha, on or off. DXT3 is a little better with 4bit so 16 total alpha values.

share|improve this answer
    
The number of bits of alpha is only relevant to the stored texture. Once you load it, it works like any other texture and all calculations have the full range of alpha values. Also the default is uncompressed textures, and I doubt Califer changed that. –  Andrew Russell Jul 2 '11 at 1:53
    
My assumption was bad, thanks. Gave you a one-up for your answer below. –  Patrick Hughes Jul 2 '11 at 4:34
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.