05 — Row-major vs column-major
Ce que tu vas apprendre
- La différence entre vecteur-ligne et vecteur-colonne
- Pré-multiplication (
P×M) contre post-multiplication (M×P) - Pourquoi l'ordre de lecture d'une chaîne de transformations s'inverse
- Le mythe du stockage mémoire « plus rapide »
Prérequis
Si un sujet déclenche des guerres de tranchées sur les forums de graphisme, c'est celui-ci. Le même point, la même matrice, le même résultat — mais deux façons de l'écrire, qui s'inversent. Comprendre la convention te sauve des heures de débogage où « tout est juste mais l'objet part dans le mur ».
Vecteur-ligne ou vecteur-colonne
Un vecteur peut s'écrire de deux manières, mathématiquement équivalentes :
- Vecteur-ligne (matrice 1×3) : les trois nombres sur une rangée horizontale.
- Vecteur-colonne (matrice 3×1) : les trois nombres empilés verticalement.
Aucune n'est « la bonne ». C'est une convention. Mais elle décide de tout ce qui suit.
Pré- ou post-multiplication
La forme du vecteur impose de quel côté il multiplie la matrice :
- Vecteur-ligne → pré-multiplication :
P × M. Le point est à gauche. Ça se lit comme une phrase : « multiplie ce point par cette matrice ». C'est la convention de Scratchapixel (et de DirectX/HLSL). - Vecteur-colonne → post-multiplication :
M × P. La matrice est à gauche. C'est la convention des maths classiques et d'OpenGL/GLSL.
Les deux donnent le même point transformé. Mais l'écriture diffère, et c'est là que les erreurs s'installent quand on copie du code d'une convention à l'autre.
L'ordre des transformations s'inverse
Conséquence directe et déroutante : enchaîner plusieurs transformations se lit dans des sens opposés selon la convention.
Vecteur-ligne (Scratchapixel) : P × T × Rz × Ry
→ se lit de gauche à droite, dans l'ordre d'application
Vecteur-colonne (maths/OpenGL) : Ry × Rz × T × P
→ se lit de droite à gauche : P d'abord, puis T, puis Rz, puis Ry
Dans la convention vecteur-colonne, on écrit les transformations dans l'ordre inverse de leur application — la première appliquée est collée au vecteur, donc tout à droite. C'est contre-intuitif et c'est exactement pour ça que Scratchapixel a choisi le vecteur-ligne : la chaîne se lit dans l'ordre où les choses se passent.
Le mythe du stockage mémoire
On lit souvent que le row-major serait « plus rapide » que le column-major à cause de la localité de cache. C'est, dans le cas qui nous occupe, faux. Il n'y a strictement aucune différence de disposition en mémoire entre une matrice row-major et column-major dès lors qu'elles sont implémentées correctement en C/C++ : si tu stockes les colonnes d'une matrice column-major comme les rangées d'un tableau 4×4, l'arrangement mémoire devient identique. L'argument de performance souvent cité en ligne ne tient pas. La vraie distinction est notationnelle (où va le vecteur dans la multiplication), pas matérielle.
Attention à ne pas confondre deux choses qui portent les mêmes mots :
- vecteur-ligne / vecteur-colonne : une convention mathématique (de quel côté multiplier) ;
- row-major / column-major storage : une convention de rangement mémoire d'un tableau 2D.
Les deux sont indépendantes, même si le vocabulaire les emmêle.
En pratique : connais ta pile
| Côté | Convention vecteur | Multiplication |
|---|---|---|
| Scratchapixel, DirectX/HLSL | vecteur-ligne | P × M |
| Maths classiques, OpenGL/GLSL | vecteur-colonne | M × P |
GLSL attend par défaut la post-multiplication (M * vec4) ; le HLSL est row-major par défaut ; GLSL moderne sait basculer avec layout(row_major). La distinction compte surtout dans le code de shader, où une matrice mal orientée donne un écran noir sans message d'erreur. La règle de survie : sache quelle convention utilise chaque morceau de ta pile, et transpose explicitement quand tu passes de l'un à l'autre.
L'article suivant quitte les matrices générales pour deux outils pratiques : les coordonnées sphériques (penser en angles) et la construction d'un repère local sur mesure.
Sources
- Scratchapixel. Geometry — Row-Major vs Column-Major Vectors and Matrices. scratchapixel.com
- Lengyel, E. (2011). Mathematics for 3D Game Programming and Computer Graphics (3ᵉ éd.), annexe sur les conventions matricielles. Cengage.
- Documentation OpenGL/GLSL et DirectX/HLSL sur l'ordre de multiplication des matrices.