Il s'agit du troisiè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» et «Unity: édition procédurale de Mesh» .Dans le monde de l'infographie, il existe de nombreux formats pour présenter des modèles 3D. Certains d'entre eux sont positionnés comme universels, d'autres comme optimisés pour des tâches ou des plates-formes spécifiques. Dans tous les domaines, ils rêvent de travailler avec un format universel, mais la réalité nous dit non. De plus, un tel zoo fait un cercle vicieux: les développeurs d'outils «universels» inventent leurs propres formats internes pour résumer les précédents, augmentant la population et créant des moyens pour convertir les formats. Il y a donc un problème de perte ou de distorsion des données lors de la conversion. Le problème est aussi ancien que le monde (monde informatique, bien sûr), et il n'a pas contourné l'importation de modèles dans
Unity .
Dans cet article, nous parlerons de certaines des difficultés auxquelles nous devons faire face lorsque nous travaillons avec des modèles dans
Unity (en particulier le fonctionnement de
ModelImporter , la différence dans les représentations des objets 3D, etc.), ainsi que des outils que nous avons créés pour surmonter ces difficultés.

Caractéristiques de ModelImporter
Rappelons que pour
l'API de la carte graphique
, la primitive minimale et uniquement tridimensionnelle est un triangle, tandis que la géométrie en
FBX , par exemple, peut être représentée comme des quadrangles. Les packages 3D modernes pour la création de modèles, en règle générale, permettent différents niveaux d'abstraction, mais même là, le rendu du résultat se produit à travers des triangles.
Dans le même temps, de nombreux outils sont conçus pour travailler avec des quadrangles, ce qui encourage les artistes 3D à utiliser cette primitive comme principale. Dans de tels cas, les savoirs traditionnels nécessitent souvent de trianguler le modèle avant la mise en œuvre. Si la triangulation n'est pas effectuée, le module
Unity correspondant en mode standard l'exécute automatiquement lorsqu'un fichier est ajouté. De ce fait, des erreurs apparaissent, car les algorithmes de triangulation sont implémentés différemment dans différents packages. Lorsque vous choisissez une diagonale pour diviser un quadrilatère, une ambiguïté apparaît, d'où la plupart des problèmes qui peuvent être divisés en deux groupes.
Le premier est lié à l'exactitude de l'affichage du formulaire modèle. Ainsi, la forme d'un quadrilatère non plan dépend directement du choix de la diagonale.
Susanna triangulée dans Blender (Méthode Quad: Beauté) et Unity (automatiquement lors de l'importation)De plus, l'algorithme de cuisson de carte normal utilise des données de partition, grâce auxquelles la différence de triangulation peut donner lieu à des artefacts sous la forme d'une croix sur un éblouissement.
Scooter homme sain et scooter fumeurLes problèmes du deuxième groupe se rencontrent dans le scan de texture. Par exemple, nous avons un quadrilatère avec un angle suffisamment obtus pour qu'une erreur se produise. Lorsqu'il est prévisualisé dans un package 3D, il est divisé par l'une des diagonales en deux triangles complètement repliables.
Polygone source
Polygone triangulé dans BlenderCependant, après l'importation dans le projet, on découvre que ce quadrilatère est rompu par une autre diagonale et que l'un des triangles est généralement dégénéré ou proche de celui-ci.
Un polygone dans Unity avec un triangle proche d'un dégénéré (le triangle de droite est presque impossible à distinguer d'un segment)
La raison des problèmes associés à la dégénérescence des polygones est les erreurs dans les calculs en virgule flottante, ainsi que les particularités de l'interpolation des pixels lors du rendu. Qu'est-ce qui se passe avec ces triangles: ils se contractent, chaque image change de couleur. La dimension transversale extrêmement petite crée des difficultés dans le traitement de la lumière, c'est pourquoi des parties d'objets dynamiques peuvent scintiller. Et dans le non-déterminisme de la cuisson de la
carte d'éclairage, il n'y a rien de bon non plus.
Je suis un package 3D, tel que je le vois

Dans la modélisation 3D, il existe souvent une différence entre le nombre réel de sommets et leur nombre dans un package 3D. L'essence du problème réside dans les informations nécessaires au traitement par la carte vidéo. La structure de données pour le sommet est prédéfinie et comprend la position, la normale, la tangente, les coordonnées de balayage de texture pour chaque canal et couleur. Autrement dit, deux normales ne peuvent pas être poussées dans un sommet.
Pour certains artistes, il n'est pas toujours évident que le pic soit déterminé non seulement par sa position. Les modélisateurs connaissent bien les concepts de
bords durs / mous et de
coutures UV , mais tout le monde ne comprend pas comment ils sont mis en œuvre par programme. De plus, les paquets 3D prêtent à confusion, qui en mode standard affichent le nombre de sommets comme le nombre de positions uniques.
Ainsi, la primitive
Cube habituelle est représentée géométriquement par 8 sommets. Cependant, afin de transmettre correctement la réflexion de la lumière de chaque face et d'appliquer correctement la texture, dans chaque coin du cube, 3 sommets avec la même position, mais des normales et des coordonnées de texture différentes sont nécessaires, car 3 bords convergent dans chaque coin. Un petit
bloc de documentation a été consacré à ce moment. Vous pouvez y voir des exemples.
Mesures du cube du mélangeur
Mesures du cube UnityArrête ça!
Face à ces problèmes et à des problèmes similaires, nous avons décidé de créer un outil d'analyse et de validation de modèle lors de l'importation dans un projet
Unity . En d'autres termes, un validateur personnalisé, qui à la demande "Eat!" réponse: «Je ne le ferai pas! Refaire », - ou cracher des ensembles d'avertissements et de valeurs de divers paramètres, notifiant que quelque chose n'est pas bon pour lui.
Pour l'analyse et la vérification, nous avons développé les fonctionnalités suivantes:
- compter le nombre de positions uniques de sommets, sommets colorés, bords durs , coutures UV ;
- Calcul de la zone de délimitation alignée sur l' axe (AABB) et de son centre;
- détermination de la sortie des coordonnées du scan UV au-delà de la plage 0,0–1,0;
- définition de superposition de texture;
- vérifier le balayage de texture pour l'adéquation de l'indentation de pixel spécifiée pour une résolution de texture donnée.
Qu'est-ce que cela nous donne?
Le comptage du nombre de positions de sommets uniques, de bords durs, de coutures UV et
de sommets colorés est nécessaire pour vérifier que le modèle de l'artiste a été importé dans
Unity . Cette fonctionnalité vous permet également de contrôler la conformité aux exigences d'optimisation du modèle (par exemple, afin que le nombre de sommets ne dépasse pas une certaine valeur). En raison de la même particularité des packages 3D, qui affichent en fait le nombre de positions uniques, il y a des cas où la métrique du nombre de sommets dans l'éditeur de modèle satisfait cette restriction, mais après avoir ajouté le fichier au projet, il peut s'avérer que ce n'est pas le cas.
Calcul de l'AABB et de son centre - vous permet de déterminer le déplacement du modèle par rapport au début de son propre système de coordonnées. Cela est nécessaire pour le positionnement prévisible des actifs qui sont initialisés dans la scène pendant l'exécution de l'application. Ainsi, l'
AABB du bâtiment devrait avoir minY = 0 et un lustre attaché au plafond - maxY = 0.


Quittez les coordonnées des sommets du scan UV pour la plage 0,0–1,0 - dans la plupart des cas (par exemple, si la texture doit être carrelée sur le modèle) est fournie. Cette approche est souvent utilisée pour représenter dans la scène une multitude de petits objets peu détaillés (végétation) et / ou situés au loin, ainsi que du carrelage de grands objets homogènes (bâtiments). Dans le cas de la mosaïque, les valeurs de coordonnées d'un canal
UV spécifique sont simplement coupées de la partie entière au niveau du shader, si le
mode Wrap de la texture est défini sur
Répéter .
Imaginez maintenant que vous avez posé la texture dans un satin (et recouvert d'une couverture: 3). Les coordonnées déjà converties correspondant à l'atlas (échelle x * + décalage) arriveront au shader. Cette fois, très probablement, il n'y aura pas de partie entière et il n'y aura rien à recadrer, et le modèle grimpera sur la texture de quelqu'un d'autre (la couverture s'est avérée petite). Ce problème est résolu de deux manières.
Le premier suppose que vous coupez à l'avance la partie entière aux coordonnées de balayage. Dans ce cas, il existe un risque de chevauchement de polygones, dont nous parlerons ci-dessous.
La seconde est basée sur le fait que le carrelage de texture est intrinsèquement une méthode d'optimisation. Personne ne vous interdit d'augmenter la taille et d'échantillonner la pièce souhaitée pour l'ensemble du modèle. Cependant, de cette manière, l'espace utilisable de l'atlas sera utilisé de manière inefficace.
Les superpositions dans un scan de texture ne sont souvent pas aléatoires: elles sont nécessaires pour utiliser efficacement les zones de texture. Il arrive qu'un novice se trompe, un camarade senior le voit, prononce un mot fort, et un novice ne fait plus ça. Mais il arrive que la superposition soit si petite et située dans un endroit si inattendu que le camarade senior ne le remarque pas.
Dans l'équipe expérimentale, les erreurs non détectées lors du scan de base pénètrent un peu plus souvent que jamais dans le projet. Une autre chose est lorsque les conditions d'utilisation du contenu prêt à l'emploi changent.
Un exemple. Nous avons travaillé avec un ensemble de modèles d'objets dynamiques dans le jeu. Puisqu'il n'y avait aucun problème à cuire la lumière pour eux, des superpositions étaient autorisées dans le scan
UV .
Un exemple d'un scan UV de base avec des superpositions (montré en rouge)Cependant, nous avons décidé de ne pas utiliser ces modèles comme des modèles dynamiques, mais de les placer comme décor statique à un niveau. Pour l'optimisation, comme vous le savez, l'éclairage des objets statiques dans une scène est cuit dans un atlas spécial. Ces modèles n'avaient pas de canal
UV2 séparé pour la
carte d'éclairage , et la qualité du générateur automatique dans
Unity ne nous convenait pas, nous avons donc décidé d'utiliser le scan de texture de base pour la cuisson aussi souvent que possible.
Ici, il y avait des problèmes évidents avec l'exactitude de l'éclairage. De toute évidence, les rayons entrant dans une statue dans l'œil ne devraient pas créer d'éblouissement
au cinquième point à l'arrière de la tête.
Éclairage du modèle mal cuit (à gauche) et corrigé (à droite)Lors de la création d'
une carte d'éclairage, Unity essaie principalement d'utiliser le canal
UV2 . S'il est vide, alors le principal
UV est utilisé , si celui-ci est vide, alors excusez-moi, mais c'est une exception. Il existe deux façons de créer des modèles dans
une lightmap sans
UV2 préalablement préparé dans
Unity .
En tant que premier,
Unity propose une génération automatique d'
UV2 basée sur la géométrie du modèle. C'est plus rapide que de le faire manuellement, de plus, cet outil peut être configuré à l'aide de plusieurs paramètres. Mais malgré cela, le chevauchement du clair-obscur qui en résulte est souvent insatisfaisant pour des objets très détaillés en raison de coutures et de fuites aux mauvais endroits, et l'emballage de pièces d'un tel balayage n'est pas le plus efficace.

La deuxième façon consiste à utiliser un scan
UV de base pour la cuisson. Une option très intéressante, car lorsque vous travaillez avec un scan de texture, il y a moins de chances de faire une erreur que lorsque vous travaillez avec deux. Pour cette raison, nous essayons de minimiser le nombre de modèles qui ont des superpositions dans la base
UV . Les outils créés nous aident à le faire.
La vérification du balayage de texture pour l'adéquation de l'indentation de pixel spécifiée à une résolution de texture donnée est une validation
UV plus précise basée sur la pixellisation. Plus d'informations sur cette méthode seront décrites dans le prochain article de la série.
Pour résumer. Bien sûr, il est presque impossible de suivre toutes les nuances: parfois, vous devez supporter l'imperfection du résultat afin de terminer la tâche à temps. Cependant, l'identification même d'une partie de ces lacunes permet d'accélérer le développement du projet et d'améliorer sa qualité.