Dans ce guide, nous vous expliquons comment configurer une structure capillaire à partir de l'ancien système de création de pilosité XGen de Maya en vue de l'importer dans l'Unreal Engine avec un ensemble d'attributs pris en charge décrits dans la documentation Spécifications relatives à la création de structures capillaires dans Alembic.
Nous avons utilisé Maya 2018.6 pour créer les ressources de ce guide.
Convertir les anciennes descriptions XGen
Convertir les guides en courbes NURBS
Procédez comme suit pour convertir les guides de votre structure capillaire en courbes afin d'enregistrer un ensemble de courbes correspondant aux guides que vous souhaitez transférer.
-
Définissez le menu de Maya sur Modélisation afin d'afficher les options de menu correctes disponibles.
-
Dans le menu principal, cliquez sur le menu déroulant Générer, puis sélectionnez Éditeur XGen.
-
Dans la fenêtre XGen, utilisez l’onglet Utilitaires pour sélectionner Guides en courbes.
-
Cliquez sur Créer des courbes.
Lorsque vous avez terminé, le résultat de votre structure capillaire doit être similaire à celui-ci :
Convertir les structures capillaires en structures capillaires interactives XGen
Si vous utilisez l'ancienne description XGen, vous devez convertir la structure capillaire en structure capillaire interactive XGen. Pour cela :
-
Sélectionnez les nœuds XGen Description.
-
Dans le menu Modélisation, utilisez le menu principal pour cliquer sur le menu déroulant Générer, puis sélectionnez Convertir en structure capillaire interactive.
Exporter des descriptions de splines vers des courbes NURBS
Procédez comme suit pour exporter vos descriptions de splines sélectionnées sous forme de fichier Alembic, que vous pouvez alors importer avec les pilosités interpolées sous forme de courbes NURBS.
-
Sélectionnez vos nœuds de description de spline XGen, et lorsque vous vous trouvez dans le menu Modélisation, utilisez le menu principal pour cliquer sur la liste déroulante Générer. Sélectionnez Cache > Exporter le cache dans la liste.
-
Dans la fenêtre Exporter le cache, définissez les paramètres suivants :
- Délai du cache : ce paramètre est défini sur Délai actuel
- Transformations multiples : ce paramètre est désactivé.
- Écrire la largeur finale : ce paramètre est activé
-
Donnez un nom à votre fichier et sélectionnez Alembic comme type de fichier.
- Cliquez sur Exporter.
-
Utilisez le menu Fichier pour sélectionner Importer. La fenêtre Importer s'ouvre. Vous pouvez l'utiliser pour sélectionner et importer votre fichier Alembic ('.abc') dans votre scène.
Une fois votre fichier importé, une description de spline XGen doit avoir été exportée et enregistrée sous forme de fichier Alembic, puis importée avec les pilosités interpolées sous forme de courbes NURBS.
Créer des attributs
Créer des attributs d'ID de groupe
Vous pouvez exporter les pilosités interpolées dans un ou plusieurs groupes. Ces groupes sont reconnus dans l'Unreal Engine pour une assignation de matériaux unique.
Utilisez le script suivant lors de la création d'attributs d'ID de groupe :
from maya import cmds
attr_name = 'groom_group_id'
# REMARQUE : modifiez les noms suivants pour refléter la scène de votre nœud.
groups = ['hair_brows_splineDescription1|SplineGrp0', 'hair_lashes_splineDescription1|SplineGrp0', 'hair_head_splineDescription1|SplineGrp0']
pour groom_group_id, group_name dans enumerate(groups) :
# obtenir des courbes sous xgGroom
curves = cmds.listRelatives(group_name, ad=True, type='nurbsCurve')
# groupe de balises avec ID de groupe
cmds.addAttr(group_name, longName=attr_name, attributeType='short', defaultValue=groom_group_id, keyable=True)
# ajouter une étendue d'attribut
# force le fichier Alembic de Maya à exporter les données au format GeometryScope::kConstantScope
cmds.addAttr(group_name, longName='{}_AbcGeomScope'.format(attr_name), dataType='string', keyable=True)
cmds.setAttr('{}.{}_AbcGeomScope'.format(group_name, attr_name), 'con', type='string')
Créer des attributs de guide
Lors de la création des attributs de guide pour votre structure capillaire, seules les courbes portant la balise guide sont utilisées pour la simulation dans l'Unreal Engine. Si aucun guide n'est spécifié dans le fichier Alembic, un pourcentage des pilosités interpolées sera balisé en interne comme guides pendant le processus d'importation dans l'Unreal Engine.
Lors de l'importation d'une structure capillaire sans guides, le pourcentage de pilosités interpolées marquées comme guides peut être défini à l'aide des options d'importation de la structure capillaire. Par défaut, seulement 10 % du nombre de pilosités sont utilisés comme guides.
Utilisez le script suivant lors de la création des attributs de votre guide :
from maya import cmds
attr_name = 'groom_guide'
# obtenir des courbes sous xgGroom
curves = cmds.listRelatives('xgGroom', ad=True, type='nurbsCurve')
# créer un nouveau groupe
guides_group = cmds.createNode('transform', name='guides')
# groupe de balises en tant que groom_guide
cmds.addAttr(guides_group, longName=attr_name, attributeType='short', defaultValue=1, keyable=True)
# force le fichier Alembic de Maya à exporter les courbes en un seul groupe.
cmds.addAttr(guides_group, longName='riCurves', attributeType='bool', defaultValue=1, keyable=True)
# ajouter une étendue d'attribut
# force le fichier Alembic de Maya à exporter les données au format GeometryScope::kConstantScope
cmds.addAttr(guides_group, longName='{}_AbcGeomScope'.format(attr_name), dataType='string', keyable=True)
cmds.setAttr('{}.{}_AbcGeomScope'.format(guides_group, attr_name), 'con', type='string')
# courbes parentes sous le groupe de guides
for curve in curves:
cmds.parent(curve, guides_group, shape=True, relative=True)
Attribut Groom_Width
Pour Maya, la valeur de largeur a un comportement spécial, contrairement à d'autres applications de CCN qui peuvent suivre les spécifications relatives à la création de structures capillaires dans Alembic pour les récupérer et les utiliser en vue de créer la structure capillaire.
Maya peut exporter les valeurs de largeur directement sur les courbes, de sorte qu'il n'est pas nécessaire d'exporter un attribut personnalisé groom_width ; l'importateur convertit automatiquement ces valeurs dans cet attribut. Si l'attribut groom_wdith est présent avec la structure capillaire lors de l'importation dans l'Unreal Engine, il n'est pas écrasé. Si l'attribut groom_width n'est pas spécifié, ou ne peut pas être converti à partir des valeurs de largeur, le générateur se rabat automatiquement sur une valeur de 1 centimètre.
Exporter vers Alembic depuis Maya
-
Dans Maya, sélectionnez les courbes Guides et Group_ID que vous souhaitez exporter.
Chaque nœud doit avoir un nom unique.
-
Dans le menu Modélisation, utilisez le menu principal pour cliquer sur le menu déroulant Cache, puis sélectionnez Cache Alembic > Exporter la sélection dans Alembic.
-
Dans la fenêtre Exporter la sélection, sous la catégorie Options générales, définissez l'option Délai du cache sur Délai actuel.
-
Sous la catégorie Attributs, saisissez le nom de l'attribut que vous souhaitez ajouter à la liste et cliquez sur le bouton Ajouter. Ajoutez les attributs de schéma suivants :
- groom_group_id
- groom_guide
-
Saisissez un nom de fichier dans la zone de texte Nom de fichier et définissez Fichiers de type sur Alembic.
-
Cliquez sur le bouton Exporter la sélection.
Appliquer des textures aux UV de pilosité
Les étapes suivantes et le script inclus peuvent vous aider à configurer vos propres pilosités XGen, puis à les exporter vers l'Unreal Engine en vue de représenter une texture appliquée sur des mèches individuelles.
-
Dans Maya, utilisez le menu Modélisation pour sélectionner Générer > Créer des splines de structure capillaire interactive.
-
Vous pouvez créer des guides et brosser les cheveux comme vous le souhaitez pour votre projet. Lorsque vous êtes prêt, exportez les courbes sous forme de cache Alembic en sélectionnant Générer > Cache > Créer un nouveau cache.
-
Retirez vos pilosités XGen en les masquant ou en les supprimant. Ensuite, réimportez vos courbes de pilosité exportées avec votre maillage source dans la scène Maya.
-
Selon votre scène, vous aurez des milliers de courbes de splines apparentées sous une courbe supérieure, SplineGrp0 dans cet exemple. Modifiez le script Python suivant et remplacez les valeurs suivantes par celles de votre projet :
- export_directory
- hair_file
- curve_top_group
- uv_mesh
Vous pouvez télécharger le script ci-dessous ici.
from maya import cmds from maya import OpenMaya import os def create_root_uv_attribute(curves_group, mesh_node, uv_set='map1'): ''' Create "groom_root_uv" attribute on group of curves. ''' # vérifier le groupe de courbes if not cmds.objExists(curves_group): raise RuntimeError('Group not found: "{}"'.format(curves_group)) # obtenir des courbes dans le groupe curve_shapes = cmds.listRelatives(curves_group, shapes=True, noIntermediate=True) curve_shapes = cmds.ls(curve_shapes, type='nurbsCurve') if not curve_shapes: raise RuntimeError('Invalid curves group. No nurbs-curves found in group.') else: print "found curves" print curve_shapes # obtenir les racines de la courbe points = list() for curve_shape in curve_shapes: point = cmds.pointPosition('{}.cv[0]'.format(curve_shape), world=True) points.append(point) # obtenir les UV values = list() uvs = find_closest_uv_point(points, mesh_node, uv_set=uv_set) for u, v in uvs: values.append([u, v, 0]) #print (str(u) + " , " + str(v) ) # créer un attribut name = 'groom_root_uv' cmds.addAttr(curves_group, ln=name, dt='vectorArray') cmds.addAttr(curves_group, ln='{}_AbcGeomScope'.format(name), dt='string') cmds.addAttr(curves_group, ln='{}_AbcType'.format(name), dt='string') cmds.setAttr('{}.{}'.format(curves_group, name), len(values), *values, type='vectorArray') cmds.setAttr('{}.{}_AbcGeomScope'.format(curves_group, name), 'uni', type='string') cmds.setAttr('{}.{}_AbcType'.format(curves_group, name), 'vector2', type='string') return uvs def find_closest_uv_point(points, mesh_node, uv_set='map1'): ''' Find mesh UV-coordinates at given points. ''' # vérifier le maillage if not cmds.objExists(mesh_node): raise RuntimeError('Node not found: "{}"'.format(mesh_node)) # vérifier uv_set uv_sets = cmds.polyUVSet(mesh_node, q=True, allUVSets=True) if uv_set not in uv_sets: raise RuntimeError('Invalid uv_set provided: "{}"'.format(uv_set)) # obtenir le maillage en tant que dag-path selection_list = OpenMaya.MSelectionList() selection_list.add(mesh_node) mesh_dagpath = OpenMaya.MDagPath() selection_list.getDagPath(0, mesh_dagpath) mesh_dagpath.extendToShape() # obtenir l'ensemble de fonctions de maillage fn_mesh = OpenMaya.MFnMesh(mesh_dagpath) uvs = list() for i in range(len(points)): script_util = OpenMaya.MScriptUtil() script_util.createFromDouble(0.0, 0.0) uv_point = script_util.asFloat2Ptr() point = OpenMaya.MPoint(*points[i]) fn_mesh.getUVAtPoint(point, uv_point, OpenMaya.MSpace.kWorld, uv_set) u = OpenMaya.MScriptUtil.getFloat2ArrayItem(uv_point, 0, 0) v = OpenMaya.MScriptUtil.getFloat2ArrayItem(uv_point, 0, 1) uvs.append((u, v)) return uvs def abc_export(filepath, node=None, start_frame=1, end_frame=1, data_format='otawa', uv_write=True): job_command = '-frameRange {} {} '.format(start_frame, end_frame) job_command += '-dataFormat {} '.format(data_format) job_command += '-attr groom_root_uv ' if uv_write: job_command += '-uvWrite ' job_command += '-root {} '.format(node) job_command += '-file {} '.format(filepath) cmds.AbcExport(verbose=True, j=job_command) def main(): export_directory = 'D:/Dev/Ref' hair_file = os.path.join(export_directory, 'hair_export.abc') curve_top_group= 'description1|SplineGrp0' uv_mesh='pPlane1' create_root_uv_attribute( curve_top_group , uv_mesh) abc_export(hair_file, curve_top_group) main() -
Dans Maya, exécutez le script avec les valeurs modifiées pour générer un nouveau fichier Alembic ('.abc') qui peut être importé dans l'Unreal Engine.
-
Dans l'Unreal Engine, créez un nouveau matériau à l'aide du modèle d'ombrage Pilosité. Dans le graphique de matériau, ajoutez une expression Attributs de pilosité et associez l'UV racine à l'entrée UV de l'échantillon de texture.
L'attribut
groom_root_uvspécifie pour chaque pilosité le maillage UV sous-jacent auquel elle est jointe. Cet attribut est facultatif et, s'il n'est pas spécifié, une racine UV est automatiquement générée dans le moteur à l'aide d'un texturage sphérique. -
Faites glisser votre fichier de pilosité Alembic importé dans le niveau à partir du navigateur de contenu et attribuez-lui votre matériau de pilosité. Le résultat doit être similaire à celui-ci :
Assurez-vous que votre fichier de pilosité Alembic dans le niveau a une largeur supérieure à 0.