Ce projet contruit, à partir de zéro, un moteur de 3D sur l'invité de commandes Windows.
L'objectif du projet était de montrer qu'il est possible de créer son propre moteur à partir:
- des opérations arithmétiques de base (addition, soustraction, multiplication, division)
- de techniques de programmation usuelles (boucles, recursivité, conditions, classes, ...)
- de mathématiques
Aucune bibliothèque n'a été utilisé. Pour pouvoir communiquer avec le système Windows, seuls ces deux fichiers d'entête ont du être importés:
-
<windows.h>
pour pouvoir redimensionner la console et afficher des caractères. Ici dans le code source. -
<stdio.h>
pour pouvoir lire le contenu d'un fichier. (importer des modèles depuis Blender 3D). Ici dans le code source.
On est donc contraint de redéfinir des fonctions mathématiques comme cosinus
, sinus
ou encore racine carrée
.
Le projet a été écrit avec Sublime Text et compilé avec MinGW à l'aide de la commande suivante:
g++ *.cpp
Ces fonctions mathématiques sont vitales, elles nous serviront pour définir la projection en perspective et la rotation d'un objet selon un axe.
Nous avons besoin d'utiliser la formule trigonométrique suivante:
Cette équation est intéressante car elle définit la fonction cosinus à partir d'elle-même, mais avec angle plus petit. Cela peut paraître anodin, mais en réalité cela va nous permettre de restreindre le calcul de cosinus à de petits angles.
Prenons par exemple le cas de cos(1)
:
En utilisant la formule du dessus:
Donc pour calculer cos 1
, il me suffit de calculer cos(0.5)
, pour calculer cos(0.5)
... on réitère:
l'angle est divisé par deux à chaque itération, il suffit donc de continuer jusqu'à atteindre un angle suffisamment petit.
Pour de (très) petits angles, on approxime cosinus
en utilisant son développement limité au voisinage de 0 (à l'ordre 4):
Pour x
très petit on a donc:
En rouge j'ai tracé la fonction cos, et en bleu son développement limité, on voit que pour de petits angles, c'est une bonne approximation.
Son implémentation se trouve ici. J'ai un peu factorisé le développement limité de cosinus pour éviter les calculs redondants.
En connaissant cosinus
, c'est immédiat ! Il suffit de prendre la formule suivante:
Une valeur approximative de pi
a été écrite en dur dans le fichier math.h. L'implémentation de sinus se trouve ici.
Par définition:
...et on sait déjà calculer cosinus
et sinus
!
L'implémentation de cotangente se trouve ici.
(ce n'est pas ce qu'il y a de plus optimal, mais c'est largement suffisant)
Cette fonction nous servira à déterminer la distance entre deux points dans l'espace (via le théorème de Pythagore).
Cela nous sera notamment utile pour les calculs de luminosité (plus un point est éloigné de la source lumineuse, moins il est éclairé)
On souhaite trouver la racine carrée d'un nombre que je vais appeler x
.
Cela revient à dire que l'on recherche le nombre r
tel que,
ou encore que l'on souhaite résoudre l'équation,
Si on pose,
rechercher la racine carrée de x, revient à chercher pour quelle valeur de x
la fonction f
s'annule.
J'ai utilisé la méthode de Newton pour trouver cette valeur. On obtient que la suite U(n) telle que
converge vers racine de x.
Pour obtenir le résultat, il suffit alors de calculer les valeurs successives de U(n) jusqu'à une valeur de n
suffisamment grande (j'ai pris 50). L'implémentation se trouve ici.
[TODO]