Nếu tôi nhìn vào một ma trận đông dân trong chương trình của mình, tôi thấy các thành phần dịch chiếm các phần tử thứ 4, 8 và 12.
Trước khi tôi bắt đầu, điều quan trọng là phải hiểu: điều này có nghĩa là ma trận của bạn là hàng chính . Do đó, bạn trả lời cho câu hỏi này:
Ma trận WVP chính của cột của tôi được sử dụng thành công để biến đổi các đỉnh với lệnh gọi HLSL: mul (vectơ, ma trận) dẫn đến vectơ được coi là hàng chính, vậy ma trận chính của cột được cung cấp bởi thư viện toán học của tôi có thể hoạt động như thế nào?
là khá đơn giản: ma trận của bạn là hàng chính.
Vì vậy, nhiều người sử dụng ma trận hàng lớn hoặc ma trận chuyển tiếp, họ quên rằng ma trận không được định hướng theo cách tự nhiên. Vì vậy, họ thấy một ma trận dịch như sau:
1 0 0 0
0 1 0 0
0 0 1 0
x y z 1
Đây là một ma trận dịch chuyển . Đó không phải là một ma trận dịch bình thường trông như thế nào. Bản dịch đi trong cột thứ 4 , không phải hàng thứ tư. Đôi khi, bạn thậm chí nhìn thấy điều này trong sách giáo khoa, đó là rác hoàn toàn.
Thật dễ dàng để biết liệu một ma trận trong một mảng là hàng hay cột chính. Nếu là hàng chính, thì bản dịch được lưu trữ trong các chỉ số 3, 7 và 11. Nếu đó là cột chính, thì bản dịch được lưu trữ trong các chỉ số 12, 13 và 14. Tất nhiên các chỉ số cơ sở.
Sự nhầm lẫn của bạn bắt nguồn từ việc tin rằng bạn đang sử dụng ma trận cột lớn khi thực tế bạn đang sử dụng các ma trận hàng chính.
Tuyên bố rằng hàng so với cột chính là một quy ước công chứng chỉ hoàn toàn đúng. Các cơ chế của phép nhân ma trận và phép nhân ma trận / vectơ là như nhau bất kể quy ước.
Những thay đổi là ý nghĩa của kết quả.
Một ma trận 4 x 4 sau tất cả chỉ là một lưới số 4 x 4. Nó không có đề cập đến một sự thay đổi của hệ tọa độ. Tuy nhiên, một khi bạn gán ý nghĩa cho một ma trận cụ thể, bây giờ bạn cần biết những gì được lưu trữ trong nó và làm thế nào để sử dụng nó.
Lấy ma trận dịch tôi chỉ cho bạn ở trên. Đó là một ma trận hợp lệ. Bạn có thể lưu trữ ma trận đó theo một float[16]
trong hai cách:
float row_major_t[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1};
float column_major_t[16] = {1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1};
Tuy nhiên, tôi đã nói rằng ma trận dịch thuật này là sai, bởi vì bản dịch không đúng chỗ. Tôi đặc biệt nói rằng nó được hoán vị so với quy ước chuẩn về cách xây dựng ma trận dịch thuật, nó phải giống như thế này:
1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1
Hãy xem cách chúng được lưu trữ:
float row_major[16] = {1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1};
float column_major[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1};
Lưu ý rằng column_major
nó giống hệt như row_major_t
. Vì vậy, nếu chúng ta lấy một ma trận dịch phù hợp và lưu trữ nó dưới dạng cột chính, thì cũng giống như hoán vị ma trận đó và lưu trữ nó dưới dạng hàng chính.
Đó là những gì có nghĩa là chỉ là một quy ước công chứng. Thực sự có hai bộ quy ước: lưu trữ bộ nhớ và chuyển vị. Bộ nhớ lưu trữ là cột so với hàng chính, trong khi chuyển vị là bình thường so với chuyển đổi.
Nếu bạn có một ma trận được tạo theo thứ tự hàng lớn, bạn có thể có được hiệu ứng tương tự bằng cách hoán đổi tương đương với cột chính của ma trận đó. Và ngược lại.
Phép nhân ma trận chỉ có thể được thực hiện theo một cách: đưa ra hai ma trận, theo một thứ tự cụ thể, bạn nhân các giá trị nhất định lại với nhau và lưu trữ kết quả. Bây giờ, A*B != B*A
nhưng mã nguồn thực tế A*B
giống như mã cho B*A
. Cả hai đều chạy cùng một mã để tính toán đầu ra.
Mã nhân ma trận không quan tâm đến việc ma trận xảy ra được lưu trữ theo thứ tự cột chính hay hàng chính.
Điều tương tự không thể được nói cho phép nhân vectơ / ma trận. Và đây là lý do.
Phép nhân vectơ / ma trận là một sự giả dối; nó không thể được thực hiện Tuy nhiên, bạn có thể nhân một ma trận với một ma trận khác. Vì vậy, nếu bạn giả vờ một vectơ là một ma trận, thì bạn có thể thực hiện phép nhân vectơ / ma trận một cách hiệu quả, chỉ đơn giản bằng cách thực hiện phép nhân ma trận / ma trận.
Một vectơ 4D có thể được coi là một vectơ cột hoặc một vectơ hàng. Nghĩa là, một vectơ 4D có thể được coi là ma trận 4x1 (hãy nhớ: trong ký hiệu ma trận, số hàng xuất hiện trước) hoặc ma trận 1x4.
Nhưng đây là điều: Cho hai ma trận A và B, A*B
chỉ được xác định nếu số cột của A bằng với số hàng của B. Do đó, nếu A là ma trận 4 x 4 của chúng ta, B phải là một ma trận có 4 hàng trong đó. Do đó, bạn không thể thực hiện A*x
, trong đó x là một vectơ hàng . Tương tự, bạn không thể thực hiện x*A
trong đó x là một vectơ cột.
Bởi vì điều này, hầu hết các thư viện toán học ma trận đều đưa ra giả định này: nếu bạn nhân một vectơ nhân với một ma trận, bạn thực sự có nghĩa là thực hiện phép nhân thực sự hoạt động , chứ không phải là vô nghĩa.
Hãy để chúng tôi xác định, cho bất kỳ vector 4D x, sau đây. C
sẽ là dạng ma trận vectơ cột của x
và R
sẽ là dạng ma trận vectơ hàng của x
. Với điều này, đối với bất kỳ ma trận A 4 nào, A*C
biểu thị ma trận nhân A với vectơ cột x
. Và R*A
biểu diễn ma trận nhân vectơ hàng x
với A.
Nhưng nếu chúng ta xem xét điều này bằng toán học ma trận nghiêm ngặt, chúng ta sẽ thấy rằng những điều này không tương đương . R*A
không thể giống như A*C
. Điều này là do một vectơ hàng không giống với vectơ cột. Chúng không phải là cùng một ma trận, vì vậy chúng không tạo ra kết quả giống nhau.
Tuy nhiên, chúng có liên quan theo một cách. Đúng là như vậy R != C
. Tuy nhiên, cũng đúng , trong đó T là hoạt động chuyển vị. Hai ma trận là hoán vị của nhau.R = CT
Đây là một sự thật buồn cười. Vì các vectơ được coi là ma trận, nên chúng cũng có một cột so với câu hỏi lưu trữ chính hàng. Vấn đề là cả hai đều trông giống nhau . Mảng phao là như nhau, vì vậy bạn không thể biết sự khác biệt giữa R và C chỉ bằng cách nhìn vào dữ liệu. Cách duy nhất để nói lên sự khác biệt là cách chúng được sử dụng.
Nếu bạn có bất kỳ hai ma trận A và B nào và A được lưu dưới dạng hàng chính và B là cột chính, việc nhân chúng là hoàn toàn vô nghĩa . Bạn nhận được vô nghĩa như là kết quả. Vâng, không thực sự. Về mặt toán học, những gì bạn nhận được là tương đương với việc làm . Hoặc ; chúng giống hệt nhau về mặt toán học.AT*B
A*BT
Do đó, phép nhân ma trận chỉ có ý nghĩa nếu hai ma trận (và nhớ: phép nhân vectơ / ma trận chỉ là phép nhân ma trận) được lưu trữ theo cùng một thứ tự chính.
Vì vậy, là một cột vector-chính hay hàng-chính? Nó là cả và không, như đã nêu trước đây. Nó chỉ là cột chính khi nó được sử dụng như một ma trận cột và nó là hàng chính khi nó được sử dụng như một ma trận hàng.
Do đó, nếu bạn có một ma trận A là cột chính, x*A
có nghĩa là ... không có gì. Vâng, một lần nữa, nó có nghĩa , nhưng đó không phải là những gì bạn thực sự muốn. Tương tự, phép nhân chuyển đổi nếu là hàng chính.x*AT
A*x
A
Do đó, thứ tự nhân vectơ / ma trận sẽ thay đổi, tùy thuộc vào thứ tự chính của dữ liệu của bạn (và liệu bạn có đang sử dụng ma trận chuyển vị không).
Tại sao trong đoạn mã sau đây không r! = R2
Bởi vì mã của bạn bị hỏng và lỗi. Về mặt toán học , . Nếu bạn không nhận được kết quả này, thì kiểm tra đẳng thức của bạn là sai (các vấn đề chính xác của dấu phẩy động) hoặc mã nhân ma trận của bạn bị hỏng.A * (B * C) == (CT * BT) * AT
tại sao pos3! = pos cho
Bởi vì điều đó không có ý nghĩa. Cách duy nhất để trở thành sự thật sẽ là nếu . Và điều đó chỉ đúng với ma trận đối xứng.A * t == AT * t
A == AT