ฉันสามารถใช้เอฟเฟกต์แสงคบไฟ (บริเวณที่มีแสงสว่างรอบแหล่งกำเนิดแสง) ในเกม 2D ได้หรือไม่?


16

ฉันกำลังคิดที่จะเขียนเกม 2D ง่าย ๆ ให้กับตัวเอง มันจะไม่ส่องแสงด้วยกราฟิกหรือรูปแบบการเล่นเกมที่สมบูรณ์แบบในตอนแรก แต่ฉันคิดว่ามันเป็นก้าวแรกของฉันในการพัฒนาเกมพีซี ลองจินตนาการถึงเกม 2D ที่ใช้สไปรต์ง่าย ๆ (เช่น Heroes IV หรือ Startcraft BroodWar)

ฉันต้องการให้เกมเพลย์รองรับกลางวัน / กลางคืนด้วยการเปลี่ยนแปลงของแสงตามและในเวลาเดียวกันมันก็เป็นเรื่องบ้าที่จะต้องสร้างสไปรต์สำหรับแสงที่แตกต่างกันนิดหน่อย ดังนั้นฉันตัดสินใจเพิ่มเลเยอร์กึ่งโปร่งใสที่ด้านบนของวัตถุอื่นจะเพียงพอ

ปัญหาของการแก้ปัญหานี้คือถ้าฉันมีวัตถุกำเนิดแสงในเกม (เช่นฮีโร่ที่สวมไฟฉายหรือตึกที่ถูกไฟไหม้) ต้องมีพื้นที่ที่เบากว่าอยู่รอบ ๆ ใช่ไหม เมื่อฉันวางเลเยอร์กึ่งโปร่งใสของฉันไว้เหนือทุกสิ่งคุณจะแนะนำให้ใช้เอฟเฟกต์คบไฟที่ฉันต้องการได้อย่างไร อาจวาดใหม่ว่าเลเยอร์ที่เพิ่ม 'ช่องว่าง' หรือพื้นที่ที่มีสีต่างกันโดยขึ้นอยู่กับเอฟเฟกต์แสง


2
หน้ากากอาจเป็นหนทางไป
Gustavo Maciel

5
"Torchlight" ในชื่ออาจสร้างความสับสนเนื่องจากเกมชื่อ Torchlight
Tetrad

4
@ Tetrad ควรจะใช้ได้ตราบใดที่ไม่ได้เป็นตัวพิมพ์ใหญ่ สำหรับฉัน Torchlight ไม่ได้คิดอะไรอยู่จนกระทั่งอ่านความคิดเห็นของคุณ
famousgarkin

อย่างไรก็ตามฉันแนะนำให้แก้ไขเพื่อให้ชื่อเฉพาะเจาะจงมากขึ้น
famousgarkin

2
ความเป็นไปได้ที่ซ้ำกันของการใช้แสง 2D เป็นอย่างไร
bummzack

คำตอบ:


12

ฉันไม่รู้ว่าคุณกำลังเขียนโปรแกรมอะไรอยู่ แต่นี่เป็นวิธีที่ฉันจัดการใน XNA:

  1. ในการเรียกการดึงList<Light>วัตถุจะถูกสร้าง / ล้าง
  2. ในระหว่างการลากไทล์แต่ละไทล์จะถูกตรวจสอบเพื่อดูว่ามีไฟใด ๆ ที่เกี่ยวข้องหรือไม่ ถ้ามันไม่ที่วัตถุที่มีการผนวกเข้ากับLightList<Light>
  3. RenderTarget2Dกระเบื้องจะมีการวาดลงบนของตัวเอง
  4. หลังจากวนลูปไทล์รายการของLights ถูกทำซ้ำแล้ววาดด้วยตนเองRenderTarget2Dโดยใช้พื้นผิวที่ฉันทำเช่นนี้:
    พื้นผิวแสง(หมายเหตุ: ฉันใช้ค่า R, G และ B ที่นี่ แต่คุณควรใช้ช่องอัลฟาใน พื้นผิวจริง.)
  5. ใช้ shader ที่กำหนดเองฉันแสดงพื้นผิวของกระเบื้องไปยังหน้าจอและส่งผ่านพื้นผิวแสงเป็นพารามิเตอร์ซึ่งได้รับการสุ่มตัวอย่างสำหรับค่า "ความมืด" ที่แต่ละพิกเซล


ตอนนี้มีบางสิ่งที่ควรทราบ:

เกี่ยวกับจุดที่ 4:

จริง ๆ แล้วฉันมีสองเฉดสีที่กำหนดเองหนึ่งที่จะวาดแสงไปยังเป้าหมายแสงการแสดงผล (ขั้นตอนที่ 4) และอื่น ๆ เพื่อวาดเป้าหมายการแสดงผลกระเบื้องไปยังหน้าจอโดยใช้เป้าหมายแสงการแสดงผล (ขั้นตอนที่ 5)
Shader ที่ใช้ที่จุดที่ 4 ทำให้ฉันสามารถเพิ่ม (สิ่งที่ฉันเรียก) เป็นค่า "ความส่องสว่าง" ค่านี้เป็นค่าfloatที่คูณกับแต่ละพิกเซลในพื้นผิวก่อนที่จะเพิ่มไปยังเป้าหมายการเรนเดอร์เพื่อที่ฉันจะสามารถทำให้แสงสว่างขึ้นหรือมืดลงได้
ณ จุดนี้ฉันยังคำนึงถึงค่า "ระดับ" ของแสงซึ่งหมายความว่าฉันสามารถมีแสงขนาดใหญ่หรือขนาดเล็กที่ใช้เพียงพื้นผิวเดียว

เกี่ยวกับจุดที่ 5:

คิดว่าเป้าหมายการให้แสงนั้นมีค่าสำหรับแต่ละพิกเซลตั้งแต่ 0 (ดำ) ถึง 1 (สีขาว) Shader นั้นคูณด้วยค่านั้นกับค่า RGB สำหรับพิกเซลในการเรนเดอร์เป้าหมายเพื่อสร้างภาพที่วาดครั้งสุดท้าย

ฉันยังมีรหัสเพิ่มเติมที่นี่ที่ฉันผ่าน (เพื่อ shader) ค่าที่จะใช้เป็นสีซ้อนทับกลางวัน / กลางคืน สิ่งนี้จะถูกนำไปคูณกับค่า RGB และรวมอยู่ในการคำนวณการแสดงผลเป้าหมายแสง


ทีนี้สิ่งนี้จะไม่อนุญาตให้คุณทำสิ่งต่าง ๆ เช่นป้องกันแสงจากการไปรอบวัตถุและอะไรก็ตาม แต่อย่างน้อยสำหรับจุดประสงค์ของฉันมันง่ายและทำงานได้ดี

ฉันเขียนบทความบล็อกที่มีรายละเอียดมากขึ้นที่นี่และที่นี่ซึ่งอาจช่วยคุณได้ ฉันยังไม่มีเวลา แต่ถ้าคุณต้องการฉันสามารถดูรายละเอียดเพิ่มเติมที่นี่ใน gamedev

โอ้และนี่คือสิ่งที่ฉันเห็นในเครื่องมือแก้ไขแผนที่ของฉัน:ป้อนคำอธิบายรูปภาพที่นี่


สร้างและล้างรายการทุกเฟรมอาจไม่แพงเกินไปใช่ไหม
Gustavo Maciel

@Gtoknu ไม่ได้สร้างความแตกต่างที่เห็นได้ชัดในเกมของฉัน รายการนี้เป็นเพียงการอ้างอิงการอ้างอิงไปยังวัตถุที่มีอยู่แล้วในหน่วยความจำดังนั้นจึงไม่เหมือนแสงทุกครั้งที่ถูกสร้างขึ้นใหม่หรืออะไรก็ตามเพียงรายการเดียว
Richard Marskell - Drackir

คุณอาจจะใช่ แต่ไม่ใช่ทั้งหมด แน่นอนว่าคุณไม่ได้สร้างออบเจ็กต์แบบเต็ม แต่คุณกำลังเพิ่มพอยน์เตอร์ไปยังการอ้างอิงยังคงมีการใช้งานต่ำ แต่ยังคงสิ้นเปลือง คุณกำลังทำในทางที่ดี แต่ฉันคิดว่ามันอาจจะดีกว่าถ้าคุณใส่รายการนอกวิธีการวาดเนื่องจากทำลอจิกในการปรับปรุงเร็วกว่าในการวาด
Gustavo Maciel

@Gtoknu แน่นอนคุณสามารถประกาศรายการได้ทุกที่ที่คุณต้องการ แต่ประเด็นคือไฟที่เกี่ยวข้องกับกระเบื้อง Drawวิธีการเรียงต่อกันเป็นวิธีการที่คุณทราบว่าแผ่นมีแสงหรือไม่ ฉันไม่วนผ่านไทล์ที่ลากทั้งหมดในUpdateวิธีการดังนั้นฉันจะเพิ่มโอเวอร์เฮดพิเศษสำหรับสิ่งนั้น นอกจากนี้ XNA พยายามรับประกันว่าUpdateจะถูกเรียก 60 ครั้งต่อวินาทีดังนั้นจึงอาจเสียสละDrawเรียกสิ่งนี้ซึ่งหมายความว่ารหัสนี้จะถูกเรียกน้อยกว่าจริง ๆ
Richard Marskell - Drackir

ทั้งหมดที่กล่าวมาเป็นจุดที่สงสัยเพราะในที่สุดฉันก็ย้ายแสงไปยังรายการของพวกเขาเองตามการแบ่งเชิงพื้นที่และเพิ่งดึงแสงทั้งหมดในส่วนที่ตัดกับหน้าจอ ฉันไม่ได้พูดถึงเรื่องนี้ในโพสต์เพราะไม่มีเวลา แต่พูดถึงในโพสต์บล็อกที่สองที่ฉันเชื่อมโยง
Richard Marskell - Drackir

9

โดยปกติการให้แสงในเกม 2D นั้นทำได้โดยมีแผนที่ปกติสำหรับสไปรต์ของคุณทั้งหมด เรื่องนี้เป็นที่รู้จักกันอย่างหลวม ๆ ว่า "2.5D" อย่างไรก็ตามฉันไม่แนะนำให้ทำเช่นนี้ในเกมแรกของคุณเนื่องจากมีความซับซ้อน

นี่เป็นวิดีโอที่ยอดเยี่ยมของคนที่ทำสิ่งนี้ใน XNA: http://www.youtube.com/watch?v=-Q6ISVaM5Ww

ที่กล่าวว่าอาจมีวิธีการโกงและได้รับระบบแสงหลอกที่สามารถทำงานกับสมมติฐานต่างๆ


เคยเห็นวิดีโอนี้มาก่อน +1 ที่กล่าวถึงเทคนิคที่น่าทึ่ง
Gustavo Maciel

ขอบคุณสำหรับคำแนะนำและลิงค์วิดีโอ อันที่จริงแผนที่ดูเหมือนจะเป็นทางออก ตัวฉันเองจะพยายามใช้แผนที่บนเลเยอร์ด้านบนของฉันเพื่อสร้าง 'ช่องว่าง' หรือเพื่อเปลี่ยนเอฟเฟกต์ที่มีต่อวัตถุต้นแบบ
Ivaylo Slavov

5

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

ฉันจะทิ้งสองเซ็นต์ของฉัน ดูว่าบทช่วยสอนนี้โดย Catalin Zima ได้รับDynamic 2D Shadowsเหมาะสมกับค่าของคุณหรือไม่ อย่างที่คุณเห็นแสงสว่างมีรัศมีและไม่ผ่านสิ่งกีดขวาง คุณสามารถทำให้รัศมีและสีเล็กลงเพื่อทำให้มองใกล้กับแสงไฟฉายจริง

ป้อนคำอธิบายรูปภาพที่นี่

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

แก้ไข

Catalin เชื่อมโยงไปยังบทความอื่นที่เขาใช้เป็นข้อมูลอ้างอิง แต่ลิงก์เสีย นี่คือการเชื่อมโยงการปรับปรุง


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