Forum Programmation.c++ Rendu 3D

Posté par .
Tags :
1
26
avr.
2011

Depuis quelques mois je travaille sur une version de l'algorithme du zbuffer. Celui-ci permet le rendu en "3D" d'objets composés de faces planes (triangulaires ou quadrilatérales). La version que je propose est un algorithme par division de facettes. Deux autres versions sont proposées dans les sources : 1) avec un point de fuite (les lignes parallèles convergent en profondeur vers un point). Cette version n'est pas encore au point. Je dois encore peaufiner les calculs. 2 Une autre version qui ne fonctionne pas bien: rendu isométrique, qui est de loin le plus économe en temps de calculs.

La version par division de facettes fonctionne fort bien. Le cube est dessiné correctement sans qu'il y ait trop de débordements au niveau des pixels.

Une vidéo d'exemple avec un cube en rotation est proposée avec les sources.

Je vais passer à l'étape suivante qui est d'importer des modèles existants (meuble, théière, personnage humain, etc) et le rendre à l'écran.

Je remercie les quelques quidams qui m'ont défendu lors de mon précédent lynchage sur son site. (Si ça se reproduit je demande aux modérateurs la suppression de toutes mes contributions à Linuxfr). A vous de voir. Il y a d'autres sites où je peux présenter mes projets.

Ceci dit:
http://ibiiztera.be/devtools/projects/pmatrix/PMatrix.zip pour le code source (C++ à la dernière version) Notez qu'il n'y a pas encore de licence (il faut que je demande le texte à mon avocat et ça coute un os...)
http://ibiiztera.be/devtools/projects/pmatrix/output.avi pour le cube en rotation

http://youtube.com/manuh008/ pour les vidéos précédentes.

Groupe de discussion utilisateurs et développeurs: https://groups.google.com/group/actif-3d-users-discussion-group?msg=new&lnk=gcis&hl=fr

allez siesta si !

MISE A JOUR ::
- Je me rends compte que le projet ne compile pas sous Windows ni sous Linux avec MinGW/GCC depuis que j'ai réordonné les sources. Ce sera fixé sous peu. Vous pouvez me contacter si vous comptez exécuter les sources.
- La licence sera également fixée sous peu.

  • # Pourquoi ? Pourquoi pas ?

    Posté par (page perso) . Évalué à 2.

    Mon "Pourquoi ?" n'est pas un appel au troll, d'où le "Pourquoi pas ?". N'ayant pas vu ton journal/forum précédent, j'ignore tout de tes motivations. Que ton logiciel ne soit pas nouveau n'est pas une raison pour t'interdire ni-même te critiquer de le faire. Mais j'aimerais bien savoir ce qui te motive en cela.

    Tout ça car je suis un peu dans le même cas que toi : je suis très fan de 3D également et modeleur à mes heures perdues; j'ai toujours dans un coin mon projet de moteur 3D en C++ (merci NeHe pour les leçons d'OpenGL) que je range dans la même catégorie que ton projet : existant sûrement déjà donc peut-être inutile mais tellement passionnant (pour moi) qu'indiscutable (pour moi).

  • # "Si ça se reproduit je demande aux modérateurs la suppression de toutes mes contributions à Linuxfr"

    Posté par . Évalué à 3.

    dur ...

  • # ZBuffer par division de facettes

    Posté par . Évalué à 2.

    Je vois un cube qui tourne dans ta vidéo, mais je ne comprends pas vraiment ce que tu fais (ou souhaite faire).

    En fait je n'ai jamais entendu parler de la "division de facettes", As-tu de la littérature sur le sujet ? Peux-tu expliquer la problématique, le fonctionnement, ... ?

    • [^] # Re: ZBuffer par division de facettes

      Posté par . Évalué à 3.

      je me pose aussi la question car de ce que je me souviens de mes programmes en OpenGL
      il faut juste lui dire que tu veux un cube, avec les coordonnées, et le mode de rendu que tu veux utiliser.

      pas besoin de recalculer les faces, il faut juste lui passer une option au moment du rendu.

      ou alors j'ai pas compris que ce tu fais.

      • [^] # Qu'est-ce que c'est?

        Posté par . Évalué à 1.

        Qu'on ne me prenne pas pour un illuminé de première! (bien que je le sois un peu)

        La division de facette devraient plutôt s'appeler " la subdivision de facettes".
        J'explique.

        On a un algorithme de rendu qui prend en entrée :
        - les coordonnées des objets. La structure de données adoptée est simple et consiste en une liste de triangle. Un triangle est formé de 3 points avec leurs coordonnées x, y et z soit 9 nombres float (ou double) par triangle.

        Par exemple un cube est composé de 6 faces chacune est divisée en 2 pour obtenir deux triangles (ou facettes) par face de pet de cube.
        Un personnage 3d sera composé de plus de facettes.

        Pourquoi des triangles? La réponse est simple: un plan dans l'espace est déterminé par définition de 3 points. Soit 3 points quelconques, on obtient, dans le cas ordinaire, un plan. En juxtaposant des plans, on peut déterminer l'enveloppe d'un objet 3D, ce qu'on souhaite dessiner. Ce dessin sera ressemblant à l'objet.

        Ce n'est peut-être pas le meilleur procédé, ce n'est qu'une simplification pour la synthèse d'objet 3D.

        Exemple de triangle:
        FacettedObject *fo = new FacettedObject();
        fo->ajouterFacette(Point3D(0,0,0), Point3D(0,1,0), Point3D(1,1,0), Color(255,255,255));

        Ce qui ajoute une facette blanche à notre objet.
        - La deuxième entrée de l'algo: les projections 2D des 3 axes 3D x,y,z.

        A partir de ces 2 entrées l'algo produit une image, que l'on peut afficher à l'écran, imprimer, sauvegarder sur disque, encoder dans une animation vidéo.

        La subdivsion de facettes proprement dite est une bidouille que j'ai inventée (à moins qu'un "plagieur par anticipation" se désigne.

        Le problème qui y mène est le suivant: l'algo du zbuffer parcourt l'écran et pour chaque point P(x,y) et chaque facette f, calcule l'intersection entre la droite 3D passant par le point P(x,y) et la facette f. Il est important de préciser qu'il s'agit bien d'une droite au point P, car le point de l'écran en 2D est en fait la projection de la droite 3D dont tous les points se trouvent projetés au point P.

        -> Un des problèmes du zbuffer est de trouver les coordonnées de cette droite. CAR c'est les coordonnées z (profondeur) des différents points d'intersections avec les facettes qui vont permettre de trier les facettes afin d'afficher seulement les facettes qui sont devant les autres. (voir schéma sur internet du zbufffer)

        La subdivision de facettes contourne ce problème. Au lieu de calculer directement z par une formule, on itère, pour chaque facette, en divisant f jusqu'à obtenir des surfaces à l'écran <= 1 (= 1 pixel).
        La division se fait comme ceci:
        Diviser f
        Prendre M= (P1+P2+P3)/3 P12= (P1+P2)/2 P23= (P2+P3)/2 P31= (P3+P1)/2
        f sub 1 = P1 M P12; f sub 2 = P12 M P2 ; f sub 3 = P2 M P23 ; f sub 4= P23 M P3 ; f sub 5 = P3 M P31 ; f sub 6 = P31 M P1
        Diviser f sub (1, 6) si surface >1

        Le bénéfice est le suivant : on peut estimer que si surface(fn) est suffisamment petit (concrètement 1 pixel), on a que (fn:P1 fn:P2 + fn:P3)/3 sont les coordonnées de la facette que l'on va tracer au pixel P.

        L'algorithme n'est pas parfait au niveau du rendu, mais ça fonctionne bien. (voir illustration sur Youtube cube tournant autour d'un axe, et d'autres objets que je vais rendre bientôt)...

        • [^] # Re: Qu'est-ce que c'est?

          Posté par (page perso) . Évalué à 2. Dernière modification le 26/04/11 à 19:55.

          Cela correspond-t-il à
          http://fr.wikipedia.org/wiki/Mod%C3%A9lisation_3D#Mod.C3.A9lisation_par_subdivision_de_surface ? ('fin un cas particulier vu que que tes surfaces sont déjà planes et polygonales).

          C'est ce que je faisais déjà au siècle dernier (mais avec peu de polygones et des temps de génération non temps-réel, hormis sur SGI...).

          Sur quels algos existants te bases-tu ? (peut-être as-tu des URL ?)

          As-tu regardé comment Blender ou BRL-CAD ou SagCAD ou encore Wings_3D procèdent ?

          • [^] # Re: Qu'est-ce que c'est?

            Posté par (page perso) . Évalué à 2.

            Non, ça ne correspond pas à l'article Wikipedia que tu cites.

            La subdivision de surface correspond à une méthode permettant de lisser des surfaces (sous entendu, courbes) Une façon de polir un objet, en fait. Il s'agit du modificateur SubSurf dans Blender, ou des modificateurs MeshSmooth ou TurboSmooth dans certains équivalents propriétaires. On parle là de modification/amélioration de la géométrie d'un objet 3D.

            La subdivision de triangles utilisée par manu008 correspond à une façon de calculer si tel pixel de l'écran fait partie de l'affichage à l'écran d'un triangle donné. On parle donc là de dessin en 2D d'un objet à l'écran.

            • [^] # Re: Qu'est-ce que c'est?

              Posté par (page perso) . Évalué à 2.

              bin je n'ai pas retrouvé de page correspondant mieux :/

              c'est en gros l'algo que j'utilisais pour des surfaces paramétrées en 3D, avec un calcul du barycentre en 3D, puis tri des surfaces selon le Z dans le référentiel de l'observateur de la scène du plus profond jusqu'au plus proche pour les dessiner (les surfaces les plus proches recouvrent les plus éloignées lors du rendu), et zou : yavait quelques artefacts sur les surfaces s'intersectant, mais pour des surfaces convexes cela fonctionnait plutôt bien.

              J'ai oublié de citer K3Dsurf qui me semble faire le même genre de chose (mais quasi en temps réel de nos jours...).

              • [^] # Re: Qu'est-ce que c'est?

                Posté par . Évalué à 1.

                Je pensais justement appliquer la technique que j'ai développée pour les triangles à des surfaces paramétrées (notamment des NURBS ou surfaces de Bézier) à l'avenir: sub-diviser l'intervalle de résolution des paramètres jusqu'à obtenir une définition de 1 pixel. Je pense que ça devrait bien fonctionner...

                Quand aux différents projets que tu cites, la plupart ne fonctionne pas sur ma machine Linux. Ce qui n'est pas un argument en soi, bien que ce soit genant pour les tests. Sous Windows, j'ai réussi il y a longtemps à faire tourner quelques applis.

                J'ai essayé récemment Cinema4D, qui a l'air bien fait. Il y a quelques le libre: Art of Illusion, qui est un travail réalisé par un amateur et est intéressant.

                Ce qui m'intéresse:
                - l'éditeur d'objets
                - le stockage des données, avec la possibilité d'importer plusieurs formats.
                - les effets spéciaux
                - l'animation vidéo

                • [^] # Re: Qu'est-ce que c'est?

                  Posté par . Évalué à 2.

                  Tu devrais regarder la manière de gérer/créer les objets. Je pense qu'il y a un gros travail à faire sur le rendu algorithmique des objets. Le rendu des jeux actuelles se ressemblent tous et c'est pas génial.

                  Par exemple, si tu définit une primitive de sphère, tu peux avoir un algo qui génère le bon nombre de triangles pour que cela apparaisse lisse à l'écran. L'idée serait d'avoir une méthode naturel et compact pour représenter les objets et un moyen efficace de faire un rendu.

                  Un truc très sympa pour le rendu naturel est la "metaball". Le rendu se fait en passant par la création de triangle ce qui est très couteux. Je me suis toujours demandé si on ne pouvait pas faire un rendu directement, sachant que les donnés de base c'est le centre de la balle, sa dimension (4 nombres pour définir une surface).

                  Sinon pour améliorer ton rendu, une téchnique habituelle est de faire du quad pixel. En gros, tu fais tes calculs pour 0.25 de la taille de ton pixel ou lieu de 1, puis tu fais une moyenne pondéré pour avoir la vrai valeur de couleur. Cela te fera de l’antialiasing à pas trop chère.

                  "La première sécurité est la liberté"

        • [^] # Re: Qu'est-ce que c'est?

          Posté par . Évalué à 1.

          à ton avis, qu'est ce qui est plus performant :
          - un iteration sur toutes les faces pour calculer ton fn()
          - appliquer les formules definies dans opengl pour faire du backface culling (ne pas afficher les faces arrieres) et du clipping (ne pas calculer les objets que l'on ne voit pas)

          • [^] # Re: Qu'est-ce que c'est?

            Posté par . Évalué à 1.

            En terme de performances, mon logiciel n'est pas encore au point.

            L'algorithme que j'utilise pour itérer sur les faces de l'objet et les diviser est au point dans ce sens où on n'a pas à calculer des points qui se situeraient en dehors des objets à dessiner.

            Le backface culling permet de cacher les faces arrières, je peux l'implémenter dans mon programme en utilisant les normales des facettes. Une normale négative entrainerait l'élimination de la facette. Une normale positive son acceptation comme candidate pour le tracé.

            Quand au clipping, il permet de ne pas calculer les objets qu'on ne voit pas. Ce que ça m'inspire en terme d'algorithme est un précalcul de terrains : en fonction de la position x du véhicule, on peut déterminer quels objets sont définitivement hors champ (un arbre situé à 500 mètres par exemple) quels objets sont candidats pour la mise en champ. Et puis faire le calcul temps réel (dans cet exemple pour un jeu de voiture), afin de calculer l'écran courant. Je ne pense pas aux objets cachés derrière un autre, bien que le cas en question devrait être considéré.

            PS: je te trouve mignon sur la photo on pourrait se rencontrer pour amitié ou plus si affinité :) : ) : ) ) ah ha ha

            • [^] # Re: Qu'est-ce que c'est?

              Posté par . Évalué à 3.

              si tu codes en OpenGL, tous les details que tu cites sont deja gérés

              • clipping : ne pas afficher un objet qui est loin, ou masqué derriere un autre
              • backface culling : ne pas afficher les faces "arrieres" d'un objet (en fait ne pas les calculer du tout.

              donc le recreer pour la curiosité mathematique et scientifique, pourquoi pas
              mais cela fera-t-il mieux que les implementations existantes en opengl ?

              un Moteur 3D, c'est peut-etre surtout definir une maniere de stocker tes "mondes" et de les rendre dans un moteur opengl.

              opengl se chargant alors de faire les operations de rendu (backface culling, clipping, puis eclairage)

              • [^] # Re: Qu'est-ce que c'est?

                Posté par . Évalué à 2.

                De mémoire, pour ne pas faire écrouler les perfs, en temps réel les cartes graphiques gèrent un nombre fixe de triangles, genre 150k.

                Pour augmenter le réalisme, le logiciel sur cpu créait une sorte de bas relief qui est rendu par la carte, cela permet de faire des choses bien plus complexe.

                "La première sécurité est la liberté"

  • # Projet "économiseurs d'écran" en Java

    Posté par . Évalué à 2.

    Tant que j'y suis je redonne l'url de mon autre projet:

    A la base les 2 projets étaient identiques. L'original est en Java.

    http://artofpixel.svn.sourceforge.net/viewvc/pixelart/Images/src/

    Bien que l'url soit toujours "pixelart" je l'ai rebaptisé en "pixeldemos", il a pour but de faire des animations graphiques vidéos. La dernière est une spirale psychédélique (à consommer sans modération).

    Le projet est en soi un peu trivial: une classe encapsule un contexte Graphics qui permet de dessiner sur les images...

    http://www.youtube.com/watch?v=r6z2A6zNbUo

    Voilou.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.