Analyse pour l'optimisation de mon moteur 3D
Par -Alexandre LEGOUT aka LAlex- le jeudi, août 21 2003, 11:42 - Divers - Lien permanent
Je me re-penche actuellement sur mon moteur 3D, entamé il y a maintenant 3 ans sur Flash 5. Depuis, je l'ai porté sur Flash 6, me permettant ainsi d'utiliser quelques notions de POO, et les API de dessin pour remplir les faces et gérer les lumières. Mais depuis, j'ai appris beaucoup plus sur notamment l'héritage et le programmation évenementielle dans Flash MX. Voici donc les reflexions que j'ai entammées sur l'optimisation de ce moteur.
Tout d'abord, un bref résumé de la structure générale d'un moteur 3D :
- Un point en 3D comporte 3 coordonnées : x (abscisse), y (ordonnée), et z (profondeur).
- Une transformation est composée de trois points 3D spécifiant :
- La translation : deplacement d'un point.
- La rotation : rotation d'un point par rapport au point d'origine.
- L'homotétie : multiplication de la distance entre un point et le point d'origine par un ratio (pourcentage).
- La translation : deplacement d'un point.
- Un environnement 3D doit inclure un "point de vue", souvent appelé "Camera". Ce point de vue est situé a des coordonnées (est donc un point 3D), et peut subir des transformations (pour la caméra, l'homotétie n'existe pas).
- L'environnement 3D contient aussi un point 3D "lumière", qui indique la position de la source lumineuse. On pourra aussi ajouter une propriété "instensité" de la source lumineuse.
- L'environnement (ou la caméra, s'il peut y en avoir plusieurs) possède aussi une distance focale.
- L'environnement possède aussi un point 2D indiquant le point d'origine des coordonnées à l'écran.
- Un Vertex est un point 3D accompagné de l'ensemble des étapes intermédiaires pour arriver à le projeter sur l'écran. Il comporte :
- Le point 3D d'origine.
- Le point 3D obtenu aprés applications des transformations du point.
- Le point 3D situé par rapport à l'environnement (caméra).
- Le point 2D projeté sur l'écran.
- Les méthodes pour passer d'une étape à l'autre. Nous les appelerons : coord2env, env2align, align2screen
Les instructions qui prennent le plus de temps processeur sont les transformations, notamment les rotations qui font une grande utilisation des fonctions trigonométriques sinus et cosinus.
L'optimisation va donc passer par le fait de ne pas recalculer une étape qui n'a pas changée. C'est là que la programmation évenementielle liée à l'instruction addProperty va nous servir. En effet, le addProperty permet de créer des propriétés "publiques" associées avec une méthode get et une méthode set. Il suffit donc que les méthodes set diffusent les évenements 'onChange' appropriés. Le problème délicat est aussi de placer les écouteurs aux bons endroits. Récapitulons quels sont les changements qui peuvent intervenir, et quelles sont leurs conséquences :
- Un point change de coordonnées ou de transformation : il faut donc repasser, uniquement pour ce vertex, par les étapes coord2env, env2align, align2screen.
- Une forme change de transformation : il faut refaire la totalité des calculs pour tous les vertex qui la composent.
- La caméra change de position : il faut effectuer la totalité des calculs pour toutes les formes présentes.
Quoi qu'il en soit, il faut faire attentiion durant toute la programmation à appeler soit la propriété publique si l'on veut déclencher un évenement (et les traitements qui en découlent) soit la propriété privée si on veut faire cela en "toute discrétion".
Un des points qui me pose problème, est de savoir si par exemple un Vertex doit connaitre sa transformation ou pas. Si c'est la cas, il faut faire trés attention à ce que la transformation du Vertex soit toujours la même que celle de la forme à laquelle il appartient. La modification de la transformation de la forme devra alors diffuser un évenement écouté par ses Vertex afin qu'ils se mettent à jours systématiquement. En fait, la question est de savoir si un Vertex peut avoir une existence propre, ou s'il doit obligatoirement faire partie d'un forme... Si vous avez la réponse, n'hésitez pas à me la donner (argumentée bien sur...) !!!
J'ai pensé également à augmenter le nombre d'étapes de transformation du Vertex, en mettant une étape pour chaque tranformation individuelle (translation, rotation et homotétie), qui elles aussi doivent s'effectuer dans un ordre bien précis (l'homotétie n'est pas utilisée par la caméra) : 1=homotétie, 2=rotation, 3=translation. Si seule la translation change, cela éviterais de refaire une rotation, et permettrais alors une précieuse économie de calculs trigonométrique.
Voila pour mes quelques réflexions sur l'optimisation de mon moteur, qui vont être mises en pratique prochainement. Je suis bien sûr ouvert à toute suggestion ! Dés que j'aurais fini le recodage et l'optimisation de ce moteur, je le mettrai a disposition ici-même, et je compte même créer un script PHP qui permettra de transormer un fichier ASCII .3ds en format XML, importable dans le moteur.
PS : Voici un petit exemple de moteur 3D tout simplement bluffant : http://www.mx3d.com/ ... J'arriverais à faire le même !!! ;D
Commentaires
Salut Lalex, Sympa ce blog! Et ya la dose, tu a un sacre rendement :)!
En plus des optimisations algorithmiques, on peut aussi noter que le moteur de mx3d par Florian Kruesh est completement optimise jusqu'au bytecode avec flasm. Sans ca, actionscript est sans doute un peu lourd pour un rendu aussi complexe en douceur. Comme le flash player 7 est sense ameliorer les perfomances d'ActionScript. Peut-etre que ce ne sera plus necessaire dans le futur :), A voir.
Fil des commentaires de ce billet