04 March 2009

Modélisation 3D en cours: vaisseau

Après avoir passé pas mal de temps sur le développement d'une API 3D combinant C++ et OpenGL (API qui est bien sûr loin d'être terminée), j'ai décidé de me replonger un peu dans l'utilisation de Blender. Après avoir acquis les réflexes de base de ce logiciel très performant, et après avoir lu quelques didacticiels pour débuter, je disposais de l'expérience nécessaire pour commencer à réaliser de véritables projets avec ce merveilleux programme de modélisation 3D, libre et gratuit.

Comme vous avez pu le constater sur ce devblog, j'ai commencé mon apprentissage de Blender par quelques scènes plutôt jolies mais géométriquement simples et/ou faciles à réaliser: le salon (simples quadratiques correctement ombragés et texturés), les trois sphères (simples objets de type UVsphere correctement ombragés et texturés) ou le verre de bière (aisément modélisé en combinant les techniques de Spin et de Subsurf). Il était dès lors opportun de mixer les différentes techniques et fonctionnalités apprises lors de mon étude de Blender dans un nouveau projet de modélisation 3D un peu plus complexe, et qui bien sûr pourrait être utilisé conjointement avec mon API de programmation 3D dans le but d'esquisser un premier jeu vidéo (le but ultime...)!

Ayant en tête depuis quelques temps maintenant la réalisation d'un jeu de type Shoot 'em up (où l'on dirige un vaisseau ou avion et que l'on tire sur les assaillants), je me suis décidé à tenter la modélisation d'un engin à mi-chemin entre l'avion de chasse et la navette spatiale, en tentant de lui donner une petite touche de style propre, ce qui est très difficile pour un débutant en modélisation 3D. Le vaisseau pourra être, une fois terminé, exporté en objet Wavefront et inséré dans un programme grâce à mon API C++/OpenGL.

Le vaisseau a été conçu à partir d'un simple cube, c'est-à-dire le quadratique Cube de base fourni dans Blender (six faces, huit sommets, douze arêtes... vous avez compris). En combinant plusieurs fonctionnalités, j'ai réussi à modéliser une première forme brute de base donnant la silouhette générale du vaisseau. On distingue un nez relativement pointu comportant un cockpit (vitre bleue) via lequel le pilote peut prendre place; deux excroissances verticales à l'arrière qui conduisent à deux réacteurs de puissance moyenne (un gros réacteur circulaire est prévu à l'arrière, au centre des deux réacteurs moyens); deux petites ailes horizontales positionnées sur les excroissances verticales; enfin la partie située au delà du cockpit et quelque peu entassée servira à modéliser une partie visible de la machinerie, un peu comme sur certaines supercars/musclecars où le moteur est partiellement visible.

Pour la réalisation, les techniques suivantes ont été utilisées à partir d'un simple cube:
  • Utilisation des Mesh tools (menu Specials)
    • Subdivision de surface
    • Création de bords doux (Bevel)
    • Adoucissement de surface (Smooth et Subdivide Smooth)
    • etc.
  • Extrusions multiples
  • Shrink/Fatten
  • Outils booléens (Boolean Tools)
  • Transform properties (spécification de coordonnées exactes)
  • Duplicate & mirroring (pour la symétrie du vaisseau, je ne travaille que sur la moitié de ce dernier)
  • Separate tools
  • Face specials
  • Faces join
  • Loop/cut
  • etc.
Vous pourrez suivre sur ce blog l'évolution de la modélisation de ce vaisseau.

Lien: La 3D libre avec Blender, livre que mon père m'a acheté et qui est un très bon outil de travail pour apprendre à modéliser en 3D... avec Blender bien sûr. A conseiller!


25 February 2009

Développement d'une API 3D en C++: textures (2)

Je n'ai pas pu résister à l'envie de poster quelques réalisations supplémentaires. C'est comme ça, à chaque fois que je raffine un peu plus mon API 3D et que je la teste à l'aide de quelques programmes dédiés que je développe, je passe parfois bien du temps à contempler le résultat. Cela met du beaume au coeur, mais permet également de s'évader un peu et de réfléchir à la prochaine étape. Je laisse l'inspiration venir en "jouant" avec mes réalisations présentes.

Vous trouverez dans cet article les copies d'écran de trois objets que j'ai modélisés à l'aide de Blender, que j'ai exportés en Wavefront avec ce dernier, et que j'ai finalement chargés dans un programme de test développé à l'aide de mon API C++/OpenGL. Deux objets très simples à modéliser, mais qui comportent aussi bien des aspects d'ombrage et de texture: la Terre et la planète Mars. Et oui, j'ai assez bien la tête dans les étoiles et l'espace me fascine (bien que je ne sois pas un grand fan de Star Wars). Le dernier objet est un peu bizarre, c'est tout à fait normal: il a été modélisé assez rapidement dans le cadre d'une démonstration que j'ai réalisée en famille. La démonstration consistait bien sûr à montrer comment un objet modélisé avec Blender pouvait se retrouver très facilement dans une application 3D basée sur mes travaux.




Développement d'une API 3D en C++: textures

Le développement de ma propre API C++/OpenGL continue, bien que ralentie ces derniers temps suite à un emploi du temps très chargé, et bon nombre d'heures passées sur d'autres travaux informatiques. Bien évidemment, il n'était pas question d'abandonner ce projet: lentement mais sûrement, l'API évolue, permettant de charger des objets 3D de plus en plus complexes... et beaux !

Lors du dernier article, j'avais présenté la fonctionnalité de chargement des matériaux. Tout objet modélisé à partir de Blender peut être exporté, puis affiché dans mon application 3D (basée sur mon API) avec sa géométrie complète, une distribution de la lumière (shading) et certaines caractéristiques comme la couleur spéculaire, le degré de brillance, la couleur diffuse, etc.

Désormais, tout objet modélisé dans Blender peut être exporté avec tous ces aspects, plus une texture appliquée. Ceci incombe que les coordonnées de placage de la texture (UV) soient également exportées dans le fichier Wavefront associé, puis chargées et gérées par l'API 3D. Il est donc désormais possible de créer très rapidement un objet 3D complexe, ombragé, émettant de la lumière et possédant une texture (image au format TIFF), dans toutes mes réalisations 3D.

Je pense avoir implémenté toutes les fonctionnalités de base en ce qui concerne les objets 3D, je vais donc maintenant m'attaquer aux interactions: détection des collisions, mouvements mécaniques, etc. Beaucoup d'amusement en perspective !


31 January 2009

Développement d'une API 3D en C++: base des matériaux

Le développement de mon API C++ basée sur OpenGL suis son cours. Lors du dernier billet de la rubrique "Développement", j'avais présenté les différentes fonctionnalités possibles, et m'étais arrêté sur les vecteurs normaux permettant de diffuser correctement la lumière sur toute la géométrie des objets. Le matériau utilisé pour afficher les objets 3D, dans mon API, était jusqu'ici toujours le même: un gris moyen.

J'ai amélioré l'API afin de gérer les matériaux propres aux objets de type Wavefront. Ces matériaux sont stockés dans des fichiers d'extension .mtl (pour Material Library) et sont composés de plusieurs informations: la couleur ambiante du matériau, sa couleur diffuse, sa couleur spéculaire (renvoyée par la lumière) et l'intensité de la réflection de la lumière (directement liée à la couleur spéculaire). Oh, et la valeur du canal de transparence (alpha) est également lue, mais ce dernier n'est pas encore utilisé (l'Alpha Blending, c'est pour plus tard).

Concrètement, qu'est-ce qui change depuis la dernière version? Et bien, lorsqu'un objet est modélisé à l'aide de Blender, on peut naturellement lui attribuer une quelconque couleur ambiante, spéculaire et diffuse; lorsque l'objet sera exporté en Wavefront et chargé grâce à mon API, ces paramètres définis à l'aide de Blender seront restaurés. Dès lors, il m'est possible de développer une application comportant divers objets 3D où la lumière est prise en compte pour le rendu (shading) - ce qui était déjà le cas auparavant -, mais où les variations de couleurs définies le sont également.

Vous devez peut être vous en douter: la prochaine étape est la prise en charge des textures.

Wait & See !


Le verre de bière 3D est de retour !

Voici le grand retour tant attendu du verre de bière 3D, positionné dans un environnement plus coquet mettant davantage en valeur la réfraction de la lumière. Les plus malins auront remarqué qu'il s'agit d'une ancienne scène que j'avais déjà réalisée par le passé, à laquelle j'ai ajouté le fameux verre. De plus, j'ai appliqué une plus belle texture à la table et aux chaises. Au risque d'en décevoir certains, le verre est toujours vide !


15 January 2009

Le verre de bière 3D

Parmi les nombreux objets représentant un parfait exercice de modélisation, le verre est toujours une composition requérant de l'adresse, de la compétence et un peu d'originalité. Bien que la géométrie résultante de cette modélisation soit complexe, cette dernière ne le fut pas tant. En effet les verres, ainsi que tout objet circulaire dont les points sont équitablement et uniformément répartis autour d'un centre, sont faciles à créer grâce aux fonctions de Spin.

Pour créer ce verre, je l'ai tout d'abord dessiné de profil, et de moitié. En regardant le profil depuis une vue du dessus, on aperçoit ce dernier comme étant un simple tracé droit: c'est le rayon d'un cercle! En appliquant un Spin, ce rayon (et donc, ce profil) est dupliqué un nombre déterminé de fois, par rotation autour d'un axe, pour former un objet rond qui peut ensuite être affiné (Subsurf, Smooth).

Reste les caractéristiques de réfraction à spécifier, ceux-ci sont d'ailleurs souvent bien difficiles à définir, et de nombreux essais ont été nécessaires. D'ailleurs, sur ce rendu, j'ai volontairement désactivé les ombres portées, sans quoi je risquais bien de m'arracher les cheveux! Et oui, la modélisation s'apprend pas à pas.

Pour le choix du verre, je n'ai pu m'empêcher de penser à mes nombreux amis amateurs de bonnes bières belges. Pour un prochain rendu, promis, j'essaierai d'y mettre une belle blonde!


04 January 2009

Développement d'une API 3D en C++

Après avoir acquis les bases nécessaires à la modélisation d'objets et de scènes 3D sous Blender, je me suis tout naturellement tourné vers le développement. En effet, mon apprentissage de Blender n'a pour seul but de concrétiser la création de mes propres personnages, objets et niveaux en 3D en vue de les inclure dans un jeu vidéo ou toute autre application en trois dimensions. Il m'était donc indispensable d'appréhender le développement d'applications 3D. Pour ne pas commencer par un trop gros projet, j'ai entrepris la programmation d'une API (Application Programming Interface) me permettant de lire et charger facilement en mémoire des objets 3D, tout en fournissant bien entendu la possibilité d'afficher ceux-ci à l'écran, sous diverses coutures et en appliquant moults fonctionnalités.

Constat: cela faisait longtemps que je ne m'étais pas autant amusé à programmer ! J'ai sélectionné une arme de premier choix: le C++, version orientée objet et optimisée du très célèbre langage C. J'avais déjà fait un peu de C++ par le passé, mais j'étais rouillé. Aujourd'hui, grâce à mes travaux, j'ai pu réapprendre à programmer avec ce langage, et même à améliorer mes connaissances et compétences. A l'heure actuelle, je n'ai rencontré aucun obstacle que je n'ai pu franchir en m'appliquant correctement tout en lisant didacticiels et références. En ce qui concerne les aspects 3D, j'utilise l'API OpenGL, bien sûr, vu qu'il est libre et qu'il se marie très bien avec le C++. Mais c'est aussi parceque j'avais déjà un peu d'expérience dans le domaine, je dois bien l'avouer. Mes études universitaires n'y sont pas pour rien.

Alors, cette interface de programmation, que diable fait-elle? Le fait est qu'OpenGL fournit un ensemble de fonctionnalités et routines procédurales et pas vraiment orientées objet. Or, ce dernier paradigme est crucial pour tout bon développeur qui se respecte (et pour tout bon logiciel, soit dit en passant). Dès lors, je me suis attellé à la création d'une API fournissant diverses classes d'objet C++ permettant de gérer les aspects 3D d'un programme. Ainsi, j'ai conçu des objets Vertex, des Face, des VertexNormal, des ShadedFace ou encore des WFObject (objets 3D chargés à partir d'un fichier Wavefront, d'extension .obj). Concrètement, il est ainsi possible de représenter un mesh 3D à partir de ces objets. Chaque mesh est composé d'un nombre défini de points dans l'espace, appellés vertices (le pluriel de vertex). Quatre vertices peuvent représenter une face, et un grand nombre de faces assemblées les unes aux autres forment un objet en trois dimensions. Plus il y a de faces, plus l'objet possède une géométrie agréable à regarder et proche de la réalité. L'API que j'ai développée permet ainsi de mettre facilement en musique tout ces concepts, de lire toutes les données requises pour la création d'un objet dans un fichier, et d'afficher l'objet en 3D à l'écran par le simple appel d'une méthode nommée draw().

Suite à de nombreuses lignes de code (et de nombreuses heures), j'ai pu représenter des objets 3D construits à partir de faces à 3 ou 4 points. Ces faces possèdent également des normales (vecteurs directeurs) permettant de définir correctement la diffusion de la lumière sur l'objet (cf la photo de cet article). Je peux donc désormais charger dans une application 3D de ma création, tout objet 3D conçu par mes soins via Blender. Voici déjà un premier pas franchi vers la création de logiciels 3D avancés, comme par exemple... des jeux vidéo!

Les prochaines étapes du développement de cette API sont la prise en charge des matériaux associés à l'objet (couleur diffuse, spéculaire, degré de brillance, etc.) ainsi que des textures et leurs coordonnées. Ensuite, je compte définir des bounding boxes sur mes objets afin de définir les limites de leur volume dans l'espace, ce qui permet d'appliquer un algorithme de détection de collisions !

Stay tuned, comme on dit.