Nous compliquons les modèles de science-fiction sur le plan de la procédure: qu'est-ce que Greeble et comment l'utiliser

image

Pour commencer, permettez-moi de me plaindre que «greeble» est un mot terrible à bannir du dictionnaire.

Eh bien, retirant la pierre de l'âme, nous nous tournons vers les explications. Greeble sont de petits détails répétitifs ajoutés à un modèle pour lui donner un sens de l'échelle et une certaine esthétique. Les champignons sont devenus populaires grâce aux films de science-fiction classiques, dans lesquels la sculpture physique était souvent le «modèle»:


Si vous savez déjà grâce à mon tutoriel d'extrusion comment extruder des maillages procéduraux, vous comprenez comment ajouter des champignons. L'ajout de champignons simples au maillage peut être accompli en extrudant tous les polygones du maillage à une longueur aléatoire .

Cependant, vous avez peut-être remarqué que le didacticiel ci-dessus ne concerne que l'extrusion de triangles, tandis que l'image au début de l'article est des champignons carrés. J'ai dû ajuster le maillage pour qu'il soit divisé en quadrangles, et de nombreux maillages sont souvent constitués de polygones avec plus de trois indices. Par conséquent, dans ce tutoriel, nous allons apprendre à extruder un polygone avec n indices et appliquer cet algorithme à l'ensemble du maillage pour créer des champignons. Nous apprenons également quelques façons de faire des variations dans l'algorithme de prolifération pour obtenir des résultats moins uniformes.

Surface normale


Tout d'abord, découvrons comment la normale d'un polygone avec n indices arbitraires est calculée. Si nous pouvons supposer que ce polygone est plan , c'est-à-dire que tous ses sommets sont sur le même plan, alors le processus ne diffère pas du calcul de la normale d'un polygone à trois indices.

La surface normale est la perpendiculaire à la face du polygone, qui peut être calculée en prenant le produit vectoriel de deux vecteurs pointant le long du bord du polygone .

Ensuite, nous normalisons ce vecteur pour que sa longueur soit 1, car de la normale à la surface, nous n'avons besoin que de direction, pas de longueur.

  fonction getFaceNormal (mesh, poly)
   Vec3 v1 = maillage: getVertex (poly [1])
   Vec3 v2 = maillage: getVertex (poly [2])
   Vec3 v3 = maillage: getVertex (poly [3])
   Vec3 e1 = v2 - v1
   Vec3 e2 = v3 - v2
   Vec3 normal = e1: croix (e2)
   return normal: normalize ()
 fin 

Si nous ne pouvons pas supposer avec certitude que le polygone est plan, alors l'algorithme présenté ci-dessus préfère le plan sur lequel les deux premiers indices sont situés. Pour une représentation plus précise de la direction dans laquelle le polygone pointe, nous pouvons plutôt prendre la moyenne de tous les produits vectoriels des arêtes :

  fonction getFaceNormal (mesh, poly)
   Vec3 n = Vec3 (0, 0, 0)
   pour i = 1, #poly -2 do
     Vec3 v1 = maillage: getVertex (poly [1])
     Vec3 v2 = maillage: getVertex (poly [1+ i])
     Vec3 v3 = maillage: getVertex (poly [2+ i])
     n: ajouter ((v2 - v1): croix (v3 - v1))
   fin
   return n: normalize ()
 fin 


Un exemple montrant l'extrusion d'un quadrilatère plan.

Extrusion


Maintenant que nous avons des informations sur la surface normale, nous sommes prêts à extruder le polygone dans la direction normale. Autrement dit, pour extruder le polygone, nous créons de nouveaux sommets en déplaçant les anciens sommets dans la direction de la surface normale.

Plus de détails:

  1. Créez de nouveaux pics «au-dessus» des anciens dans la direction normale.

    Les nouveaux sommets peuvent être calculés comme suit:

      (position de l'ancien pic) + (direction normale) 

    Cela «déplace» l'ancienne position dans la direction de la normale de surface.

    Par exemple, regardez l'image ci-dessus, sur elle v1 se déplace dans la direction normale vers v5.
  2. Créez des quadrangles pour connecter les nouveaux et anciens sommets.

    Il est à noter que pour chaque indice du nouveau polygone, un nouveau quadrilatère est créé.

    Par exemple, jetez un œil à un quad créé à partir de v8, v7, v3 et v4 .
  3. Remplacez l'ancien polygone par un nouveau polygone créé par de nouveaux sommets. Par exemple, jetez un œil à un quad créé à partir de v5, v6, v7 et v8.


  fonction extrudePoly (maillage, polyIndex, longueur)
   int [] poly = mesh.polys [polyIndex]
   int [] newPoly = []
   Vec3 n = getFaceNormal (maillage, poly)

   - (1) Créer des verts extrudés
   pour j = 1, #poly do
     p = maillage local: getVertex (poly [j])
     newPoly [#newPoly + 1] = # mesh.verts
     - la longueur détermine la longueur de l'extrusion
     maillage: addVertex (p + (n * longueur))
   fin

   - (2) Points d'extrusion de points avec quadruples
   pour j0 = 1, #poly do
     local j1 = j0% #poly + 1
     mesh: addQuad (
       poly [j0],
       poly [j1],
       newPoly [j1],
       newPoly [j0]
     )
   fin

   - (3) Déplacer la face existante vers des sommets extrudés
   pour j = 1, #poly do
     mesh.polys [pi] [j] = newPoly [j]
   fin
 fin 


Champignon uniforme.

Champignon tout en maille


Maintenant que nous avons la fonction getSurfaceNormal () et la fonction extrude (), la prolifération est très facile! Nous appliquons simplement la fonction extrude () à chaque polygone de maillage . Nous utilisons l'extrusion avec une longueur aléatoire afin que chaque polygone extrudé ait une taille légèrement différente, ce qui crée une sensation de texture. L'algorithme présenté ci-dessous est appliqué au cube présenté ci-dessus, qui se compose entièrement de quadrangles.

  fonction greeble (mesh)
   pour i = 1, # mesh.polys do
     - ces valeurs aléatoires sont arbitraires: p
     float length = random: getUniformRange (0.1, 1.0)
     extrudePoly (maille, i, longueur)
   fin
   maillage de retour
 fin 

Félicitations, notre prolifération a gagné. Mais nous pouvons faire plus! Maintenant, la prolifération est assez uniforme. Voici deux exemples de modifications pour le rendre plus intéressant.


Modification 1: la présence de fungling dépend du hasard


C'est assez simple: il suffit de lancer le dé pour déterminer si la prolifération doit être appliquée à chaque polygone. Grâce à cela, la prolifération devient moins uniforme. L'algorithme illustré ci-dessous est appliqué au cube ci-dessus.

  pour i = 1, # mesh.polys do
    <strong> si aléatoire: chance (0,33) puis </strong>
      longueur flottante = aléatoire (0,1, 1,0)
      extrudePoly (maille, i, longueur)
    fin
  fin
  maillage de retour
 fin 


Modification 2: Ajouter une échelle d'extrusion


Cela nécessite de modifier l'algorithme d'extrusion. Lorsque nous créons les sommets d'un polygone extrudé, nous pouvons les réduire vers le centre du polygone d'une quantité aléatoire pour rendre l'objet plus intéressant.

Pour commencer, notre fonction extrude () doit recevoir un paramètre supplémentaire qui détermine le degré de rétrécissement du nouveau polygone. Nous allons le définir comme Vec3 appelé scale . Pour déplacer un sommet vers le centre, nous interpolons la position du sommet entre sa position d'origine et le centre du polygone par la valeur d' scale .

(Si vous avez besoin de connaître l'algorithme pour trouver le centre d'un polygone, je vous recommande de passer rapidement au didacticiel sur la triangulation et de lire la triangulation centroïde.)

  - trouver le centre du poly
 Vec3 c = maillage: getFaceCentroid (poly)
 pour j = 1, #poly do
   p = maillage local: getVertex (poly [j])
   newPoly [#newPoly + 1] = # mesh.verts
   self: addVertex (
     math.lerp (cx, px, scale.x) + nx * longueur,
     math.lerp (cy, py, scale.y) + ny * longueur,
     math.lerp (cz, pz, scale.z) + nz * longueur
   )
   maillage: addVertex (p + (n * longueur))
 fin 

Vous pouvez maintenant l'utiliser dans l'algorithme de prolifération en mettant à l'échelle une valeur aléatoire pour chaque polygone. Nous obtenons donc l'image ci-dessus.

  fonction greeble (mesh)
   pour i = 1, # mesh.polys do
     float length = random: getUniformRange (0.1, 1.0)
     Échelle Vec3 = (aléatoire: getUniformRange (0,1, 1,0),
                   random: getUniformRange (0.1, 1.0),
                   random: getUniformRange (0.1, 1.0))
     extrudePoly (maillage, i, longueur, échelle)
   fin
   maillage de retour
 fin 

La fin


Super, nous sommes arrivés à la fin! J'espère que ce tutoriel vous a été utile.

Source: https://habr.com/ru/post/fr482316/


All Articles