Distemporal Arts

Image aléatoire

Actualités

Le premier projet informatique du site sera un raycaster. J'expliquerai comment il est programmé dans la catégorie Informatique.

01 Juin 2021

Le Inktober 2020 a été ajouté à la section Images. Attention, c'est un contenu gore/horreur.

18 Mars 2021

Le Inktober 2019 a été ajouté à la section Images. Aussi, l'annonce du projet de musée virtuel change de moteur de rendu.

24 Janvier 2021

J'inaugure le déploiement du site web de Distemporal Arts. J'ai hâte de partager mes créations et les sujets que je trouve intéressants.

17 Janvier 2021

Outils



Me suivre

Programmation d'un raycaster basique - Partie 3

Dans ces pages, je décortique les étapes de création d'un raycaster basique dans un but didactique. Un raycaster est un moteur de rendu en 2,5D comme on peut le voir dans le jeu Wolfenstein 3D sorti en 1992. En bonus, des améliorations seront proposées et expliquées en détails.

Fonctionnement de la camera

Dans un raycaster sur grille 2D, on ne cherche pas à rendre une vue en 3 dimensions. Il n'est donc pas nécessaire de pouvoir tourner la caméra vers le haut ou le bas. Cela rend son fonctionnement plus simple, mais il reste possible d'ajouter cette fonctionnalité avec quelques modifications sur le rendu final du monde. Ici, je ne vais pas aborder cet aspect et vais donc me contenter d'utiliser la géométrie en 2 dimensions. Dans cette partie, vous allez apprendre comment initialiser une caméra assez simple, déclarer un plan de projection que j'appellerai "vue", et qui est tout simplement l'écran sur lequel on dessine le monde, et comment tourner la caméra à 360° et bouger sur la carte du monde. Il y aura aussi une fraction de la vue qui sera très pratique pour accélérer les calculs du rendu du monde.

Les besoins minimum de la camera

Pour fonctionner, la caméra aura besoin de quelques attributs et une initialisation minimale. Avant d'entrer dans les détails, voici une représentation graphique de la caméra dans le monde en 2 dimensions.








On peut voir qu'ici, le rayon traverse la vue en un point, et vient toucher un mur (wall). L'intersection du rayon et de la vue est une colonne de pixels dans laquelle on ira calculer la hauteur du mur en fonction de sa distance avec la camera. Le rayon passe par autant de points qu'il y en a dans la largueur de l'écran en pixels. Ainsi, on scanne la largueur de l'écran et cherche des impacts avec des murs pour déterminer leur distance et aussi leur propriété pour dessiner des couleurs, ou des textures appropriées. On ne balaye pas les pixels de haut en bas. On préférera déterminer une hauteur cohérente, ce qui interdit de lever ou baisser la tête sous peine de constater une étrangeté dans la perspective. Cette étrangeté est cependant acceptable aux yeux de l'observateur. D'ailleur, des jeux comme Doom ou Duke-Nukem (qui ne sont pas des raycasters) ont cette bizarrerie visuelle, mais ne sont pas pour autant désagréables à regarder.

Initialiser la caméra

La première chose à faire est d'initialiser la caméra, avant de la déplacer, la faire tourner, ou encore calculer les éléments nécessaires aux calculs du rendu. Pour faire fonctionner notre caméra, nous aurons besoin de la position de la caméra (Pos), de son angle de rotation (Alpha), de la distance entre la position et la vue (Near), et aussi d'initialiser la vue, ainsi que quelques optimisations pour le rendu. Je ne vais pas en parler ici, car cela dépend de votre manière de programmer, et peut-être aussi de votre langage de programmation, mais personnellement, je fais passer en paramètre des outils pour SDL 2 et aussi une boîte à outil pour des mathématiques optimisées et enregistre tout cela dans un pointeur. Cela me permet de ne pas passer ces outils en paramètre de certaines fonctions, et pouvoir y accéder simplement en interne. Il faut aussi la vitesse de déplacement de la caméra, ainsi que sa vitesse de rotation. Ces données peuvent être déclarées sous forme de macro en C ou C++ par exemple, être déclarées dans le constructeur ou bien dans la fonction d'initialisation si on souhaite pouvoir les modifier au cours d'un jeu à l'aide d'une potion, d'un sort ou d'une technologie par exemple. Dans ce dernier cas, on préfèrera les avoir en tant que variables de notre caméra et on voudra peut-être ajouter des fonctions pour les modifier librement.

Tourner la caméra

Pour comprendre la rotation de la caméra, mais aussi d'autres calculs à venir dans le reste du programme, je dois préciser une chose à propos de l'écran et de son influence sur la trigonométrie. Lorsqu'il y a un calcul qui dépend des angles, on utilise le sens trigonométrique. Dans un repère orthonormé classique appris à l'école, ce sens est toujours l'inverse de celui des aiguilles d'une montre. On part de la droite du cercle, et on tourne vers le haut et la gauche, pour revenir du bas vers la droite du cercle trigonométrique. A l'inverse, une montre ou une horloge commençe du haut et tourne vers la gauche, puis revient après un tour complet du bas en passant par la gauche pour atteindre le haut du cercle. Seulement voilà, l'écran en informatique a un repère orthonormé avec l'axe des Y allant vers le bas. On commence le zero absolu en haut à gauche de l'écran et non en bas à gauche. Cela signifie donc qu'aller vers le haut correspond non pas à une addition, mais à une soustraction. Ainsi, dans les calculs trigonométriques, ce changement de signe s'exprime par une rotation vers le bas pour augmenter la valeur de l'angle, et non vers le haut. Finalement, dans le contexte d'un axe Y dont la flèche point vers le bas (soit sinus (alpha) descend, au lieu de monter), on peut se représenter la rotation trigonométrique comme équivalente à celle d'une horloge. Retenez donc bien que dans notre programme, les angles tournent vers le bas du cercle, en partant de la droite, et non l'inverse.

Déplacer la caméra

Calculer la vue

Optimiser les futurs calculs

Dessiner la caméra en 2D

Que ce soit pour visualiser des bugs éventuels, pour mieux comprendre la géométrie derrière le raycasting, ou créer une carte ou un éditeur de niveau pour un jeu-vidéo, il peut être très utile de pouvoir dessiner la caméra et le monde en 2 dimensions.