Chaque année ~~ Âgés ~~ Le calendrier de l'Avent annuel Houdini. Eh bien, j'ai réfléchi à ce qu'il faut écrire, mais comme je ne touche Arnold que cette année, j'aimerais écrire des informations qui semblent utiles dans HtoA (Arnold pour Houdini). Arnold est l'un des moteurs de rendu
En d'autres termes, il s'agit d'un moteur de rendu pris en charge par la plupart des principaux logiciels, et on peut dire que c'est la norme de facto de facto dans l'industrie vidéo. De plus, il est avantageux de pouvoir rendre n'importe quel DCC avec une licence de rendu par lots. De plus, vous pouvez écrire des shaders non seulement en C ++ mais aussi en ** O ** pen ** S ** hading ** L ** anguage (OSL), et il prend également en charge MaterialX (décrit plus tard) rapidement. Ou est-ce le dollar suivant? J'ai hâte d'y être. Le moteur de rendu Mantra standard de Houdini est une spécification généreuse que les utilisateurs de Houdini peuvent utiliser autant qu'ils le souhaitent gratuitement, et le shader est facile à écrire avec le VEX familier, donc je l'aime bien, mais l'inconvénient qu'il ne fonctionne qu'avec Houdini est douloureux. Arnold peut être rendu (** Kick Ass ) dans un fichier ass ( A ** rnold ** S ** cene ** S ** ource), qui est un format de description de scène standardisé. .. En d'autres termes, si vous exportez n'importe quel DCC vers ass, vous pouvez rendre n'importe quel DCC.
Si vous comprenez Arnold, il vaut mieux étudier le cul. Voici une page recommandée pour votre référence. https://arnoldsupport.com/category/ass/
** Notez que Houdini nécessite une licence Houdini Indie, Houdini Core ou Houdini FX pour utiliser un moteur de rendu tiers tel qu'Arnold. De plus, la version Houdini Indie ne peut pas générer de fichiers ass: sob: ** Alors, veuillez étudier en produisant le cul dans l'environnement Houdini Core / FX, environnement Maya (version étudiante, licence domestique est également possible).
Si vous souhaitez rendre une scène de rendu construite dans Maya coexistant avec la scène de rendu Houdini sur Houdini, exportez simplement le cul de MtoA et lisez-le dans HtoA.
Exécutez ** le menu Arnold → Exporter Stand In ** sur MtoA, vérifiez les informations que vous souhaitez générer et exportez le fichier ass.
Ajoutez simplement ** Arnold Procedural ** ou ** Arnold Include ** sur le contexte HtoA / obj
et spécifiez le fichier ass pour capturer la scène Arnold de Maya directement sur Houdini.
Pour les scènes utilisant des shaders spécifiques à Maya, il est nécessaire de spécifier le chemin de cette DLL dans le Plugin Path
d'Arnold ROP, mais au fur et à mesure que la version monte, le shader spécifique DCC passe au shader Arnold pur. Ça devient. Attentes pour l'avenir.
Un exemple d'importation d'une scène Maya dans Houdini via un fichier ass et coexistant avec Mr. Pig.
C'est pratique.
Cependant, si vous souhaitez éditer un autre objet DCC sur Houdni, vous devrez actuellement l'importer dans Houdini dans un format intermédiaire tel que Alembic / FBX (ci-après USD), attribuer un shader Arnold et le rendre.
En plus de cela, il peut être utile de préparer Maya, alors je voudrais vous le présenter.
L'extension de fichier Houdini est ** hip ** L'extension de fichier Arnold est ** ass ** ** hanche et cul !!! **: penser: D'une manière ou d'une autre, il semble être compatible: spy_tone1:
Houdini utilise souvent la position de repos. Position de repos est le mot japonais pour «position de repos». S'il s'agit d'Arnold, cela signifie Pref (Position Reference), et s'il s'agit de Maya, cela signifie Objet de référence. La raison pour laquelle cela est nécessaire est que si vous créez un shader en projetant une texture sur une géométrie en 2D / 3D (par exemple, projection de caméra), la texture projetée apparaîtra glissante si la géométrie se déforme. Dans ce cas, nous utilisons la technique consistant à renvoyer le résultat de la projection 2D / 3D à la géométrie non transformée vers la géométrie transformée. Si vous n'êtes pas sûr, lisez ici. https://houdini.prisms.xyz/wiki/index.php?title=Rest_Attrib Pour définir la position de repos dans Maya, exécutez ** Créer un objet de référence de texture ** dans le menu ** Texturing ** et dans Arnold ** Exporter les positions de référence * dans la propriété Arnold de la forme Maya pour refléter cela. Est d'activer *. Cette méthode est unique à Maya et je la déteste car elle fait référence à la géométrie dans un format de référence. Et il ne peut pas être présenté comme un attribut uniquement dans Alambic. Idéalement, j'aimerais ajouter la position de repos comme attribut de sommet à la géométrie et exporter cet attribut vers Alembic.
Vous pouvez éventuellement ajouter des attributs de sommet / face aux formes Maya ** en construisant MEL **, je vais donc vous montrer comment faire cela. ** Généralement, ** Attribut de sommet Maya <-> Attribut de point Houdini, attribut de face Maya <-> Attribut primitif Houdini. Cette fois, je voudrais ajouter la position de repos comme attribut de sommet, mais je voudrais également expliquer comment ajouter un attribut de sommet / face en ajoutant un attribut de face qui contient le nom du shader pour chaque face.
Le code Pymel est ci-dessous. Il s'agit d'un ** script pour Maya qui ajoute une position de repos et un chemin shop_materialpath à une forme à laquelle un shader Arnold est affecté au SG **. Puisque nous obtenons les coordonnées des sommets dans l'espace mondial, nous supposons que la transformation de l'objet que vous souhaitez exporter vers Alembic est gelée.
--Un attribut de sommet nommé rest
qui stocke les informations de position de la géométrie du cadre actuel
shop_materialpath
qui stocke le nom du shader assigné à la géométrie comme / shop / maya / shader name
Peut être ajouté. Si vous appliquez cela, vous pouvez ajouter Velocity et Cd, alors essayez-le.
repos et magasinage_Script PyMEL pour ajouter un chemin de matériau
import pymel.core as pm
#Déclarez un dictionnaire où la clé est le nom de la forme et la valeur est une paire de listes de valeurs d'attribut de visage pour cette forme
dictAttributes = {}
context = "/shop/maya/"
for eachSG in pm.ls(type="shadingEngine"):
members = pm.sets(eachSG,q=True,nodesOnly=False)
#Objection à SG/Ignorer si aucun composant n'est attribué
if len(members)==0:
continue
#Si aucun shader n'est affecté à SG, ignorez-le.
#Un shader de surface dans lequel le connecteur d'entrée de l'aiSurfaceShader de SG est prioritaire dans Arnold. Sinon, le shader de surface du connecteur d'entrée de surfaceShader est utilisé.
shader = (pm.listConnections(eachSG+".aiSurfaceShader",p=False,c=False,s=True,d=False) or [""])[0]
if shader == "":
shader = (pm.listConnections(eachSG+".surfaceShader",p=False,c=False,s=True,d=False) or [""])[0]
if shader == "":
continue
shaderName = shader.name()
#Traitement de branche selon qu'il s'agit d'une allocation au niveau de l'objet ou d'une allocation au niveau du composant.
#Au niveau de l'objet, préparez une liste aussi grande que le nombre de toutes les faces et écrivez le nom du shader sur tous les éléments de la liste.
#Au niveau du composant, écrivez les informations sur le nom du shader dans l'index de cette face
for eachMember in members:
#Traitement lorsque SG est associé à un objet
if type(eachMember) == pm.nodetypes.Mesh:
dictAttributes[eachMember]={"shader":[],"rest":[]}
dictAttributes[eachMember]["shader"] = [context+shaderName]*eachMember.numFaces()
for vtxIndex in range(eachMember.numVertices()):
position = pm.pointPosition(eachMember+".vtx["+str(vtxIndex)+"]",world=True).get()
dictAttributes[eachMember]["rest"].append( [position[0],position[1],position[2]] )
#Traitement lorsque SG est lié au visage
elif eachMember._ComponentLabel__ == "f":
listComponents = pm.ls(eachMember,flatten=True)
shape = eachMember._node
if shape not in dictAttributes:
dictAttributes[shape]={"shader":[],"rest":[]}
dictAttributes[shape]["shader"]= [""]*eachMember.totalSize()
for vtxIndex in range(shape.numVertices()):
dictAttributes[shape]["rest"].append( pm.pointPosition(shape+".vtx["+str(vtxIndex)+"]",world=True) )
#Ecrire le nom du shader dans l'index de la liste correspondante
for index in eachMember.indices():
dictAttributes[shape]["shader"][index] = context+shaderName
restAttributeName = "rest"
shaderAttributeName = "shop_materialpath"
for eachShape in dictAttributes:
#Ajout de l'attribut Position de repos
if not pm.attributeQuery(restAttributeName+"_AbcGeomScope",node=eachShape,exists=True):
pm.addAttr(eachShape, dataType="string", longName=restAttributeName+"_AbcGeomScope")
pm.setAttr(eachShape+"."+restAttributeName+"_AbcGeomScope", "var")
if not pm.attributeQuery(restAttributeName,node=eachShape,exists=True):
pm.addAttr(eachShape,dataType="vectorArray",longName=restAttributeName)
pm.setAttr(eachShape+"."+restAttributeName,dictAttributes[eachShape]["rest"])
#shop_Ajout de l'attribut materialpath
if not pm.attributeQuery(shaderAttributeName+"_AbcGeomScope",node=eachShape,exists=True):
pm.addAttr(eachShape, dataType="string", longName=shaderAttributeName+"_AbcGeomScope")
pm.setAttr(eachShape+"."+shaderAttributeName+"_AbcGeomScope", "uni")
if not pm.attributeQuery(shaderAttributeName,node=eachShape,exists=True):
pm.addAttr(eachShape,dataType="stringArray",longName=shaderAttributeName)
pm.setAttr(eachShape+"."+shaderAttributeName,dictAttributes[eachShape]["shader"])
Une fois exécutés, des attributs personnalisés seront ajoutés comme indiqué ci-dessous. Je pense que la valeur est affichée au format d'un champ de valeur numérique / chaîne s'il s'agit d'un attribut normal, mais comme le reste / shop_materialpath ajouté est une valeur de tableau pour chaque sommet / face, la valeur ne peut pas être confirmée à partir de l'interface graphique. J'aimerais pouvoir le vérifier dans l'éditeur de composants. .. .. J'ajoute intentionnellement un nom d'attribut nommé ʻattribute name_AbcGeomScope` ici, ce qui est logique.
Avez-vous remarqué que lorsque vous ajoutez un attribut de valeur de tableau à une forme, ce ne sont pas assez d'informations?
Est-ce un attribut de tableau par objet? Est-ce un attribut par vertical? Est-ce un attribut basé sur le visage?
Vous devez le spécifier explicitement.
Même dans Houdini, lorsque vous touchez le Wrangle SOP, vous spécifiez intentionnellement quel attribut de Point / Sommet / Primitive / Détail avec le paramètre "Run Over".
** Maya ajoute des attributs sur la forme ** Ci-dessus, vous devez spécifier quel attribut est un sommet, une face ou un objet comme information supplémentaire.
L'importateur / exportateur d'alambic de Maya définit le suffixe _AbcGeomScope
comme les métadonnées qui jouent ce rôle.
Cette information peut être trouvée dans le code publié sur Github d'Alembic.
https://github.com/alembic/alembic/blob/master/maya/AbcExport/AttributesWriter.cpp
Il semble que vous puissiez spécifier vtx
, fvr
, ʻuniet
var pour la valeur de la chaîne
_AbcGeomScope. Si aucune autre valeur ou «_AbcGeomScope» n'est définie, elle sera traitée comme «const», c'est-à-dire que ce sera un attribut par objet. Cette fois, l'alambic écrit du côté maya voulait être reconnu comme l'attribut Point de Houdini en définissant l'attribut rest sur
var et shop_materialpath sur ʻuni
dans Houdini, de sorte que le code ci-dessus est reconnu comme l'attribut primitif de Houdini. C'est une telle désignation.
Maintenant, préparez le modèle. Ici, nous avons préparé trois types: une sphère déformante, une sphère avec une face de shader assignée et le sol. Avec des attributs ajoutés et plusieurs géométries que vous souhaitez exporter vers Houdini sélectionnées, ** Exécuter le menu du cache → Cache d'alambic → Exporter la sélection vers l'alambic ... **. Ajoutez un attribut comme indiqué ci-dessous.
_AbcGeomScope
n'est nécessaire que par l'importateur / exportateur d'Alembic de Maya pour déterminer le type d'attribut, donc seuls rest
et shop_materialpath
sont nécessaires.
** Ogawa ** est requis pour ** Format de fichier **. Arnold prend uniquement en charge ** Ogawa **.
** Write Face Sets ** est requis si des attributs par face ont été attribués.
Lorsque j'ai importé la sortie du fichier Alembic de Maya dans Houdini, la position de repos a été capturée comme attribut rest
Point: détendu:
L'attribut primitif shop_materialpath
est également chargé.
Placer un shader dans ce chemin élimine le besoin de réaffecter le matériau.
Placez le shader dans le contexte / shop
.
L'API Arnold Python vous permet d'analyser les informations de shader dans un fichier ass exporté depuis Maya et de le reproduire sous forme de graphique de shader sur Houdini.
Je suis désolé de ne pas pouvoir publier la méthode. Vous pouvez l'essayer vous-même en vous référant à l'API Arnold Python décrite ci-dessous: japanese_ogre:
(Ajouté le 13 décembre 2019) À partir de HtoA5.0.0 (Arnold6), la fonction permettant de créer un fichier ass en tant que graphique de shader a été ajoutée. https://docs.arnoldrenderer.com/display/A5AFHUG/HtoA+5.0.0
Après avoir placé le shader, lorsque j'essaye de le rendre avec Arnold ROP, si je charge Alembic comme une géométrie Houdini normale, il sera rendu, mais s'il est toujours compressé, le shader ne sera pas reflété. Comment attribuer un shader à Packed Alambic
--Utiliser l'attribut material_attribute --Utiliser MaterialX --Utiliser aiOperator
C'est possible en utilisant l'un de ceux-ci. La méthode utilisant MaterialX et aiOperator n'autorise actuellement que les affectations de ** niveau objet **.
La fonction material_attribute peut reconnaître le shop_materialpath défini dans Packed Alembic et attribuer des shaders. C'est quelque chose que j'ai toujours voulu faire, mais c'est rendu possible avec HtoA 4.2.0 sorti cette année. https://docs.arnoldrenderer.com/display/A5AFHUG/HtoA+4.2.0 Dans cette note de version,
Add per primitive shop_materialpath translation in the alembic procedural
Est écrit.
Oui, c'est pourquoi j'ai ajouté l'attribut shop_materialpath
dans Maya.
Vérifiez simplement «Exporter les matériaux référencés» dans Arnold ROP et il regardera le chemin de l'attribut «shop_materialpath» dans Packed Alembic et attribuera un shader.
MtoA et HtoA ont des exportateurs MaterialX. Je fabrique mon propre exportateur car il est trop minable, mais ici, je vais expliquer comment attribuer un shader à Packed Alembic en utilisant l'exportateur MaterialX standard.
Qu'est-ce que MaterialX? Pour ceux qui sont intéressés, veuillez vous référer à https://www.materialx.org/.
En fait, je traduis les spécifications en japonais. https://materialx.prisms.xyz/
Avec plusieurs géométries que vous souhaitez exporter vers MaterialX sélectionnées sur Maya, exécutez le menu ** Arnold Utilities → Export Selection to MaterialX **.
Définissez simplement la destination de sortie du fichier MaterialX (.mtlx
) sur ** Nom de fichier ** et le" nom approprié "sur ** Nom de l'apparence ** et ** Exporter **.
Ensuite, un fichier XML comme celui-ci sera généré.
Définissez le schéma du shader avec l'élément xi: include
. Si vous avez ajouté un shader personnalisé, ajoutez un nouveau schéma de shader ici.
** Il convient de noter la valeur de l'attribut geom
de l'élément<materialassign> ʻelement. ** ** MaterialX peut accéder à la hiérarchie de géométrie interne de l'Alambic Packed avec le * wildcard * spécifié par cet attribut
geom. Cette valeur sortie par MaterialX standard n'est pas pratique. Cette fois, réécrivons la partie de
geom =" / Gonyogonyo "en
geom =" * / Gonyogonyo "` dans l'éditeur de texte.
Connectez simplement le MaterialX ROP à l'Arnold ROP, définissez la sélection sur le chemin de l'objet Alembic, le fichier MaterialX sur le chemin du fichier MaterialX et le look sur le nom de l'apparence et le rendu, et le graphe de shader et l'affectation de shader seront traités automatiquement. ..
La bonne chose à propos de MaterialX est que vous n'avez pas à reconstruire le graphe de shader sur HtoA, et vous n'avez pas à être conscient de la hiérarchie car vous pouvez faire des affectations de shader avec des caractères génériques.
Comme vous pouvez le voir dans le résultat du rendu, l'affectation de shader pour chaque face n'est pas possible.
** material_attribute ** permet les affectations face à face, mais le graphe de shader réel doit être construit dans le contexte / shop, ce qui semble être un obstacle de taille.
** MaterialX ** est facile, mais il peut être difficile pour les artistes de modifier son XML.
Avec ** aiOperator **, même un artiste peut éditer avec un peu d'étude, et le graphique de shader de Maya peut être importé et contrôlé comme un fichier ass.
Quand je touche Arnold, je pense que le fichier ass est utile.
** Le fichier ass est principalement utilisé pour décrire les scènes, mais il est également préparé comme un fichier qui définit les graphiques de shader, un fichier qui définit les lumières et un fichier qui définit les paramètres de rendu. Vous pouvez le préparer comme. ** **
Apprenez à utiliser aiOperator pour importer des graphiques de shader Maya via un fichier ass.
Tout d'abord, sur Maya, affichez le fichier ass du shader uniquement.
** Exécutez le menu Arnold → Stand In → Export Stand In **.
Cochez uniquement Shaders
dans l'élément Exporter et exportez le fichier ass.
Nommez ce fichier, par exemple, «ShadersOnly.ass».
Sur Houdini, placez un objet ** Arnold Include ** dans le contexte / obj
. Spécifiez le fichier ShadersOnly.ass
ici.
Cela vous permet d'importer des graphiques de shader Maya.
Pour assigner un graphe de shader capturé par ** Arnold Include ** à n'importe quel objet, ajoutez le ** Set Parameter ROP ** de aiOperator dans le contexte / out
et ajoutez-le à ** Arnold ROP **. Relier
Ensuite, dans ** Selection **, entrez le chemin de l'objet auquel vous voulez affecter le shader
, et dans le paramètre ** Assignment_1 **, entrez` shader [0] =" shader name "" décrit dans le fichier ass.
Lorsque j'ai essayé le rendu avec cela, j'ai pu attribuer un shader.
Vous pouvez affecter des shaders à d'autres objets en vous connectant à Arnold ROP de la même manière.
e? : oreille: Est-ce gênant?
Eh bien, c'est vrai. Créons donc un script qui déchiffre le fichier ass et configure automatiquement ** aiOperator **. Le fichier ass nécessaire ici est les informations sur le shader et la forme qui lie ce shader. Le fichier ass lu par ** Arnold Include ** contient uniquement des informations sur le shader, pas le shader à lier à quelle forme. Par conséquent, exécutez à nouveau ** Export StandIn ** et Dans l'élément Export, cochez "Shapes" et "Shaders" pour exporter le fichier ass. Par exemple, «ShapesShaders.ass».
Script Python qui configure automatiquement aiOperator
import arnold
arnold.AiBegin()
assFilePath = "F:/AdventCalendar2019/ShapesShaders.ass"
dicShapes={}
result = arnold.AiASSLoad(assFilePath)
nodeIter = arnold.AiUniverseGetNodeIterator(arnold.AI_NODE_SHAPE)
while not arnold.AiNodeIteratorFinished(nodeIter):
node = arnold.AiNodeIteratorGetNext(nodeIter)
nodeName = arnold.AiNodeGetName(node)
nodeEntry = arnold.AiNodeGetNodeEntry(node)
if nodeName == "root" or nodeName == "":
continue
dicShapes[nodeName]={}
parmIter = arnold.AiNodeEntryGetParamIterator(nodeEntry)
while not arnold.AiParamIteratorFinished(parmIter):
parm = arnold.AiParamIteratorGetNext(parmIter)
parmName = arnold.AiParamGetName(parm)
if parmName == "shader":
dicShapes[nodeName][parmName] = []
parmArray = arnold.AiNodeGetArray(node,parmName)
for arrayIndex in range(arnold.AiArrayGetNumElements(parmArray)):
dicShapes[nodeName][parmName].append(arnold.AiNodeGetName(arnold.AiArrayGetPtr(parmArray, arrayIndex)))
elif parmName == "visibility":
dicShapes[nodeName][parmName] = arnold.AiNodeGetInt(node,parmName)
arnold.AiParamIteratorDestroy(parmIter)
arnold.AiNodeIteratorDestroy(nodeIter)
subnet = hou.node("/out").createNode("subnet","setParms")
merge = subnet.createNode("merge","Merge")
for shapeIndex,eachShape in enumerate(dicShapes):
setParameterNode = subnet.createNode("set_parameter",eachShape)
merge.setInput(shapeIndex,setParameterNode)
setParameterNode.parm("selection").set("*/"+eachShape)
setParameterNode.parm("assignment").set(1)
setParameterNode.parm("assignment_1").set("visibility="+str(dicShapes[eachShape]["visibility"]))
for shaderIndex,eachShader in enumerate(dicShapes[eachShape]["shader"]):
setParameterNode.parm("assignment").set(shaderIndex+2)
setParameterNode.parm("assignment_"+str(shaderIndex+2)).set("shader["+str(shaderIndex)+"]=\""+str(dicShapes[eachShape]["shader"][shaderIndex])+"\"")
Lorsque j'exécute ce script, un sous-réseau setParms est créé dans le contexte / out
, et des ROP de paramètres définis y sont créés et fusionnés pour le nombre d'objets définis dans le fichier ass.
Connectez ce sous-réseau au Arnold ROP.
Vous pouvez maintenant effectuer le rendu.
Comme MaterialX, aiOperator ne prend en charge que les affectations de shader au niveau objet, voici donc le résultat.
Cependant, si votre modèle n'a pas d'attributions de shader face à face, vous pouvez utiliser l'API Arnold Python avec un fichier ass pour lookDev dans Houdini, même si vous n'êtes pas dans Maya.
Environnement de vérification: Maya2019 MtoA3.3.0.2 Houdini17.5.425 HtoA4.4.1
Fin: étreindre:
Recommended Posts