Pixels de retrait de texture

Présentation du quatrième article de notre série sur l'utilisation des modèles 3D dans Unity. Articles précédents: "Fonctionnalités du travail avec Mesh dans Unity" , "Unity: édition procédurale de Mesh" , "Importation de modèles 3D dans Unity et pièges" .

Dans l'article précédent, nous avons mentionné la vérification du balayage de texture pour l'adéquation de l'indentation des pixels à une résolution de texture donnée. Dans cette publication, nous décrivons l'essence du problème de l'observation de l'indentation des pixels et l'algorithme de suivi. Il ne sera pas considéré comme le code, mais précisément comme le principe qui peut être implémenté dans n'importe quel langage et dans n'importe quel environnement de développement.



Problème


Une commande de modèle 3D est généralement accompagnée d'une exigence de résolution de texture. En raison de la nature discrète de l'image raster, l'artiste 3D doit observer l'indentation en pixels entre les parties du scan de texture. L'absence de l'indentation nécessaire conduit au fait que le même pixel est affiché sur le modèle à des endroits complètement différents lorsqu'il n'est pas nécessaire.

Il est particulièrement important de suivre une indentation suffisante dans les premières étapes du travail. Le plus souvent, certaines personnes sont impliquées dans la création de géométrie, y compris un scan de texture, et d'autres dans le dessin de textures. L'erreur détectée par l'artiste 3D causera moins de problèmes que celle que le concepteur de textures trouvera. Dans ce dernier cas, la situation devient encore plus compliquée si le package 3D utilisé ne fournit pas d'outils pour dessiner sur la géométrie (par exemple, un pinceau).

Vous devriez également considérer deux nuances, car entre les éléments du balayage, cela peut nécessiter plus d'espace. Le premier est une diminution de la résolution de texture pendant le mipmapping. La seconde est l'utilisation d'un filtre de dilatation lors de la formation d' une carte d'éclairage . Au cours de la tâche de création d'un scan UV , un artiste 3D doit être guidé par les exigences de résolution de texture et également prendre en compte les nuances énumérées ci-dessus. Néanmoins, de nombreuses lacunes ne peuvent tout simplement pas être détectées sans vérification automatisée.


Un exemple de l'apparition d'artefacts avec une diminution des détails

Pour les modèles simples, une analyse de texture peut être générée à l'aide d'outils automatiques. Cependant, ils sont basés sur des métriques internes et ne prennent pas en compte l'indentation des pixels, de sorte que les pixels partagés sont souvent situés le long des bordures diagonales. La vérification avec les textures du vérificateur n'affiche pas toutes les erreurs, de plus, ces textures ont souvent une résolution plus élevée que celles qui seront utilisées dans le projet.


Pixels partagés

Le problème de l'indentation insuffisante des pixels dans le scan UV est similaire au problème des superpositions. Dans les deux cas, le soi-disant saignement peut se produire - dans l' article précédent, nous avons décrit les artefacts que cela génère.

Cependant, le problème d'indentation des pixels dépend de l'exigence de résolution de texture minimale. Une seule vérification suffit pour déterminer les superpositions, tandis que les exigences de résolution de texture peuvent changer à l'étape suivante du développement. La situation est compliquée par le fait que les packages 3D que nous utilisons ne disposent pas d'outils pour détecter automatiquement les erreurs liées à la proximité de parties du scan UV . Et n'oubliez pas qu'après le fonctionnement du shaper automatique dans Unity, vous devez toujours vérifier UV2 .

Nous avons décidé de créer un outil qui peut vérifier l'indentation en pixels et marquer les emplacements des lacunes potentielles dans le modèle. Les exigences d'indentation seront déterminées en fonction des paramètres suivants:

  1. La résolution de base de la texture.
  2. Résolution minimale de la texture à laquelle l'écoulement n'est pas autorisé.
  3. L'indentation requise sur la texture minimale.

Étant donné que les tailles des textures que nous utilisons sont égales à deux degrés, la formule de calcul de l'indentation nécessaire à la résolution de base est assez simple: (résolution de base / résolution minimale) * retrait sur la MinTexture.

De toute évidence, la solution à ce problème est étroitement liée à la pixellisation. Pour un énoncé plus clair des exigences et le développement d'un algorithme, nous introduisons plusieurs concepts.

Concepts clés


Considérons un espace UV et une grille uniforme de dimension NxM dans la plage de 0,0 à 1,0. Les cellules 1 / N de largeur et 1 / M de hauteur forment une partition de l' espace UV .


NxM divisant l' espace UV

Nous prenons deux points arbitraires et notons Dn le nombre de pixels occupés par la projection sur l'axe U du segment reliant les points donnés. De même, Dm pour l'axe V. Ensuite, nous définissons la distance en pixels comme le maximum entre Dn et Dm.


Distance en pixels

Il convient de noter que dans l'espace euclidien, des opérations de mouvement telles que la translation parallèle et la rotation ne sont pas des mouvements pour le maillage, si la distance en pixels est prise comme métrique. Cette nuance a un peu compliqué le développement de notre solution.



Nous appelons un carré avec un côté en K pixels le noyau de K. Ensuite, deux points quelconques avec une distance en pixels inférieure à K peuvent être couverts par un noyau de K.


Exemples de noyaux de différentes tailles

Deux arêtes du polygone forment une concavité du contour si leur point médian (le centre de masse à quatre sommets) se trouve à gauche de ces arêtes lorsque vous contournez le contour dans le sens horaire. Pour une traversée dans le sens antihoraire, la condition est de trouver un point à droite des bords.


Une paire de nervures formant une concavité du contour

Solution


Parlons maintenant directement de la vérification de l'indentation des pixels. Pour l'implémenter, nous avons trouvé un algorithme composé de trois fragments indépendants. L'ordre d'exécution n'est pas important. Le résultat de chacun des fragments est la matrice NxM, qui est un tampon des cellules de la partition, où certaines cellules sont marquées. L'ajout des trois tampons est le résultat général.

Tout d'abord, considérez l'extrait le plus simple. Il s'agit de trouver des cellules qui se croisent près de triangles et de bords dégénérés, dont la longueur est inférieure au côté du noyau d'une magnitude donnée. Toutes ces cellules sont marquées dans le tampon.


Résultat de la vérification de la taille des éléments

Avant de décrire les deux autres fragments, réfléchissez à la logique générale de leur travail. Les deux sont liés au traitement de grappes de triangles appelés coquilles ou îles. Shell pour un artiste 3D est un ensemble de polygones connectés, c'est-à-dire que chaque polygone de cet ensemble a un voisin avec lequel il partage des sommets communs. Shell est également un terrain d'entraînement indépendant. De plus, par coquille, île et grappe, nous entendons la même chose.



Pour trouver tous les coques, nous utilisons l'algorithme de recherche pour toutes les composantes connectées du graphique, où le sommet du graphique est représenté par un polygone et le bord par la présence de sommets communs dans une paire de polygones. Puisque le seul polygone dans Unity est un triangle défini par des indices de sommet, nous considérons que les triangles sont adjacents si au moins un indice du sommet du premier coïncide avec l'indice de tout sommet du second. De l'analogie avec le graphique et la méthode de détermination des arêtes, il s'ensuit que l'ensemble des indices des sommets d'un cluster ne coupe pas l'ensemble des sommets de l'autre.



Avec la partie commune terminée. Le deuxième fragment, que nous considérerons, détermine les emplacements des erreurs potentielles associées à la proximité ou au chevauchement de différents clusters.

De nombreux clusters sont alimentés à l'entrée sous la forme d'ensembles de triangles dans l'espace UV , la dimension de la division UV correspondant à la résolution de la texture (NxM), et la valeur d'indentation P comme le nombre de pixels. Pour une partition donnée, il est nécessaire de trouver les zones dans lesquelles la distance en pixels entre les clusters est inférieure au retrait requis. Une cellule de la matrice de résultat est marquée si elle entre dans au moins un noyau de la valeur K = P + 1 , qui coupe deux grappes différentes.

L'essence du fragment est presque exposée dans la description du résultat. Il est nécessaire de trouver tous les noyaux de magnitude K qui se croisent avec des triangles de coquilles différentes, puis de marquer les cellules de ces noyaux dans le tampon de résultat.

Dans notre implémentation, toutes les paires de clusters sont considérées à tour de rôle. Pour chaque paire, la région d'intersection des ensembles de noyaux de grandeur K couverts par ces grappes est déterminée. Choisissez une paire et dénotez un tel ensemble comme Q.



Ensuite, tous les éléments de Q doivent être vérifiés par le critère suivant: le noyau donné coupe-t-il au moins un triangle dans chacun des clusters de la paire sélectionnée. Si c'est le cas, alors toutes les cellules du noyau testé sont marquées.



Le tampon avec des cellules marquées pour toutes les paires de grappes constitue le résultat.


Résultat d'indentation de cluster

Nous allons maintenant traiter du dernier fragment. Ici, vous devez traiter un cluster. L'entrée est un ensemble de triangles dans l'espace UV , la dimension de la partition UV correspondant à la résolution de la texture (NxM) et la valeur d'indentation P en nombre de pixels. Une cellule peut être marquée dans deux cas: soit le cluster n'est pas valide ou a des trous, soit la distance en pixels entre les bords de concavité est inférieure au retrait requis.

La partie interne du cluster ne nous intéresse pas - pour commencer, nous obtiendrons son contour représenté par une liste connectée d'arêtes. Les triangles voisins dupliquent les indices des sommets, donc l'arête appartient au contour si une paire d'indices de ses sommets est unique pour l'ensemble des arêtes du cluster. Après avoir déterminé les bords qui forment le contour, il est nécessaire de les composer pour obtenir une liste chaînée.

Si après cette étape, tous les bords du contour n'entrent pas dans la liste, alors soit le cluster a des trous, soit il y a une erreur dans les données de maillage. Dans ce cas, il est nécessaire de marquer de manière appropriée toutes les cellules des noyaux coupés par l'amas.

Si le contour est trouvé, le traitement se poursuit. Nous avons formulé l'exigence de résultat suivante. Soit la paire d'arêtes formant la concavité du contour coupant le noyau de K = P + 1 . Ensuite, les cellules du noyau doivent être marquées si les deux parties du contour entre les bords dépassent ce noyau.


Résultat du test de fonctionnalité de cluster

Nous avons décidé de mettre en œuvre cette exigence en comparant par paire les bords du contour. Nous commençons par la condition de concavité, puis pour chaque paire tous les noyaux qui coupent les deux bords sont vérifiés. Pour tester le noyau, des traversées de chaque partie du contour entre une paire d'arêtes sont effectuées. Si chaque partie contient au moins un point au-delà des limites du noyau, alors toutes les cellules du noyau sont marquées.


La condition dans laquelle les cellules du noyau vérifié sont marquées

Résumé


L'algorithme ci-dessus est très approprié pour une implémentation utilisant le calcul parallèle. Le traitement de chaque paire de grappes et de bords se produit indépendamment. Étant donné que les vérifications sont basées sur la pixellisation, si vous commencez à traiter non pas avec des paires d'arêtes, mais avec des cœurs, il est conseillé d'utiliser les capacités du GPU .

Nous transformons le résultat de l'algorithme en texture. Pour une résolution donnée, cela vous permet de représenter graphiquement les emplacements des défauts potentiels dans le scan UV . De plus, la texture résultante peut être appliquée au modèle pour voir les marques directement sur la géométrie.

Dans les exemples ci-dessous, nous avons spécialement coupé le lapin et Suzanne avec l'outil automatique Blender afin d'obtenir plus d'artefacts. La résolution de texture vérifiée est 256x256, l'indentation requise est 1.

Les cellules marquées en bleu couvrent des grappes avec des trous, ainsi que des triangles et des bords trop petits. Le vert indique les noyaux cellulaires avec les caractéristiques de chaque cluster individuellement. Les grains dans lesquels le retrait entre les grappes n'est pas observé sont marqués en rouge.

Des exemples




Dans le prochain article, nous considérerons un algorithme pour optimiser les modèles 3D dans une scène en supprimant la géométrie invisible. Reste avec nous!

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


All Articles