Hacer que toda la escena se desvanezca a escala de grises

20

Cuando el jugador pierde toda su vida, quiero que toda la pantalla del juego pase a escala de grises, pero no deje de actualizarse de inmediato. También prefiero que se desvanezca a escala de grises en lugar de perder repentinamente todo el color. Todo lo que he encontrado hasta ahora se trata de tomar una captura de pantalla y hacerla en escala de grises, o hacer una escala de grises de textura específica. ¿Hay alguna manera de cambiar todo el campo de juego y todos los objetos dentro a escala de grises sin recorrer todo?

Fibericon
fuente

Respuestas:

23

La forma más fácil de hacer esto es crear un sombreador para él (ver el código a continuación). Dibuje todo en un objetivo de renderizado, luego use el sombreador para dibujar eso en su búfer posterior

En el registro del código del juego cuando el jugador muere, luego, en los renderizados posteriores, interpola un parámetro de sombreador entre 1 (a todo color) y 0 (escala de grises completa) de acuerdo con
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();
    }
}

La razón para el 0.3, 0.59 y 0.11 es porque el ojo humano no trata los colores por igual, esos valores dan una mejor imagen en escala de grises.

George Duckett
fuente
Hace un tiempo, estaba convirtiendo rgb a gris, pero no pude encontrar una fuente confiable, así que solo usé 1.0 / 3,1.0 / 3,1.0 / 3 ... ¿Puede proporcionar una fuente para las constantes numéricas 0.2,0.59,0.11?
Trevor Boyd Smith
He estado tratando de encontrar de dónde obtuve el código, pero no he podido encontrarlo. Aquí hay una página de Valve Developer que usa valores diferentes (pero vagamente similares) (0.222, 0.707, 0.071).
George Duckett el
1
Aquí hay una referencia para los valores que admite los números de válvula pero enumera ambos. poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9
Adam
1
Hay una pregunta sobre los coeficientes de escala de grises en stackoverflow: stackoverflow.com/questions/5311774/…
Exilyth
Puedo confirmar que este sombreador funcionó para mí en XNA 4.0
Roboblob
0

EDITAR

Después de pensarlo, si no está poniendo un tinte en nada, pero usando los colores originales de los gráficos, podría tener (como digo a continuación) todos sus colores de objetos dibujados configurados en una variable de Color declarada establecida en blanco. (Color NoTint = Color.White;) y luego Lerp que si el jugador vive es igual a cero. Cada objeto dibujado con el Color NoTint cambiará lentamente (de acuerdo con la velocidad de interpolación mencionada a continuación) a lo que sea que esté Lerping.

Sin embargo, si tiene diferentes matices en diferentes objetos, el siguiente bucle foreach podría funcionar.

Fin de edición

En mi conocimiento limitado, intentaría esto: declare los colores que usa al dibujar objetos específicos, ej. Color catColor = Color.Brown, luego agrega todos los colores de tus juegos a una lista.

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);
   }
}

Incluso puede hacer esto para los elementos que dibuja sin tinte y Lerp the Color.White to a Color.Gray. (nómbralo como Color NoTint = Color.White y ponlo en todos tus objetos dibujados)

Probablemente hay una mejor manera, independientemente de que espero que esto ayude.

AndrewAchilles
fuente
1
-1 Esto desvanecería la pantalla completa a un color sólido, no lo convertiría en escala de grises. La escala de grises mide un color por su brillo (con el color que percibe diferentes colores con diferentes brillos), no es solo a medio camino entre un color y un gris (que todavía tiene color).
doppelgreener
Excelente. Espero que alguien más aprenda de esto como lo hice yo. ¡Gracias!
AndrewAchilles