2
\$\begingroup\$

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.

\$\endgroup\$

2 Answers 2

6
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ 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? \$\endgroup\$
    – Califer
    Commented Jul 2, 2011 at 23:08
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jul 3, 2011 at 3:58
  • \$\begingroup\$ (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.) \$\endgroup\$ Commented Jul 3, 2011 at 3:59
  • \$\begingroup\$ (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.) \$\endgroup\$ Commented Jul 3, 2011 at 4:02
  • \$\begingroup\$ Sorry for the late response. Post-process was exactly what I needed! \$\endgroup\$
    – Califer
    Commented Jul 6, 2011 at 1:46
1
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jul 2, 2011 at 1:53
  • \$\begingroup\$ My assumption was bad, thanks. Gave you a one-up for your answer below. \$\endgroup\$ Commented Jul 2, 2011 at 4:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .