ฉันจะดึงข้อมูลตำแหน่งโลกของกล้องจากเมทริกซ์มุมมองได้อย่างไร คำตอบเดียวที่ฉันเคยเห็นสำหรับคำถามนี้แนะนำให้แปลอยู่ในแถว / คอลัมน์สุดท้าย แต่สิ่งนี้จะไม่ทำงานเนื่องจากเมทริกซ์มี [x (dot) ขวา, y (dot) up, z (dot) look]
ฉันจะดึงข้อมูลตำแหน่งโลกของกล้องจากเมทริกซ์มุมมองได้อย่างไร คำตอบเดียวที่ฉันเคยเห็นสำหรับคำถามนี้แนะนำให้แปลอยู่ในแถว / คอลัมน์สุดท้าย แต่สิ่งนี้จะไม่ทำงานเนื่องจากเมทริกซ์มี [x (dot) ขวา, y (dot) up, z (dot) look]
คำตอบ:
คำตอบสั้น ๆ
ขั้นแรกให้สลับเมทริกซ์มุมมอง จากนั้นดึงคำแปลจากแถว / คอลัมน์สุดท้าย
คำตอบยาว ๆ
วิธีหนึ่งในการอนุมานเนื้อหาของวิวเมทริกซ์คือเริ่มจากการพิจารณาว่ากล้องเป็นวัตถุอื่นใดในโลกและคำนวณเมทริกซ์โลกสำหรับมัน:
RightX RightY RightZ 0
UpX UpY UpZ 0
LookX LookY LookZ 0
PosX PosY PosZ 1
เมทริกซ์โลกเปลี่ยนพิกัดจากอวกาศในพื้นที่โลก แต่ในกรณีนี้พื้นที่ในตัวกล้องและพื้นที่ดูเป็นแบบเดียวกันดังนั้นเราจึงสามารถบอกได้ว่าเมทริกซ์นี้แปลงพิกัดจากพื้นที่ดูเป็นอวกาศ
เนื่องจากเราต้องการการแปลงในทิศทางตรงกันข้ามเราต้องกลับเมทริกซ์ ผลลัพธ์คือสิ่งที่เราเรียกว่าเมทริกซ์มุมมองซึ่งเปลี่ยนพิกัดจากอวกาศโลกเป็นพื้นที่ว่าง:
RightX UpX LookX 0
RightY UpY LookY 0
RightZ UpZ LookZ 0
-(Pos*Right) -(Pos*Up) -(Pos*Look) 1 // * = dot product
นั่นคือเมทริกซ์ที่คุณมี ดังนั้นเพื่อให้ได้ตำแหน่งกล้องกลับมาคุณจะต้องกลับด้านก่อนจากนั้นคุณสามารถคว้าการแปลจากแถวสุดท้าย (หรือคอลัมน์ขึ้นอยู่กับระบบ)
ก่อนอื่นฉันขอแนะนำเพียงแค่เก็บตำแหน่งไว้เป็นเวกเตอร์แยกต่างหากมันจะทำให้การคำนวณง่ายขึ้นมาก อย่างไรก็ตาม...
[x (dot) right, y (dot) up, z (dot) look]
ไม่ใช่เมทริกซ์มุมมองจริง เมทริกซ์เองนั้นอยู่ในรูปแบบ:
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
เมื่อเมทริกซ์ 3x3 ซ้ายบนแสดงถึงการหมุน, สเกล, ฯลฯ การวางแนวของกล้องทั้งหมดจะทำ แถวและคอลัมน์ที่เหลือใช้สำหรับการแปลและมุมมองที่ซับซ้อนบางอย่างที่ฉันไม่อยากเข้าไปในตอนนี้
เมื่อคุณได้รับเมทริกซ์ (สมมติว่าเป็นเมทริกซ์ 4x4) การแปลจะถูกเก็บไว้ในแถวสุดท้ายหรือคอลัมน์สุดท้ายเสมอโดยขึ้นอยู่กับว่าคลาสเมทริกซ์ของคุณเป็นการเรียงลำดับแถวหลักหรือคอลัมน์หลัก
สิ่งที่คุณอาจสับสนคือข้อเท็จจริงที่ว่าคุณต้องการผลิตภัณฑ์ดอท สิ่งที่เกิดขึ้นคือความเรียบง่ายของคณิตศาสตร์เมทริกซ์มีคำตอบโดยละเอียดในคำถาม Stack Overflow นี้: /programming/349050/calculating-a-lookat-matrix
วิธีแก้ปัญหาสามารถพบได้ที่นี่คุณจะต้องใช้อินเวอร์สของเมทริกซ์และรับการแปล:
Vector3 ViewTrans = Matrix.Invert(ViewMatrix).Translation;
Position = ViewTrans;
คำตอบอื่น ๆ ที่นี่อธิบายถึงวิธีการรับตำแหน่งกล้องจากผกผันเมทริกซ์กล้อง
หากส่วนของกล้องเมทริกซ์ 3x3 มีการหมุนเท่านั้น (ไม่มีการปรับสเกลหรือตัด) ตามปกติการคำนวณสามารถปรับให้เหมาะสมได้โดยการคูณการแปลเมทริกซ์กล้องกับการแปลงการหมุนของกล้อง ตำแหน่งกล้องคือเวกเตอร์แปลที่แปลงแล้วคูณด้วย -1 ใน GLSL นี่คือ:
vec3 cameraPosition = -transpose(mat3(worldToCameraMatrix)) * worldToCameraMatrix[3].xyz;
หรือ
vec3 cameraPosition = -worldToCameraMatrix[3].xyz * mat3(worldToCameraMatrix);
นี่คือสิ่งที่ฉันใช้ในเครื่องแต่งทรงผมถ้าฉันไม่ต้องการคำนวณและส่งตำแหน่งกล้องเป็นเครื่องแบบ