Maths pour le rendu 3D — 05 — Row-major vs column-major

La convention qui sème la zizanie entre moteurs et API : vecteur-ligne ou vecteur-colonne, pré- ou post-multiplication, ordre de lecture des transformations, et le mythe du stockage mémoire.

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.

Réservez un audit gratuit de 30 minutes. Je vous montre concrètement ce qu'on peut automatiser.