SOP->LOP Material Workflow

   7968   10   6
User Avatar
Member
23 posts
Joined: 8月 2019
Offline
Hey all,

Is there a recommended SOP->LOP workflow with materials? We'd like to assign materials in SOPs and have them carry over to UsdShade in LOPS.

VOP Materials assigned in LOPs create UsdShade references *and* translated USD preview shaders. However, materials assigned in SOP and imported into LOPs with default settings preserve the shop_materialpathproperty as primvars::shop_materialpathbut no UsdShade material slots or bindings are created in the output LOP stage.

Is there a node that performs this linking automagically?

Otherwise, is there a conceptual difference preventing a node like this from being published?

Thanks!
User Avatar
Member
7747 posts
Joined: 9月 2011
Offline
SOP Create imports materials and performs assignments to geometry subsets based on shop_materialpath values. The primvars:shop_materialpath is superfluous, and can be filtered using the sop import attribute settings.

I'm not sure if there is another node that translates materials and assignments the way sop create does. Scene import will import geometry and materials, but I don't know how it handles materials assigned at geometry level.
User Avatar
Member
23 posts
Joined: 8月 2019
Offline
@jsmack, this isn't the behavior I'm experiencing. I get a USD output without a binding, just a shop_materialpath primvar in partitions.

Attached below is the repro.

Houdini Core Version 18.0.287

Repro steps:

1. in /stage, create a “Sop Create” node
2. in /mat, create a principled shader, select teal as an emissive color.
3. in /stage/sopcreate1, create a “box” and assign it the material via “material” node.
4. material will appear teal inside /stage/sopcreate1/sopnet/create.
5. in /stage, right-click sopnet1 -> LOP Options -> Inspect Flattened Stage.


Output USD:
#usda 1.0
(
defaultPrim = "sopcreate1"
doc = """Generated from Composed Stage of root layer
"""
)

def Xform "sopcreate1" (
kind = "component"
)
{
matrix4d xformOp:transform:xform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
uniform token[] xformOpOrder = ["xformOp:transform:xform"]

def Mesh "mesh_0"
{
float3[] extent = [(-0.5, -0.5, -0.5), (0.5, 0.5, 0.5)]
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4] (
customData = {
int64 HoudiniDataId = 2654593799
}
)
int[] faceVertexIndices = [1, 5, 4, 0, 2, 6, 5, 1, 3, 7, 6, 2, 0, 4, 7, 3, 2, 1, 0, 3, 5, 6, 7, 4] (
customData = {
int64 HoudiniDataId = 2654593799
}
)
uniform token orientation = "leftHanded"
point3f[] points = [(-0.5, -0.5, -0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, -0.5), (0.5, 0.5, -0.5), (0.5, 0.5, 0.5), (-0.5, 0.5, 0.5)] (
customData = {
int64 HoudiniDataId = 158027
}
interpolation = "vertex"
)
uniform token subdivisionScheme = "none"
uniform token subsetFamily:shop_materialpath:familyType = "partition"

def GeomSubset "shop_materialpath__mat_principledshader1" (
customData = {
string partitionValue = "/mat/principledshader1"
}
)
{
uniform token familyName = "shop_materialpath"
int[] indices = [0, 1, 2, 3, 4, 5]
}
}
}

def HoudiniLayerInfo "HoudiniLayerInfo" (
customData = {
string HoudiniCreatorNode = "/stage/sopcreate1/sopimport"
string[] HoudiniEditorNodes = ["/stage/sopcreate1/sopnet/OUT", "/stage/sopcreate1/sopimport", "/stage/sopcreate1/merge1", "/stage/sopcreate1/xform"]
string HoudiniSaveControl = "Placeholder"
}
)
{
}

Attachments:
repro.hip (244.1 KB)

User Avatar
Member
7747 posts
Joined: 9月 2011
Offline
The materials aren't dynamic. Click the auto-fill button on the material tab to create material prims corresponding to the shop_materialpath values.

#usda 1.0
(
    defaultPrim = "tetrahedron"
    doc = """Generated from Composed Stage of root layer 
"""
)

def Xform "tetrahedron" (
    kind = "component"
)
{
    matrix4d xformOp:transform:xform = ( (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) )
    uniform token[] xformOpOrder = ["xformOp:transform:xform"]

    def Mesh "mesh_0"
    {
        float3[] extent = [(-0.9428103, -0.3333297, -0.8164976), (0.47140515, 1, 0.8164976)]
        int[] faceVertexCounts = [3, 3, 3, 3] (
            customData = {
                int64 HoudiniDataId = 2654461245
            }
        )
        int[] faceVertexIndices = [0, 3, 2, 0, 1, 3, 0, 2, 1, 1, 2, 3] (
            customData = {
                int64 HoudiniDataId = 2654461245
            }
        )
        normal3f[] normals = [(0.9428086, 0.33333457, -0), (-0.47140425, 0.33333454, -0.81649625), (-0.47140425, 0.33333454, 0.81649625), (0, -1, 0)] (
            customData = {
                int64 HoudiniDataId = 29748
            }
            interpolation = "uniform"
        )
        uniform token orientation = "leftHanded"
        point3f[] points = [(0, 1, 0), (-0.9428103, -0.3333297, 0), (0.47140515, -0.3333297, 0.8164976), (0.47140515, -0.3333297, -0.8164976)] (
            customData = {
                int64 HoudiniDataId = 25469
            }
            interpolation = "vertex"
        )
        uniform token subdivisionScheme = "none"
        uniform token subsetFamily:shop_materialpath:familyType = "partition"

        def GeomSubset "shop_materialpath__mat_teal" (
            customData = {
                string partitionValue = "/mat/teal"
            }
        )
        {
            uniform token familyName = "shop_materialpath"
            int[] indices = [0, 1, 2, 3]
        }
    }

    def Xform "materials"
    {
        def Material "teal" (
            customData = {
                int64 HoudiniMaterialId = 2
                int HoudiniPrimEditorNodeId = 26
            }
        )
        {
            token outputs:karma:displacement.connect = </tetrahedron/materials/teal/teal_displace.outputs:displacement>
            token outputs:karma:surface.connect = </tetrahedron/materials/teal/teal_surface.outputs:surface>
            token outputs:surface.connect = </tetrahedron/materials/teal/teal_preview.outputs:surface>

            def Shader "teal_surface"
            {
                uniform token info:implementationSource = "sourceAsset"
                uniform asset info:sourceAsset = @opdef:/Vop/principledshader::2.0?SurfaceVexCode@
                vector3f inputs:basecolor = (0.075, 0.3, 0.1875)
                float inputs:ior = 1.447
                float inputs:rough = 0.19
                token outputs:surface
            }

            def Shader "teal_displace"
            {
                uniform token info:implementationSource = "sourceAsset"
                uniform asset info:sourceAsset = @opdef:/Vop/principledshader::2.0?DisplacementVexCode@
                token outputs:displacement
            }

            def Shader "teal_preview"
            {
                uniform token info:id = "UsdPreviewSurface"
                float inputs:clearcoatRoughness = 0
                color3f inputs:diffuseColor = (0.075, 0.3, 0.1875)
                float inputs:ior = 1.447
                float inputs:roughness = 0.19
                color3f inputs:specularColor = (0.075, 0.3, 0.1875)
                token outputs:surface
            }
        }
    }
}

def HoudiniLayerInfo "HoudiniLayerInfo" (
    customData = {
        string HoudiniCreatorNode = "/stage/tetrahedron/materiallibrary"
        string[] HoudiniEditorNodes = ["/stage/tetrahedron/materiallibrary", "/stage/tetrahedron/merge1", "/stage/tetrahedron/assignmaterial", "/stage/tetrahedron/xform"]
        string HoudiniSaveControl = "Placeholder"
    }
)
{
}
Edited by jsmack - 2019年12月24日 00:58:51
User Avatar
Member
23 posts
Joined: 8月 2019
Offline
Thanks so much @jsmack!

I noticed this feature only exists in “SOP Create”, not in “SOP Import”. Is there a reason / are there plans to add support for material imports with “SOP Import”?

Additionally, I see “Scene Import (All)” will import materials as “SOP Create” does, the primitives retain the primvars::shop_materialpathattributes but they don't get linked to the imported materials via UsdShade.

Is there a different intended workflow for this design?

Thanks!
User Avatar
Member
7747 posts
Joined: 9月 2011
Offline
SpeedOfLight
Thanks so much @jsmack!

I noticed this feature only exists in “SOP Create”, not in “SOP Import”. Is there a reason / are there plans to add support for material imports with “SOP Import”?

Sop Create is an HDA (Digital Asset) which combines the material library with a sop import. I would guess that no, it won't be coming to sop import unless they change the scope of it's functionality.

SpeedOfLight
Additionally, I see “Scene Import (All)” will import materials as “SOP Create” does, the primitives retain the primvars::shop_materialpathattributes but they don't get linked to the imported materials via UsdShade.

Is there a different intended workflow for this design?

Thanks!

The primvar is a red herring. All attributes are translated to usd primvars by default. It's simply a naive copy, and has nothing to do with the material bindings. I believe the Scene Import tool will preserve object level material bindings, but not SOP ones. The material section of the scene import can configure the scope of materials to translate to prims.
User Avatar
Member
66 posts
Joined: 2月 2017
Offline
Good thread! Would anyone have any pointers in how to use a wrangle to partition all USD “Mesh” primitives into “GeomSubset” primitives under the mesh? Recreating the ‘partitionattribs’ functionality of the ‘SOP Import’ LOP, but across all mesh objects on stage.

Going over the vex functions for USD now, but haven't cracked it yet. Thanks.

EDIT: Think I may have figured this out. Will update with solution after I make a solid example.
Edited by 9krausec - 2019年12月31日 12:57:51
User Avatar
スタッフ
1448 posts
Joined: 7月 2005
Offline
9krausec
Would anyone have any pointers in how to use a wrangle to partition all USD “Mesh” primitives into “GeomSubset”
There is also a Geometry Subset VOP LOP, with mode parameter set to “partition” and vex source to “vexpression”.
User Avatar
Member
66 posts
Joined: 2月 2017
Offline
Rafal, using Geometry Subset VOP LOP as you recommended was far more straightforward (and probably more efficient) than writing it all out in VEX. Got it working. Thank you, thank you.

My setup below for folks looking for this in the future -

Attached parameters.
Vex expression below,
string shop_materialpath[] = usd_attrib(0, @primpath, 'primvars:shop_materialpath');
string path = shop_materialpath[@elemnum];
string dir, name;
splitpath(path, dir, name);
return name;
Edited by 9krausec - 2019年12月31日 14:54:52

Attachments:
2019-12-31_13-50-03.jpg (51.2 KB)

User Avatar
Member
9 posts
Joined: 8月 2015
Offline
I noticed that SOP Create doesn't support material overrides: They don't get carried over, nor is another material with overrides created in UsdShade.
Are there plans to add material override support?
User Avatar
スタッフ
4438 posts
Joined: 7月 2005
Offline
That is not currently in the plan, no.
  • Quick Links