ใน Minecraft เมื่อคุณดูน้ำยิ่งคุณเห็นความมืดที่ได้รับ ไม่มีใครรู้วิธีการรหัสบางอย่างเช่นนั้น
Minecraft ที่มีเอฟเฟกต์
เกมที่คล้ายกันโดยไม่มีผลกระทบ
ใน Minecraft เมื่อคุณดูน้ำยิ่งคุณเห็นความมืดที่ได้รับ ไม่มีใครรู้วิธีการรหัสบางอย่างเช่นนั้น
Minecraft ที่มีเอฟเฟกต์
เกมที่คล้ายกันโดยไม่มีผลกระทบ
คำตอบ:
โดยพื้นฐานแล้วมีสองวิธีที่แตกต่างกันสำหรับแสงน้ำตามความลึก:
Minecraft ใช้แสงจาก voxel ซึ่งทำงานโดยกระจายแสงไปยังลูกบาศก์ที่อยู่ติดกันลดความสว่างขึ้นอยู่กับประเภทของบล็อก มหาสมุทรมืดเป็นผลข้างเคียงของระบบนี้
น้ำปิดกั้นแสงแดดและลดแสงลง 3 ระดับต่อบล็อก (แทนที่จะเป็น 1 ระดับเริ่มต้น) ซึ่งหมายถึงความสว่างในมหาสมุทรในแต่ละระยะทางจากพื้นผิวคือ:
0 (surface): 15 (direct sunlight)
1: 12
2: 9
3: 6
4: 3
5 and below: 0 (darkness)
ที่มา: Minecraft Wiki - Light
ในเกมที่มีรูปแบบแสงแบบดั้งเดิมเอฟเฟกต์นี้สามารถสร้างขึ้นได้โดยการวัดปริมาณน้ำที่อยู่ระหว่างแหล่งกำเนิดแสงและพื้นมหาสมุทร แสงจะจางลงตามระยะทางนี้ มีสองสามวิธีในการทำสิ่งนี้:
หากคุณมีพื้นผิวที่เรียบคุณสามารถคำนวณระยะทางที่แสงเดินทางผ่านน้ำได้ถ้าคุณผ่านพื้นผิวออกห่างจากแหล่งน้ำทั่วไปและผลคูณของจุดของตำแหน่งนี้และตำแหน่งพื้นผิวลงในรูปร่างเรขาคณิต
ระยะทางน้ำที่มีประสิทธิภาพคือ
โดยที่เป็นตำแหน่งของจุดยอดและเป็นมุมระหว่างทิศทางแสงใต้พื้นผิวและพื้นผิวของน้ำไปทางร่างกายของน้ำ
เมื่อพระอาทิตย์ตกดินจะถึงน้อยกว่า 50 °เล็กน้อยเพราะแสงหักเหเมื่อเข้าสู่น้ำ
นี่คือโพสต์บล็อกพร้อมคำอธิบายที่ดี: กล้องดิจิตอล: การสะท้อนกลับหมดภายใน
โพสต์อีกรายละเอียดเพิ่มเติม: กล้องดิจิตอล: กฎการหักเหของ Snell
หากคุณกำลังใช้ heightmap บนขนานพื้นผิวลงไปในน้ำที่จะกลายเป็น ปัจจัยที่ถูกต้องเท่ากับ 1 หากดวงอาทิตย์อยู่เหนือผิวน้ำโดยตรง
ด้วยแสงจุดคุณต้องคำนวณสำหรับแต่ละจุดยอดตามตำแหน่งสัมพันธ์กับแหล่งกำเนิดแสง
ด้วยระดับน้ำคงที่หรือทิศทางแสงคงที่ชิ้นส่วนของสมการจะคงที่และไม่ควรคำนวณในส่วนของ Shader ด้วยเหตุผลด้านประสิทธิภาพ
หากคุณแสดงผิวน้ำเป็นแผนที่ความลึกแยกต่างหาก (ดังที่เห็นจากแหล่งกำเนิดแสง) คุณสามารถใช้พื้นผิวความลึกนั้นเพื่อคำนวณระยะทางที่แสงเดินทางผ่านน้ำก่อนที่จะกระแทกพื้นผิว
ในการทำเช่นนี้คุณฉายแต่ละจุดยอดลงในมุมมองการฉายของแหล่งกำเนิดแสงใน Shader ที่จุดสุดยอดและทำการค้นหาพื้นผิวใน Pixel Shader
หากพื้นผิวค่อนข้างเรียบคุณควรใช้แหล่งกำเนิดแสงแบบหักเหเพื่อผลลัพธ์ที่ดีกว่า
* คุณสามารถกำหนดปริมาณน้ำที่อยู่ด้านหน้าของพื้นผิวของแข็งที่ใกล้ที่สุดโดยนับความลึกจากมุมมองของแสงดังนี้:
ตอนนี้พื้นผิวผลลัพธ์ประกอบด้วยปริมาณน้ำที่อยู่ด้านหน้าของแสงในพื้นที่แสงดังนั้นค่าจะต้องถูกเปลี่ยนกลับก่อนที่คุณจะใช้ วิธีนี้ใช้ในการคำนวณแสงทิศทาง (ลบด้วยการหักเห) แต่จะนำไปสู่แสงแวดล้อมที่ไม่ถูกต้องหากพื้นผิวไม่สม่ำเสมอมากและมีอากาศจำนวนมากระหว่างไปยังแหล่งน้ำที่มีผลต่อชิ้นส่วนเดียวกัน
ข้อดีและข้อเสียเหมือนกับการแมปเงาปกติยกเว้นว่าคุณต้องการบัฟเฟอร์เพิ่มอีกหนึ่งตัวในขณะที่คำนวณความลึกและประสิทธิภาพจะแย่ลงเนื่องจากคุณต้องวาดรูปเรขาคณิตมากขึ้น
การติดตามรังสีเป็นวิธีที่แม่นยำที่สุด แต่ก็เป็นวิธีที่แพงที่สุดในการแสดงปริมาณที่โปร่งใส มีสองวิธีในการทำสิ่งนี้: 1. การติดตามจากพื้นมหาสมุทรสู่พื้นผิวและ 2. การติดตามจากแหล่งกำเนิดแสงสู่น้ำ จำเป็นต้องมีรังสีหลายจุดสำหรับแต่ละจุดบนพื้นเพื่อคำนวณความสว่าง
มีอีกสองสิ่งที่ต้องคำนึงถึงเมื่อเรนเดอร์น้ำ:
แสงในน้ำจะถูกกระจายอีกครั้งในขณะที่เดินทางไปยังผู้สังเกตการณ์ดังนั้นคุณควรผสมผสานแสงนั้นเข้ากับสีทึบ
หากผู้สังเกตการณ์จมอยู่ใต้น้ำคุณสามารถทำให้เกิดหมอกได้โดยอิงตามผลลัพธ์สุดท้ายของบัฟเฟอร์ความลึก สีหมอก แต่ไม่ใช่ความหนาแน่นของมันควรเปลี่ยนไปตามระยะทางของผู้สังเกตจากพื้นผิว! (Minecraft ใช้ส่วนนี้ของเอฟเฟกต์เท่านั้น)
หากผู้สังเกตการณ์มองดูน้ำจากด้านบนคุณจะต้องคำนวณหมอกตามความแตกต่างเชิงลึกระหว่างพื้นผิวและเรขาคณิตใต้น้ำ สีของหมอกควรจะเข้มขึ้นเล็กน้อยโดยมีความแตกต่างของความลึกที่มากขึ้น แต่ควรเปลี่ยนเฉพาะจุดที่หมอกนั้นทึบอย่างสมบูรณ์
สีหมอกก็ควรขึ้นอยู่กับทิศทางการดูของแต่ละพิกเซลด้วยดังนั้นจึงมีสีเข้มขึ้นเล็กน้อยเมื่อมองลงไปในทั้งสองกรณี
หากคุณใช้ 3D-Texture แบบเรียงต่อกันแทนที่จะเป็นแบบรูปลอกสำหรับการปลอมแปลงคุณสามารถหลีกเลี่ยงการยืดบนพื้นผิวแนวตั้ง ความแรงของแสงที่กระจัดกระจายอยู่ใกล้พื้นผิวแตกต่างกันไปในสามมิติดังนั้นการใช้พื้นผิวแบบ 2D-Texture จึงมักจะสร้างความยาวเหยียดในฉาก คุณสามารถสร้างแบบจำลองการเปลี่ยนมุมแสงโดยการฉายตำแหน่งจุดสุดยอดของพื้นเป็นระบบพิกัดที่แตกต่างกัน
ความเป็นไปได้อีกอย่างหนึ่งคือการคำนวณความหนาแน่นของแสงตามตำแหน่งพื้นผิวในระบบพิกัดของแสงแม้ว่ามันจะมีค่าใช้จ่ายบ้าง
caustics ควรจางหายเร็วกว่าแสงกระจายที่เพิ่มความลึก
สีกระจัดกระจายแตกต่างกันดังนั้นสีของแสงควรเปลี่ยนตามความลึกที่เพิ่มขึ้น นอกจากนี้ยังป้องกันขอบฉับพลันเช่นที่ชายหาดตัดกับผิวน้ำ
เนื่องจากการหักเหของแสงแสงกระทบพื้นมหาสมุทรสูงชันกว่าปกติ บทความวิกิพีเดียเกี่ยวกับกฎหมายปราดเปรื่องของมีสูตรสำหรับมุมและเวกเตอร์
ฉันเชื่อว่าเอฟเฟกต์แสงบนท้องฟ้าใน Minecraft นั้นตรง - สิ่งต่าง ๆ ถูกบังด้วยสิ่งที่อยู่เหนือสิ่งเหล่านั้นไม่ว่าดวงอาทิตย์จะอยู่ที่ใด จากนั้นแสงในพื้นที่จากคบเพลิง ฯลฯ จะถูกนำไปใช้โดยมีเอฟเฟกต์ดรอปดาวน์ซึ่งอยู่ห่างจากแหล่งกำเนิดแสงมากขึ้น
หากทำเช่นนี้น้ำแต่ละชั้นจะรวมกันเป็นชั้น ๆ ใต้เงาดังนั้นแต่ละชั้นจะมืดลงเรื่อย ๆ ต้นไม้ใบให้ร่มเงาเช่นนี้ แต่ไม่สะสม คุณได้ร่มเงาเดียวกันกับต้นไม้ไม่ว่าจะเป็นลูกบาศก์ 1 หรือ 100 ก้อน
เงื่อนหนึ่งที่เป็นวิธีการใช้คือน้ำไม่ได้เข้มขึ้นเมื่ออยู่ห่างจากผู้ชม - เฉพาะเมื่อคุณลงไป ใช่เอฟเฟกต์หมอกจะเตะในระยะไกล แต่ไม่ใช่เอฟเฟกต์น้ำ
ดังนั้นสูตรพื้นฐานสำหรับการคำนวณแสงจะเป็นแบบนี้ในรหัสหลอก ...
light_on_cube = 1.0
for each cube above target cube, from lowest to highest {
if cube being examined is tree foliage
light_on_cube = 0.5
else if cube being examined is water
light_on_cube = light_on_cube - 0.1
else if cube being examined is solid
light_on_cube = 0
}
วิธีนี้ไม่เหมาะสำหรับการคำนวณแสงภายใต้ที่แขวนหรือในถ้ำเนื่องจากมันจะมืดสนิทภายใต้การแขวนโดยใช้วิธีนี้ แต่เราสามารถเพิ่มแหล่งกำเนิดแสงทั้งในท้องที่ (คบเพลิงไฟ ฯลฯ ) รวมทั้งการรักษาตึกบังแสงดวงอาทิตย์เป็นแหล่งกำเนิดแสง บางสิ่งเช่นนี้อาจทำ ...
ความคิดที่นี่ก็คือว่าถ้าก้อนถูกจุดโดยดวงอาทิตย์หรือคบเพลิงก้อนที่อยู่ติดกับมันก็จะถูกจุดในบางวิธี และยิ่งคุณอยู่ห่างจากคิวบ์ที่สว่างมากเท่าไหร่แสงยิ่งน้อยลงเท่านั้น มันเป็นวิธี kludge ในการประมาณแสงแบบกระจาย แต่ฉันคิดว่ามันจะใช้งานได้ (?)
บางทีฉันอาจเข้าใจผิดคำถาม แต่ทำไมคุณไม่สามารถเปลี่ยนสีของบล็อกขึ้นอยู่กับความลึกของพวกเขา
หากคุณมีความลึกd (เป็นบล็อกเริ่มต้นที่ 0) สมการที่เหมาะสมสำหรับความสว่างจะเป็น:
L = (1- m ) e - kd + m
รหัส: L = (1.0 - m) * exp(-k * d) + m;
kควบคุมความเร็วที่ได้รับเข้มขึ้น (สูงกว่า = เร็วกว่า) ค่าที่เหมาะสมจะเป็น 0.5
mคือความสว่างขั้นต่ำที่คุณต้องการ
Lแตกต่างกันไปตั้งแต่ 0 ถึง 1
หากคุณไม่ทราบวิธีเปลี่ยนสีของบล็อกในกราฟิก API ที่คุณใช้อยู่โปรดถามคำถามนั้นเป็นคำถามแยกต่างหาก (ระบุว่าคุณใช้ API ใดและคุณกำลังใช้เฉดสีหรือไม่)
e^-kd
บิตเป็นเพียงชี้แจงสลายซึ่งเป็นฟังก์ชั่นมาตรฐานสำหรับสิ่งที่ค่อยๆมีแนวโน้มไปศูนย์กว่ามูลค่าบางคน (ลึก) คูณโดย(1-m)
และนอกเหนือจากm
นี้เป็นเพียงขนาดและชดเชยการสลายตัวเพื่อที่จะจบลงที่ต่ำสุดของแต่ยังคงเริ่มต้นที่ m
en.wikipedia.org/wiki/Exponential_decay1