シーン全体をグレースケールにフェードさせる


20

プレイヤーがすべての命を失ったとき、ゲーム画面全体をグレースケールにしたいが、すぐに更新を停止したくない。また、突然すべての色が失われるのではなく、グレースケールにフェードインすることを好みます。私がこれまでに見つけたのは、スクリーンショットを撮ってグレースケールにするか、特定のテクスチャをグレースケールにすることです。すべてを繰り返すことなく、競技場全体とその中のすべてのオブジェクトをグレースケールに変更する方法はありますか?

回答:


23

これを行う最も簡単な方法は、シェーダーを作成することです(以下のコードを参照)。すべてをレンダーターゲットに描画し、シェーダーを使用してバックバッファーに描画します

プレイヤーが死亡したときのゲームコードレコードでは、その後のレンダリングでは、シェーダーパラメーターを1(フルカラー)から0(フルグレースケール)の間で補間します。
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();
    }
}

0.3、0.59、および0.11の理由は、人間の目が色を等しく扱わないためです。これらの値は、より良いグレースケール画像を提供します。


しばらく前にrgbをグレーに変換していましたが、信頼できるソースが見つからなかったため、1.0 / 3,1.0 / 3,1.0 / 3を使用しました...数値定数0.2,0.59,0.11のソースを提供できますか?
トレバーボイドスミス

私はコードの入手元を見つけようとしましたが、見つけることができませんでした。以下は、異なる(しかしあいまいに似ている)値(0.222、0.707、0.071)を使用するValve Developerページです。
ジョージデュケット

1
以下は、Valve番号をサポートしているが両方をリストしている値のリファレンスです。poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9
アダム

1
stackoverflowの上のグレースケール係数についての質問があります:stackoverflow.com/questions/5311774/...は
Exilyth

XNA 4.0でこのシェーダーが機能していたことを確認できます
ロボブロブ

0

編集

それについて考えた後、何かに色合いを付けず、グラフィックスの元の色を使用すると、(以下に述べるように)描画されたオブジェクトのすべての色を白に設定された宣言されたColor変数に設定できます。(Color NoTint = Color.White;)そして、プレイヤーが生きていればゼロに等しいというLerp。NoTint Colorで描画されたすべてのオブジェクトは、Lerpingの対象にゆっくりと変化します(後述の補間レートに従って)。

ただし、異なるオブジェクトに異なる色合いがある場合、以下のforeachループ機能する可能性があります。

編集を終了

私の限られた知識では、これを試してみます:特定のオブジェクトを描くときに使用する色を宣言します。カラーcatColor = Color.Brownを選択し、すべてのゲームカラーをリストに追加します。

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

色合いなしで描画するアイテムに対してもこれを行うことができ、Color.WhiteをColor.Grayに変更できます。(Color NoTint = Color.Whiteのような名前を付け、描画されたすべてのオブジェクトに配置します)

これが役立つことを願っていますが、おそらくもっと良い方法があります!


1
-1これにより、画面全体が単色にフェードし、グレースケールになりません。グレースケールは、その明るさ(色が異なる明るさを持っていると認識する色)で色を測定します。
-doppelgreener

優れた。私がやったように、他の誰かがこれから学ぶことを願っています。ありがとう!
アンドリューアキレス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.