Comment puis-je plier un objet dans OpenGL?

11

Existe-t-il un moyen de plier un objet, comme un cylindre ou un avion en utilisant OpenGL?

Je suis un débutant OpenGL (j'utilise OpenGL ES 2.0, si cela importe, bien que je soupçonne que les mathématiques comptent le plus dans ce cas, donc c'est en quelque sorte indépendant de la version), je comprends les bases: traduire, faire pivoter, les transformations matricielles, etc. Je me demandais s'il existe une technique qui vous permette de modifier réellement la géométrie de vos objets (en l'occurrence en les pliant)?

Tous les liens, tutoriels ou autres références sont les bienvenus!

Valentin Radu
la source

Réponses:

11

Ce que vous devez faire pour "plier" un objet est d'appliquer une combinaison appropriée de translation / rotation / mise à l'échelle à seulement un sous-ensemble des sommets de l'objet en question - pondérant probablement cette transformation en conséquence.

Faire ceci est une mode agréable qui nécessitera d'utiliser plus de sommets que cela ne serait autrement strictement nécessaire pour décrire le maillage d'origine. Par exemple, un simple cylindre peut n'avoir que des sommets à chaque extrémité, mais si vous souhaitez que ce cylindre se plie au milieu, vous aurez également besoin de sommets.

Si tout ce qui vous intéresse est des déformations ponctuelles très spécifiques de formes très simples (comme votre avion susmentionné), vous pouvez probablement le faire manuellement. Par exemple, décidez de l '"axe de pliage" de votre plan et calculez les transformations appropriées pour chaque rangée de sommets du plan pour obtenir la rotation appropriée autour de cet axe de pliage en fonction de leur distance par rapport à celui-ci, puis appliquez-la à la géométrie (éventuellement sur le CPU car ce serait le plus simple, au moins au début). Mais une telle technique n'évoluerait pas bien et serait très fastidieuse.

Puisqu'il peut être si lourd de comprendre correctement comment pondérer une transformation à chaque sommet individuel dans un ensemble pour obtenir la déformation souhaitée (en particulier pour les objets plus pratiques et compliqués), de nombreux jeux utilisent une technique appelée animation squelettique . À un niveau élevé, cela implique d'associer un ensemble distinct de géométrie (le «squelette») à votre maillage. Cette géométrie représente les os de votre objet et vous définissez (souvent dans les outils de modélisation) une correspondance entre les sommets du modèle réel et les os du squelette - quels os sont associés à chaque sommet et dans quelle mesure cet os affecte la déformation de ce sommet. Ensuite, le squelette est animé directement et l'animation est transférée au modèle réel via la relation entre les os et leurs sommets.

Généralement, dans cette technique, la correspondance entre le squelette et le maillage réel est définie au moment de la production des actifs. Les animations peuvent également être créées à ce moment-là, ou elles peuvent être construites de manière procédurale lors de l'exécution. L'application des transformations d'animation au maillage réel se produit lors de l'exécution. Généralement, aucun nouveau sommet n'est généré au moment de l'exécution, ce qui signifie que la plage de déformations attrayantes est implicitement fixée dans le maillage lors de sa création d'origine.

En théorie, on pourrait également appliquer une tessellation et une subdivision au maillage lors de l'exécution en fonction de l'analyse des transformations de l'animation, et ainsi produire les sommets appropriés pour créer une animation qui n'était pas nécessairement prévue. Je ne suis au courant, par hasard, d'aucun article sur ce sujet.

Voir également:

Vaillancourt
la source
9

Pour le calcul réel de la déformation, cela peut devenir très compliqué, pourquoi ne commencez- vous pas ici? .

Je vais maintenant parler de la façon dont vous pouvez appliquer cela, en supposant que vous avez déjà les calculs nécessaires pour réduire vos déformations.

2 façons:

1) Chaque cadre, visitez chaque sommet du modèle de cylindre et décalez-le d'une manière ou d'une autre.

2) Décalez les sommets dans le vertex shader lors du rendu. OpenGL ES 2.0 prend en charge les vertex shaders. Vous avez donc de la chance, en quelque sorte.

Voulez-vous déformer uniquement l'objet tel qu'il apparaît à l'écran , ou voulez-vous déformer l'objet de sorte que chaque objet du jeu sache qu'il a été déformé?

Si vous déformez l'objet dans le vertex shader, cela ne se produit qu'immédiatement avant l'affichage / la pixellisation , donc cela signifie qu'aucun des objets du jeu ne connaîtra la déformation . C'est très bien si vous faites simplement un économiseur d'écran, ou si les déformations sont si petites qu'elles n'ont aucun impact sur la forme collidable de l'objet.

Lorsque vous déformez la géométrie dans le vertex shader, les sommets d'origine du modèle ne bougent pas (ils semblent se déplacer uniquement ).

Déformation dans le vertex shader

Non déformé:

non déformé

Déformé

déformé

Ceci est du chapitre 6 du tutoriel cg , (programme # 14).

Le code shader pour produire cette déformation est quelque chose comme

// choose a displacement amount
float displacement = scaleFactor * 0.5 * sin(position.y * frequency * time) + 1 ;

// displace it in the direction of the normal
float4 displacementDirection = float4(normal.x, normal.y, normal.z, 0) ;

// move the vertex
float4 newPosition = position + displacement * displacementDirection ;

// transform (as normal)
oPosition = mul(modelViewProj, newPosition) ;

Comme vous pouvez le voir, cela se produit juste avant l'affichage (le vertex shader se produit sur le GPU), donc le code CPU n'a pratiquement aucun moyen d'accéder à la position du vertex transformé (il existe des moyens d'envoyer des données du GPU au CPU (principalement via des textures) mais nous n'y ira pas).

bobobobo
la source
8

Ce que vous essayez de réaliser est essentiellement un sous-ensemble du sujet de la déformation du maillage. Mais comme vous êtes débutant, je crains que ce type d'informations ne soit un peu trop étrange pour le moment. Je vais cependant essayer de définir les notions de base.

Pour ce faire, vous aurez besoin de deux choses:

  1. Votre maillage doit avoir suffisamment de sommets pour que vous puissiez vous transformer. Par exemple, s'il s'agit d'un plan, vous devrez vous assurer qu'il est bien créé comme une sorte de grille, avec de nombreux sommets à déformer. Même chose avec un cylindre. Cela pourrait être possible à l'exécution avec la tessellation mais je ne sais pas grand-chose sur le sujet.
  2. Vous devez utiliser un vertex shader pour déformer les sommets. Fondamentalement, le vertex shader se charge de calculer la position finale transformée de chaque sommet, vous pouvez donc profiter de la possibilité de leur appliquer des déformations.

Je ne sais pas à quel point cela sera utile, mais jetez un œil à cette ressource OpenGL, car elle semble être le type de chose dont vous avez besoin:

http://www.ozone3d.net/tutorials/mesh_deformer_p3.php#part_3

Capture d'écran de ce lien:

entrez la description de l'image ici

Éditer

Je viens de voir la réponse de Josh et je suis d'accord, l'animation squelettique est également un moyen très élégant pour résumer ce problème, surtout lorsque vos déformations commencent à devenir plus complexes et plus difficiles à représenter mathématiquement.

Mais rappelez-vous que les deux points ci-dessus s'appliquent toujours - vous ne pouvez déformer que les sommets, donc ils doivent évidemment exister en premier lieu, c'est pourquoi votre maillage doit avoir une quantité décente de densité de sommets. Et c'est généralement le vertex shader qui anime l'animation squelettique et fait le mélange des vertex et autres.

Et en passant, vous pouvez également les faire sur le CPU, mais de nos jours, c'est généralement une meilleure option pour les faire sur le GPU, c'est pourquoi je mets l'accent sur le vertex shader, et vous devriez le regarder. Ce n'est pas vraiment beaucoup plus difficile au niveau du programme que de le faire sur le CPU de toute façon.

David Gouveia
la source