มีหลายวิธีในการทำเช่นนี้ สิ่งเหล่านี้จะต้องมีการใช้ shader และฉันคิดว่าคุณกำลังใช้แสงต่อพิกเซล ต่อไปนี้เป็นคำแนะนำบางอย่างอย่างไรก็ตามการค้นหาเทคนิคที่เหมาะกับคุณอาจต้องใช้การวิจัยมากขึ้น
รวดเร็วและสกปรก
คุณสามารถระบุกล่องขอบที่กำหนดพื้นที่ภายใน หากแสงอยู่นอกกล่อง แต่รูปทรงเรขาคณิต (ซึ่งไม่ได้อยู่ในเงา) อยู่ในกล่องจากนั้นแสงจะต้องได้รับผลกระทบจากการผ่านหน้าต่าง (นี่ก็เป็นจริงเช่นกันถ้าเรขาคณิตอยู่นอกกล่องและแสง อยู่ข้างใน) ปัญหาเดียวที่นี่คือวิธีการส่งผ่านข้อมูลกล่องไปยัง shader และวิธีการระบุผลกระทบต่อแสง
อีกตัวเลือกหนึ่งคือการระบุ windows เป็นวัตถุที่วางอยู่บนเครื่องบิน การทดสอบครั้งแรกเพื่อดูว่ารูปทรงเรขาคณิตและแสงอยู่บนด้านตรงข้ามของระนาบหรือไม่จากนั้นถ้าทางระหว่างพวกมันตัดกับระนาบที่จุดหนึ่งภายในขอบเขตของหน้าต่าง นี่จะแม่นยำกว่าวิธีแรกและมันจะง่ายกว่าถ้ามีหน้าต่างในการตกแต่งภายในแบบเดียวกันกับกระจกสีที่แตกต่างกัน
รับรายละเอียดมากขึ้นด้วยการนำเสนอรูปทรงเรขาคณิตของหน้าต่างและคุณจะได้ผลลัพธ์ที่แม่นยำยิ่งขึ้น แต่การคำนวณจะได้รับหนักกว่า
เทคนิคเหล่านี้จะทำงานได้ดีพอสมควรสำหรับนักกีฬาที่เดินเล่น แต่ไม่ค่อยดีนักสำหรับโลกที่มีการเปลี่ยนแปลงหรือเปิดกว้าง นอกจากนี้เทคนิคเหล่านี้อาจกลายเป็นความรุนแรงเล็กน้อยได้อย่างรวดเร็วดังนั้นจึงแนะนำให้ย้ายไปที่ไปป์ไลน์แรเงาที่เลื่อนออกไป
แผนที่เงา
ตัวเลือกอื่นคือทำสิ่งที่คล้ายกับการทำแผนที่เงา
ในการทำแผนที่เงาคุณสร้างภาพบิตแมปบางส่วนของโลกที่ได้รับผลกระทบจากแสง แต่ละพิกเซลในขณะที่ยังคงมีสีเป็นระยะทางของชิ้นส่วนเรขาคณิตที่ไม่โปร่งใสที่ใกล้ที่สุด (คุณใช้สี่ไบต์สำหรับ 1 ลอยแทน 4 สี) หากคุณคำนวณระยะทางจากแสงไปยังชิ้นส่วนของรูปทรงเรขาคณิตและมันอยู่นอกเหนือจากค่าที่สอดคล้องกันในแผนที่เงาชิ้นส่วนของรูปทรงเรขาคณิตของคุณอยู่ในเงา (โดยทั่วไปคุณใช้รังสีระหว่างรูปทรงเรขาคณิตและแสงเพื่อทำดัชนีแผนที่)
หากคุณใช้ความคิดนี้กับปัญหาของคุณสิ่งที่คุณต้องทำคือเก็บแผนที่ของระยะทางจากแสงของชิ้นส่วนที่โปร่งใสของรูปทรงเรขาคณิตที่ใกล้ที่สุดแล้วสร้างแผนที่ที่สองของสีของแสงหลังจากผ่านรูปทรงเรขาคณิตนั้น ( เพียงสีของรูปทรงเรขาคณิตถ้าแสงเป็นสีขาว)
หากส่วนของรูปทรงเรขาคณิตของคุณอยู่ไกลเกินกว่าระยะทางในแผนที่นี้ให้ใช้สีแผนที่หากไม่ได้ใช้สีแสงเดิม
ฟังก์ชั่นสำหรับการคำนวณสีสำหรับแต่ละพิกเซลในแผนที่ควรเป็นอย่างคร่าวๆ lightColor - invertedWindowColor ดังนั้นสำหรับแสงสีขาวบริสุทธิ์และหน้าต่างสีแดงบริสุทธิ์ซึ่งไม่ดูดซับสเปกตรัมสีแดงเราจึงได้ (255,255,255) - (0,255,255) = (255,0,0) ดังนั้นสีของแสงที่อยู่อีกด้านหนึ่งจึงเป็นสีแดงบริสุทธิ์ สำหรับวัตถุโปร่งใสที่ซับซ้อนมากขึ้นเช่นหน้าต่างกระจกสีคุณอาจต้องการค้นหาพื้นผิวเพื่อให้ได้สีของวัสดุ
หากคุณกำลังมองหาบางสิ่งบางอย่างที่คล้ายกันแล้วตรวจสอบสะท้อนเงาแผนที่
เทคนิคนี้มีความเที่ยงตรงจำนวนมากและอาจดีที่สุดหากคุณต้องการใช้รูปทรงเรขาคณิตที่ซับซ้อนเช่นหน้าต่างกระจกสี
การพยายามแก้ไขปัญหาทั่วไป
เมื่อไม่นานมานี้ได้รับความนิยมในการเข้ารหัสข้อมูลแสงในรูปแบบตัวแทนของ voxel (ไม่ได้มีไว้สำหรับรูปทรงเรขาคณิตเท่านั้น) เอ็นจิ้น crytek ล่าสุดใช้ stratagy ชนิดนี้สำหรับการให้แสงขั้นสูง ( ปริมาณการแพร่กระจายแสง )
นี่คือความคิดทั่วไป:
- สร้างแผนที่ของลูกบาศก์ที่เว้นระยะเท่ากันซึ่งครอบคลุมฉากของคุณ (พิจารณาใช้เส้นโค้งลำดับ z )
- ค้นหาวิธีการจัดเก็บข้อมูลแสงที่ตกกระทบสำหรับแต่ละ voxel (การเป็นตัวแทนฮาร์มอนิกทรงกลมมีประโยชน์ที่นี่)
- ค้นหา voxel ที่มีแสงและเป็นตัวแทนของแสงนั้นใน voxel
- เผยแพร่แสงออกมาผ่าน voxels ที่อยู่ติดกัน (เช่น minecraft น้ำ)
- คำนวณว่ารูปทรงเรขาคณิตในแต่ละ voxel จะส่งผลต่อแสงที่ส่องผ่าน (ดูดกลืนสะท้อนส่งผ่าน)
- ทำซ้ำจนกว่าแสงจะจางลง
มีหลายวิธีในการสร้างข้อมูล voxel นี้ แต่รายการด้านบนให้แนวคิดทั่วไป ตัวอย่างเช่น; คุณสามารถเริ่มต้นด้วยการสร้างเงาแผนที่ / ปริมาณแล้วฉายข้อมูลนั้นลงในแผนที่ voxel เพื่อให้คุณสามารถสร้างแผนที่ของแสงโดยตรง จากนั้นคุณเริ่มต้นการแพร่กระจายจาก voxels ตามขอบของพื้นที่ที่ได้รับผลกระทบ โปรดทราบว่าในกรณีนี้คุณจะไม่สนใจว่ารูปทรงเรขาคณิตนั้นโปร่งใสหรือไม่เมื่อสร้างแผนที่เงา / ระดับเสียง
ในรอบสุดท้ายของตัวเรนเดอร์ที่เลื่อนออกไปเมื่อคำนวณความส่องสว่างของรูปทรงเรขาคณิตคุณเพียงแค่ใช้ตำแหน่งรูปทรงเรขาคณิตเพื่อทำดัชนีแผนที่ voxel ของคุณเพื่อค้นหาว่าแสงของเหตุการณ์นั้นเกิดขึ้นที่จุดใดในอวกาศ จากนั้นคุณสามารถสร้างแผนที่หน้าจอของซีพียูไฟที่ตกกระทบหรืออาจทำเช่นนี้กับ cuda