Die gesamte Szene wird in Graustufen ausgeblendet

20

Wenn der Spieler sein ganzes Leben verliert, möchte ich, dass der gesamte Spielbildschirm in Graustufen angezeigt wird, die Aktualisierung jedoch nicht sofort beendet wird. Ich würde es auch vorziehen, wenn es in Graustufen ausgeblendet wird, anstatt plötzlich alle Farben zu verlieren. Alles, was ich bisher gefunden habe, besteht entweder darin, einen Screenshot zu machen und ihn in Graustufen darzustellen, oder eine bestimmte Textur in Graustufen. Gibt es eine Möglichkeit, das gesamte Spielfeld und alle Objekte in Graustufen zu ändern, ohne alles durchlaufen zu müssen?

Fibericon
quelle

Antworten:

23

Der einfachste Weg, dies zu tun, besteht darin, einen Shader dafür zu erstellen (siehe Code unten). Zeichnen Sie alles auf ein Rendering-Ziel und zeichnen Sie es dann mit dem Shader in Ihren Backbuffer

Wenn der Spieler stirbt, interpolieren Sie in Ihrem Spielcode-Datensatz in nachfolgenden Renderings einen Shader-Parameter zwischen 1 (Vollfarbe) und 0 (Vollgrauwert) entsprechend
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();
    }
}

Der Grund für die Werte 0,3, 0,59 und 0,11 liegt darin, dass das menschliche Auge Farben nicht gleich behandelt. Diese Werte ergeben ein besseres Graustufenbild.

George Duckett
quelle
Vor einiger Zeit habe ich RGB in Grau konvertiert, konnte aber keine verlässliche Quelle finden, also habe ich nur 1.0 / 3,1.0 / 3,1.0 / 3 verwendet ... Können Sie eine Quelle für die numerischen Konstanten 0.2,0.59,0.11 angeben?
Trevor Boyd Smith
Ich habe versucht herauszufinden, woher ich den Code habe, konnte ihn aber nicht finden. Hier ist ein Ventil Entwickler Seite , die verschiedene verwendet (aber vage ähnlich) Werte (0,222, 0,707, 0,071).
George Duckett
1
Hier ist eine Referenz für die Werte, die die Ventilnummern unterstützen, aber beide auflisten. poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9
Adam
1
Es gibt eine Frage zu den Graustufenkoeffizienten bei Stackoverflow: stackoverflow.com/questions/5311774/…
Exilyth
Ich kann bestätigen, dass dieser Shader für mich in XNA 4.0
Roboblob
0

BEARBEITEN

Nachdem Sie darüber nachgedacht haben, können Sie, wenn Sie nichts einfärben, aber die Originalfarben der Grafik verwenden, alle Farben der gezeichneten Objekte auf eine deklarierte Farbvariable setzen, die auf Weiß gesetzt ist (siehe unten). (Color NoTint = Color.White;) und dann Lerp, dass, wenn der Spieler lebt, gleich Null ist. Jedes mit der NoTint-Farbe gezeichnete Objekt ändert sich langsam (entsprechend der unten angegebenen Interpolationsrate) in das Objekt, in das Sie es einfügen.

Wenn Sie jedoch unterschiedliche Farbtöne für verschiedene Objekte haben, funktioniert die folgende foreach-Schleife möglicherweise .

Bearbeiten beenden

In meinem begrenzten Wissen würde ich Folgendes versuchen: Deklarieren Sie die Farben, die Sie beim Zeichnen bestimmter Objekte verwenden, z. Color catColor = Color.Brown, und fügen Sie dann alle Farben Ihrer Spiele zu einer Liste hinzu.

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

Sie können dies sogar für Elemente tun, die Sie ohne Farbton zeichnen, und die Color.White auf Color.Gray setzen. (Nennen Sie das etwas wie Color NoTint = Color.White und setzen Sie das auf alle Ihre gezeichneten Objekte)

Es gibt wahrscheinlich einen besseren Weg, auch wenn ich hoffe, dass dies hilft!

AndrewAchilles
quelle
1
-1 Dadurch wird der gesamte Bildschirm auf eine Farbe ausgeblendet, nicht auf Graustufen. Graustufen messen eine Farbe an ihrer Helligkeit (wobei die Farbe unterschiedliche Farben als unterschiedlich hell wahrnimmt). Sie liegt nicht nur auf halber Strecke zwischen einer Farbe und Grau (das immer noch Farbe hat).
Doppelgreener
Ausgezeichnet. Ich hoffe, jemand anderes lernt so wie ich daraus. Vielen Dank!
AndrewAchilles