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.

When the player loses all of their lives, I want the entire game screen to go grayscale, but not stop updating immediately. I'd also prefer it fade to grayscale instead of suddenly lose all color. Everything I've found so far is either about taking a screenshot and making it grayscale, or making a specific texture grayscale. Is there a way to change the entire playing field and all objects within to grayscale without iterating through everything?

share|improve this question

2 Answers 2

up vote 23 down vote accepted

The easiest way to do this is to create a shader for it (See code below). Draw everything to a render target, then use the shader to draw that to your back buffer

In your game code record when the player dies, then in subsequent renders interpolate a shader parameter between 1 (full colour) and 0 (full grey-scale) according to
CurrentTime-DeadTime / FadeTime

float ColourAmount;
Texture coloredTexture;

sampler coloredTextureSampler = sampler_state
{
    texture = <coloredTexture>;
};

float4 GreyscalePixelShaderFunction(float2 textureCoordinate : TEXCOORD0) : COLOR0
{
    float4 color = tex2D(coloredTextureSampler, textureCoordinate); 
    float3 colrgb = color.rgb;
    float greycolor = dot(colrgb, float3(0.3, 0.59, 0.11));

    colrgb.rgb = lerp(dot(greycolor, float3(0.3, 0.59, 0.11)), colrgb, ColourAmount);

    return float4(colrgb.rgb, color.a);
}

technique Grayscale
{
    pass GreyscalePass
    {
        PixelShader = compile ps_2_0 GreyscalePixelShaderFunction();
    }
}

The reason for the 0.3, 0.59 and 0.11 is because the human eye doesn't treat colours equally, those values give a better greyscale image.

share|improve this answer
    
A while back I was converting rgb to gray but could not find a reliable source so I just used 1.0/3,1.0/3,1.0/3 ... Can you provide a source for the numerical constants 0.2,0.59,0.11? –  Trevor Boyd Smith Mar 19 '12 at 12:12
    
I have been trying to find where I got the code from, but haven't been able to find it. Here is a Valve Developer page that uses different (but vaguely similar) values (0.222, 0.707, 0.071). –  George Duckett Mar 19 '12 at 12:16
1  
Here's one reference for the values which supports the Valve numbers but lists both. poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9 –  Adam Mar 19 '12 at 13:08
1  
There's a question about the greyscale coefficients on stackoverflow: stackoverflow.com/questions/5311774/… –  sarahm Mar 20 '12 at 23:54
    
i can confirm this shader worked for me in XNA 4.0 –  Roboblob Apr 3 '13 at 13:51

EDIT

After thinking about it, if you are not putting a tint on anything, but using the graphics original colors you could just have (like I state down below) all your colors of drawn objects set to a declared Color variable set to white. (Color NoTint = Color.White;) and then Lerp that if player lives is equal to zero. Every object drawn with the NoTint Color will slowly change (according to your interpolation rate mentioned below) to whatever you are Lerping it to.

However if you do have different tints on different objects, the below foreach loop might work.

End Edit

In my limited knowledge I would try this: Declare the colors you use when drawing specific objects, ex. Color catColor = Color.Brown, then add all of your games colors to a list.

public static Color catColor = Color.Brown;
List<Color> colorList = new List<Color>(){ catColor }; // and other colors
float interpolation = 0f;
float interpolationRate = .01f;
.
.
.
if(playerLives == 0) 
{
   interpolation += interpolationRate;
   if (interpolation >= 1)
      {interpolation = 1;}

   foreach(Color c in colorList)
   {
      Color.Lerp(c, Color.Gray, interpolation);
   }
}

You can even do this for items you draw with no tint and Lerp the Color.White to a Color.Gray. (name that something like Color NoTint = Color.White, and put that on all your drawn objects)

There is probably a better way, regardless I hope this helps!

share|improve this answer
1  
-1 This would fade the entire screen to one solid colour, not turn it greyscale. Greyscale measures a colour by its brightness (with the colour perceiving different colours as having different brightnesses), it isn't just halfway between a colour and grey (which still has colour). –  doppelgreener Mar 19 '12 at 11:12
    
Excellent. I hope someone else learns from this as I did. Thanks! –  tigersnack Mar 19 '12 at 13:25

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.