De la 2D pure à l'illusion de la 3D
Ce moteur n'a rien d'un vrai moteur 3D : il n'y a ni polygones, ni matrices de projection, ni carte de profondeur. Juste une carte en grille — des cases pleines (murs) et des cases vides — parcourue par des rayons, exactement comme le faisait Wolfenstein 3D en 1992 sur des machines qui ne savaient pas dessiner un triangle texturé. Toute la sensation de relief tient dans une idée : lancer un rayon par colonne d'écran et en déduire la hauteur d'un mur.
Un rayon par colonne, avancé en DDA
Pour chaque colonne de l'image, je construis un rayon qui part de la caméra et traverse le plan de l'écran, puis je le fais avancer sur la grille par DDA (Digital Differential Analyzer). Plutôt que de progresser à petits pas réguliers — coûteux et faillible — le DDA saute directement d'une frontière de cellule à la suivante : à chaque itération, je compare la distance jusqu'au prochain bord vertical et jusqu'au prochain bord horizontal, et j'avance vers le plus proche. En quelques sauts, le rayon atteint la première case pleine. C'est exact, sans jamais « rater » un mur fin, et borné par la taille de la carte.
La hauteur d'un mur est l'inverse de sa distance
Une fois le mur touché, la projection en perspective se résume à une division : la hauteur de la tranche verticale à dessiner est inversement proportionnelle à la distance. Un mur deux fois plus loin occupe deux fois moins de hauteur à l'écran. Je dessine alors une seule bande verticale, centrée, aussi haute que le dicte cette distance — et l'accumulation de ces bandes, colonne après colonne, reconstitue un couloir en perspective sans jamais manipuler la moindre géométrie 3D.
Corriger la distorsion « fisheye »
Le piège classique : si l'on mesure la distance euclidienne du joueur au mur, les murs se courbent vers les bords de l'écran comme dans un objectif fisheye. La parade est de projeter cette distance sur l'axe de la caméra — d'utiliser la distance perpendiculaire au plan de la caméra, et non la distance au point de vue. Le calcul tombe naturellement du DDA, sans trigonométrie coûteuse par pixel, et les murs redeviennent bien droits.
Teinter pour donner du relief
Un couloir tout d'une couleur resterait plat. J'assombris donc chaque tranche selon deux critères : la distance — un brouillard discret fait fondre les murs lointains dans l'obscurité — et l'orientation de la face touchée, les faces nord-sud étant rendues plus sombres que les faces est-ouest. Ce simple contraste entre deux teintes suffit à faire lire les angles et les coins, et donne au rendu colonne par colonne son épaisseur.
Ce que je retire d'un vieux truc d'arcade
Le raycasting est un modèle réduit de ce que je recherche sur les projets sérieux : choisir la représentation qui rend le problème simple. Ici, ramener un rendu 3D à une boucle de divisions sur une grille transforme un calcul intimidant en code clair, rapide et prévisible. C'est la même démarche que j'applique à une architecture logicielle — trouver l'angle qui fait disparaître la complexité inutile — pour livrer une base performante que votre équipe pourra reprendre et faire évoluer sans moi.