ฉันจะจัดการกับการตัดจุดยอดที่อยู่ใกล้กับดวงตาได้ดีกว่าระนาบคลิปใกล้ได้อย่างไร?


13

ฉันเปิดโปรแกรม 3D ของฉันเองใน JavaScript และใช้เฉพาะภาพวาดบนผ้าใบไม่มี WebGL นี่เป็นโคลน Minecraft อีกอัน; ฉันรักกล่องอย่าตัดสินฉัน

จนถึงตอนนี้ทุกอย่างใช้งานได้อย่างยอดเยี่ยมยกเว้นสิ่งหนึ่ง: ในแบบ 3 มิติเมื่อจุดยอดเยี่ยมอยู่ด้านหลังระนาบรูปวาดใกล้การฉายภาพบนหน้าจอของพวกเขาออกมาแปลก ๆ (สมมติว่าจุดยอดอื่น ๆ ที่ใช้ติดตามเครื่องบินอยู่ด้านหน้า)

ฉันพยายามตัดจุดเหล่านี้ แต่จากนั้นฉันสามารถเห็นรางพื้นผิวที่ใช้จุดยอดเหล่านี้ ใน WebGL / OpenGL การ์ดกราฟิกจะดูแลจุดเหล่านี้และระนาบแสดงผลอย่างถูกต้อง แต่ฉันไม่สามารถเข้าถึงฮาร์ดแวร์ได้ดังนั้นฉันจะต้องใช้รหัสนี้เอง

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

นี่คือความคิดของฉัน:

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

นี่คือภาพบางส่วนที่แสดงให้เห็นถึงสิ่งที่เกิดขึ้น:

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

จากระยะไกลกล่องสีฟ้าจะแสดงผลได้ดีอย่างสมบูรณ์

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

เมื่อจุดยอดหนึ่งไปด้านหลังระนาบการเล็มของผู้เล่นฉันจะฉายภาพย้อนกลับ แต่มันก็ดูไม่ถูก:

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

โปรดทราบว่าช่องสีเทาด้านหลังจะถูกลบออกอย่างสมบูรณ์เนื่องจากจุดยอดทั้งหมดที่ใช้วาดใบหน้านั้นอยู่ด้านหลังโปรแกรมเล่น

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

นี่คือสิ่งที่เกิดขึ้นเมื่อค้นหาขึ้นหรือลง

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


1
หากจุดที่อยู่ใกล้กับดวงตามากกว่าระนาบคลิปใกล้พวกเขาควรจะถูกตัด - และนี่อาจทำให้คุณเห็น "ผ่าน" วัตถุ นี่เป็นพฤติกรรมปกติ การชนโดยปกติจะป้องกันสิ่งประดิษฐ์ที่มองเห็นโดยเฉพาะ นั่นเป็นสิ่งเดียวที่ผิดกับโซลูชันการคลิปของคุณหรือไม่

@ JoshPetrie: ฉันเข้าใจว่าจะต้องตัดจุด แต่ถ้าฉันทำทั้งสี่เหลี่ยมจะหายไปเมื่อหนึ่งหรือสองจุดยอดที่รูทีนการวาดต้องผ่านหายไป (ใน 2d) และผู้เล่นจะสามารถมองเห็นได้ ผ่านจัตุรัสนั้น ฉันต้องการให้พวกเขาเป็น "นอก" ของผืนผ้าใบ (ในการฉายภาพ) เพื่อให้สี่เหลี่ยมยังคงถูกดึงออกมา ฉันไม่แน่ใจว่าฉันชัดเจนเพียงพอหรือไม่
โซลินอยด์

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

สิ่งที่คุณพูดมีเหตุผลการสร้างใหม่ต้องใช้เวลามากเกินไปนั่นไม่ใช่วิธีแก้ปัญหา ฉันหวังว่าจะมีวิธีการที่จะดึงจุดสุดยอดนั้นบนระนาบ 2dที่อยู่ด้านหลังผู้เล่นดังนั้นlineTo(x,y)ฟังก์ชั่นจึงยังสามารถเรียกใช้ได้ แต่ฉันไม่รู้ว่ามันทำงานอย่างไร ... มันเป็นมิติที่แปลกประหลาดฉันเห็นด้วย
โซลินอยด์

ลองดูที่บทช่วยสอนนี้มันอธิบายวิธีการคำนวณการตัดของสามเหลี่ยมแต่ละรูปและวัตถุโดยรวม
กระทำ

คำตอบ:


1

วัตถุประสงค์ของการตัดระนาบใกล้ก็คือว่ามันเป็นเครื่องบินตัด สามเหลี่ยมที่อยู่นอกระนาบการตัดจะถูกตัด : ตัดเป็นชิ้น ๆ เพื่อให้ชิ้นส่วนที่เหลืออยู่ภายในขอบเขตการตัด

คุณสามารถพยายามละเว้นคลิปใกล้ถ้าคุณต้องการ แน่นอน OpenGL และ D3D มีวิธีการปิดการตัดระนาบใกล้กัน (แม้ว่าบัฟเฟอร์ความลึกยังคงมีค่าใกล้ขั้นต่ำ) ปัญหาไม่ได้อยู่ใกล้กับคลิป

ปัญหาคือจุดยอดที่อยู่ด้านหลังกล้อง

คุณไม่สามารถแสดงรูปสามเหลี่ยมที่อยู่ด้านหลังกล้อง ไม่ได้มีมุมมองการฉาย สามเหลี่ยมดังกล่าวไม่สมเหตุสมผลภายใต้คณิตศาสตร์หลังการคาดการณ์มุมมอง นอกจากนี้พวกเขายังอยู่นอก frustum

การปิดใกล้การตัดจะทำให้ frustum กลายเป็นปิรามิด เหตุผลที่ปิรามิดหยุดที่จุดนั้นเป็นเพราะคะแนนเหนือปิรามิดอยู่ด้านหลังทั้งสี่ด้านของปิรามิด ดังนั้นจุดใด ๆ ที่อยู่ด้านหลังกล้อง (ปลายปิรามิด) อยู่ด้านบนด้านล่างด้านซ้ายและด้านขวาของพื้นที่ที่มองเห็นได้ของหน้าจอ ทั้งหมดในเวลาเดียวกัน

อย่างที่ฉันพูด: จุดยอดภายใต้มุมมองที่อยู่ด้านหลังกล้องไม่สมเหตุสมผล

คุณต้องใช้การตัด คุณต้องตรวจจับเมื่อจุดยอดของรูปสามเหลี่ยมใด ๆ ในพื้นที่คลิป ( ก่อนที่จะแบ่งมุมมอง) อยู่ด้านหลังกล้อง ถ้าเป็นเช่นนั้นคุณต้องคลิปรูปสามเหลี่ยมนั้นสร้างรูปสามเหลี่ยมที่อยู่ด้านหน้ากล้องเท่านั้น

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


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

0

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

คุณอาจปฏิบัติต่อระนาบใกล้เคียงเช่นระนาบตัดอื่น ๆ ตัวอย่างเช่นการตัดเครื่องบินใช้สำหรับสิ่งต่าง ๆ เช่นระนาบน้ำ (สำหรับการสะท้อนและการหักเหของแสง) ฉันคิดว่าระนาบการตัดนี้จะใช้ได้เหมือนระนาบการตัดที่ใกล้และคลิปต่อพิกเซล

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

นอกจากนี้นี่คือลิงค์ที่อาจช่วยคุณได้: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html


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