ทำให้ฉากทั้งหมดจางหายไปเป็นสีเทา


20

เมื่อผู้เล่นเสียชีวิตไปทั้งหมดฉันต้องการให้หน้าจอเกมทั้งหมดเป็นสีเทา แต่ไม่หยุดอัปเดตทันที ฉันยังต้องการให้มันจางหายไปถึงระดับสีเทาแทนที่จะเสียสีไปในทันที ทุกสิ่งที่ฉันพบจนถึงขณะนี้คือเกี่ยวกับการจับภาพหน้าจอและทำให้เป็นสีเทาหรือทำให้เป็นสีเทาเฉพาะพื้นผิว มีวิธีที่จะเปลี่ยนสนามเด็กเล่นทั้งหมดและวัตถุทั้งหมดภายในเป็นสีเทาโดยไม่ต้องวนซ้ำทุกอย่างหรือไม่?

คำตอบ:


23

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือการสร้าง shader (ดูรหัสด้านล่าง) วาดทุกอย่างไปยังเป้าหมายการเรนเดอร์จากนั้นใช้ shader เพื่อวาดที่บัฟเฟอร์ด้านหลังของคุณ

ในบันทึกรหัสเกมของคุณเมื่อผู้เล่นเสียชีวิตจากนั้นในภายหลังทำให้การแก้ไขพารามิเตอร์ shader ระหว่าง 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 หรือไม่?
เทรเวอร์บอยด์สมิ ธ

ฉันพยายามค้นหาว่าฉันได้รับรหัสจากที่ไหน แต่ไม่สามารถหาได้ นี่คือหน้านักพัฒนา Valveที่ใช้ค่าที่แตกต่างกัน (แต่คล้ายกันอย่างคลุมเครือ) (0.222, 0.707, 0.071)
George Duckett

1
นี่คือการอ้างอิงหนึ่งสำหรับค่าที่รองรับหมายเลข Valve แต่แสดงรายการทั้งคู่ poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9
Adam

1
มีคำถามเกี่ยวกับสัมประสิทธิ์ greyscale ใน stackoverflow: stackoverflow.com/questions/5311774/…
Exilyth

ฉันสามารถยืนยัน shader นี้ได้สำหรับฉันใน XNA 4.0
Roboblob

0

แก้ไข

หลังจากคิดถึงเรื่องนี้แล้วหากคุณไม่ได้ใส่สีอะไรเลย แต่ใช้สีดั้งเดิมของกราฟิกคุณสามารถมี (เช่นที่ฉันเขียนลงไปด้านล่าง) สีทั้งหมดของวัตถุที่วาดที่ตั้งค่าเป็นตัวแปรสีที่ประกาศเป็นสีขาว (Color NoTint = Color.White;) จากนั้นให้ Lerp ว่าหากผู้เล่นมีชีวิตอยู่เท่ากับศูนย์ วัตถุทุกชิ้นที่วาดด้วยสี NoTint จะเปลี่ยนอย่างช้าๆ (ตามอัตราการแก้ไขของคุณที่ระบุไว้ด้านล่าง) กับสิ่งที่คุณกำลัง Lerping

อย่างไรก็ตามหากคุณมีโทนสีที่แตกต่างกันในวัตถุที่แตกต่างกันลูป foreach ด้านล่างอาจทำงานได้

สิ้นสุดการแก้ไข

ในความรู้ที่ จำกัด ของฉันฉันจะลองสิ่งนี้: ประกาศสีที่คุณใช้เมื่อวาดวัตถุเฉพาะเช่น Color 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);
   }
}

คุณสามารถทำได้แม้กระทั่งสำหรับไอเท็มที่คุณวาดโดยไม่มีการแต้มสีและ Lerp the Color White to a Color.Gray (ตั้งชื่อสิ่งที่ต้องการ Color NoTint = Color.White และวางลงบนวัตถุที่ถูกวาดทั้งหมดของคุณ)

อาจมีวิธีที่ดีกว่าไม่ว่าฉันหวังว่านี่จะช่วยได้!


1
-1 การทำเช่นนี้จะทำให้หน้าจอทั้งหมดจางลงเป็นสีทึบไม่เปลี่ยนเป็นเฉดสีเทา Greyscale วัดสีด้วยความสว่างของมัน (ด้วยสีที่รับรู้สีต่างกันว่ามีความสว่างต่างกัน) มันไม่ได้อยู่กึ่งกลางระหว่างสีกับสีเทาเท่านั้น (ซึ่งยังคงมีสีอยู่)
doppelgreener

ยอดเยี่ยม ฉันหวังว่าคนอื่นเรียนรู้จากสิ่งนี้เหมือนที่ฉันทำ ขอบคุณ!
AndrewAchilles
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.