No. I termini "riga-maggiore" e "colonna-maggiore" si riferiscono esclusivamente all'ordine di memoria dei componenti della matrice nella memoria. Non hanno nulla a che fare con l'ordine di moltiplicazione di matrici e vettori. In effetti, la chiamata D3D9 HLSL mul
interpreta gli argomenti della matrice come colonna principale in tutti i casi. La chiamata ID3DXBaseEffect::SetMatrix()
interpreta il suo argomento di matrice come riga principale e traspone dietro le quinte per l'ordine di colonna principale previsto di mul
.
Se si dispone di una matrice che sembra astrattamente simili:
[ a b c d ]
[ e f g h ]
[ i j k l ]
[ m n o p ]
poi quando memorizzate in ordine row-major, la sua memoria aspetto:
a b c d e f g h i j k l m n o p
cioè gli elementi di una riga sono tutti contigui in memoria.Se conservato in modo column-major, la sua memoria sarebbe simile a questa:
a e i m b f j n c g k o d h l p
con gli elementi di una colonna di tutti contigui. Tuttavia, questo ha esattamente l'effetto zero su quale elemento è quello. L'elemento b
è ancora nella prima riga e nella seconda colonna, in entrambi i casi. L'etichettatura degli elementi non è cambiata, solo il modo in cui sono mappati alla memoria.
Se si dichiara una matrice come float matrix[rows][cols]
in C, si utilizza la memoria di riga maggiore. Tuttavia, alcuni altri linguaggi, come FORTRAN, utilizzano l'archiviazione a livello di colonna per i loro array multidimensionali per impostazione predefinita; e OpenGL utilizza anche l'archiviazione principale delle colonne.
Ora, completamente separatamente, c'è un'altra scelta della convenzione, che è se utilizzare la matematica vettore riga o vettore colonna. Questo non ha nulla a che fare con il layout di memoria delle matrici, ma influenza il modo in cui costruisci le tue matrici e l'ordine di moltiplicazione. Se si utilizzano vettori riga, farete vettore-matrice di moltiplicazione:
[ a b c d ]
[x y z w] * [ e f g h ] = [x*a + y*e + z*i + w*m, ... ]
[ i j k l ]
[ m n o p ]
e se si utilizza vettori colonna, poi farete matrice-vettore moltiplicazione:
[ a b c d ] [ x ]
[ e f g h ] * [ y ] = [x*a + y*b + z*c + w*d, ... ]
[ i j k l ] [ z ]
[ m n o p ] [ w ]
Questo perché in matematica vettoriale riga, un vettore è in realtà una matrice 1 × n (una singola riga), e in matematica vettore colonna è una matrice n × 1 (una singola colonna) e la regola su quali dimensioni delle matrici possono essere moltiplicato insieme determina l'ordine. (Non è possibile moltiplicare una matrice 4 × 4 con una matrice 1 × 4, ma è possibile moltiplicare una matrice 4 × 4 con una 4 × 1.)
Si noti che la matrice non è cambiata tra i due equazioni sopra; solo l'interpretazione del vettore è cambiata.
Quindi, per tornare alla tua domanda iniziale:
Quando si passa un vettore di HLSL di mul
, interpreta automaticamente "in modo corretto", secondo cui argomento è. Se il vettore è a destra, è un vettore riga e, se è a sinistra, è un vettore colonna.
Tuttavia, la matrice viene sempre interpretata allo stesso modo. Una matrice è una matrice, indipendentemente dal fatto che venga moltiplicata con un vettore riga sul lato sinistro o un vettore colonna sulla destra. Puoi decidere liberamente se utilizzare la matematica riga-vettore o vettore colonna nel codice, a condizione di essere coerenti. HLSL è agnostico su questo punto, sebbene la libreria matematica D3DX utilizzi i vettori di riga.
E si scopre che per qualche motivo, in D3D9 HLSL, mul
si aspetta sempre che le matrici vengano archiviate nell'ordine delle colonne. Tuttavia, la libreria matematica D3DX memorizza le matrici nell'ordine delle righe e, come dice la documentazione, ID3DXBaseEffect::SetMatrix()
prevede l'immissione in ordine di riga principale. Effettua una trasposizione dietro le quinte per preparare la matrice per l'uso con mul
.
BTW, D3D11 HLSL imposta automaticamente l'ordine di colonna principale, ma consente di utilizzare una direttiva del compilatore per indicare di utilizzare invece l'ordine di riga principale. È ancora agnostico rispetto alla matematica vettoriale riga-vettore-riga. E OpenGL GLSL usa anche l'ordine delle colonne, ma non (per quanto ne so) fornisce un modo per cambiarlo.
Ulteriori letture su questi temi:
+1 Grazie, credo che sia tutto su come ordinare poi. Ottimo layout di risposta! – dk123
Questo non è giusto. C'è una differenza tra "row-major" (che riguarda i componenti della matrice degli ordini sono memorizzati in memoria) e "convenzione vettoriale delle righe" (che è circa l'ordine di moltiplicazione). La matrice qui è * memorizzata * in ordine di riga principale in entrambi i casi. Il primo caso utilizza un vettore riga e il secondo caso un vettore colonna (e la matrice dovrebbe essere stata costruita in modo appropriato per ciascuno). –