การแรเงาที่เลื่อนออกไป - วิธีรวมแสงหลายดวงเข้าด้วยกัน?


9

ฉันเริ่มต้นด้วย GLSL และฉันได้ใช้การแรเงาที่เลื่อนออกไปอย่างง่ายซึ่งจะส่งออก G-buffer ด้วยตำแหน่ง, ค่าพื้นฐานและอัลเบโด้

ฉันยังเขียน shader แสงจุดง่ายเช่นกัน

ตอนนี้ฉันวาดทรงกลมสำหรับจุดไฟและเอาท์พุทไปที่บัฟเฟอร์แสง

ปัญหาคือฉันจะรวมผลลัพธ์ของบัฟเฟอร์แสงเมื่อวาดแสงหลายดวงได้อย่างไร

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

คำตอบ:


12

การผสมแบบเติมแต่งเช่น glBlendFunc (GL_ONE, GL_ONE) และ glEnable (GL_BLEND)


การทดสอบเชิงลึกต้องปิดการใช้งานสำหรับสิ่งนี้หรือไม่
woojoo666

1
@ woojoo666 ไม่ที่จริงแล้วควรเปิดใช้งานด้วยการทดสอบความลึกที่ตั้งค่าไว้ไม่เท่ากันดังนั้นพื้นผิวที่ตรงกับรหัสผ่านก่อนหน้านี้จะผ่านได้อย่างแม่นยำ หากการทดสอบความลึกปิดอยู่พื้นผิวจะสะสมแสงจากสิ่งที่อยู่ด้านหลังไม่ถูกต้อง :)
นาธานรีด

อืมดูเหมือนว่าจะเป็นอย่างนั้นแหละ การเปิดการผสมทำให้ใบหน้าด้านหน้ากลมกลืนกับใบหน้าด้านหลังแม้ว่าฉันจะเปิดใช้การทดสอบเชิงลึกอยู่ก็ตาม ฉันต้องทำอะไรกับมาสก์ลึกเช่นกัน?
woojoo666

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

2
@ woojoo666 อ๊ะดูเหมือนว่าคุณจะแก้ไขมันด้วยตัวเอง ใช่คุณต้องวางลึกลงในพาสทึบก่อนที่จะใช้การผสมแบบใดก็ได้ อาจเป็น z-prepass ที่ปิดใช้งานการเขียนสีหรือวิธีการทั่วไปอื่นคือการทำแสงรอบทิศทาง / ทิศทางในรอบแรกโดยไม่ผสมแล้วเพิ่มไฟจุด / จุดในการส่งในภายหลังด้วยการผสม
Nathan Reed

2

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

โดยพื้นฐานแล้วฉันรันเกมเรขาคณิตทั้งหมดของฉันผ่านรูปทรงเรขาคณิตของฉันเพื่อสร้าง g-buffers จากนั้นฉันให้อาหาร g-buffer ไปยัง shader pass เบา ๆ แสงแต่ละดวงวิ่งผ่านผ่านโดยใช้รูปสี่เหลี่ยมเต็มหน้าจอ วิธีนี้พิกเซลของฉันสามารถใช้ความเข้มแสงสำหรับพื้นผิวที่มองเห็นได้ทั้งหมดจาก g-buffer และเพิ่มไปยังเป้าหมายการเรนเดอร์แสง คุณเพียงแค่เพิ่มความเข้มของแสงสำหรับแต่ละแสงในบัฟเฟอร์แสง แต่ให้แน่ใจว่าคุณยึดความเข้มจาก 0 ถึง 1

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


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

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

คุณจะจัดการกับกรณีที่มีแสงสว่างอยู่ด้านหลังกำแพงและไม่ควรให้แสงสว่างในอีกด้านหนึ่งของผนังได้อย่างไร
jjxtra

@PsychoDad นั่นคือโดเมนของเงาซึ่ง ... หัวข้อที่ซับซ้อนมากขึ้น :)
นาธานรีด

0

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


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

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

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

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