===============
Child Materials
===============

This page documents how child materials are imported into Katana through
:kat:node:`UsdIn` nodes.

To translate between USD's method of creating material inheritance to a format
compatible with Katana, we must alter the hierarchy from a structure of sibling
materials with a ``specializes`` arc to child materials.

Consider the following USD layer:

.. code-block:: none

    def "root"
    {
        def "materials"
        {
            def Material "metal"
            {
                color3f inputs:diffuseColor = (0.073087625, 0.073087625, 0.073087625)
                float inputs:metallic = 0.663
                float inputs:roughness = 0.432
                token outputs:glslfx:surface.connect = </root/root/materials/metal/UsdPreviewSurface.outputs:surface>

                def Shader "UsdPreviewSurface"
                {
                    uniform token info:id = "UsdPreviewSurface"
                    color3f inputs:diffuseColor = (0.073087625, 0.073087625, 0.073087625)
                    color3f inputs:diffuseColor.connect = </root/root/materials/metal.inputs:diffuseColor>
                    float inputs:metallic = 0.663
                    float inputs:metallic.connect = </root/root/materials/metal.inputs:metallic>
                    float inputs:roughness = 0.432
                    float inputs:roughness.connect = </root/root/materials/metal.inputs:roughness>
                    token outputs:surface
                    uniform token ui:nodegraph:node:expansionState = "open"
                    uniform float2 ui:nodegraph:node:pos = (-105, 114)
                }
            }

            def Material "metal_dull" (
                prepend apiSchemas = ["ChildMaterialAPI"]
                specializes = </root/root/materials/metal>
            )
            {
                float inputs:metallic = 0.872
                float inputs:roughness = 0.671
                uniform string katana:primName = "dull"
            }

            def Material "metal_dull_rusty" (
                prepend apiSchemas = ["ChildMaterialAPI"]
                specializes = </root/root/materials/metal_dull>
            )
            {
                color3f inputs:diffuseColor = (0.7265149, 0.22986107, 0.005717588)
                uniform string katana:primName = "rusty"
            }

            def Material "metal_shiny" (
                prepend apiSchemas = ["ChildMaterialAPI"]
                specializes = </root/root/materials/metal>
            )
            {
                float inputs:metallic = 0.845
                float inputs:roughness = 0.195
                uniform string katana:primName = "shiny"
            }
        }
    }

In this layer, a material ``metal_dull`` specializes parameters from
``metal`` through the ``specializes`` composition arc overriding the
``inputs:metallic`` and ``inputs:roughness`` parameter values to create a
different look while not affecting ``inputs:diffuse`` color. Similarly,
``metal_dull_rusty`` is another material which further modifies ``metal_dull``
to change the ``inputs:diffuse`` color to a slight orange, while retaining the
dullness from ``metal_dull``.

Katana uses a parent-child relationship for inheritance of attributes and their
values, which differs from the above example whereby siblings share parameters
through the ``specializes`` composition arc. In Katana, we would expect a
similarly functioning material hierarchy to be:

.. code-block:: none

    root
    └─ materials
       └─ metal
          ├─ dull
          │  └─ rusty
          └─ shiny

When this layer is imported through :kat:node:`UsdIn`, the hierarchy is altered
to move this derived Material to become a child of the material it specializes.
This only occurs under certain prim names. By default, this is: ``Looks``,
``looks`` or ``materials``. These prim names can be set manually though the
``USD_KATANA_LOOK_TOKENS`` environment variable (see
:ref:`usdin-environment-variable-options`).

Child Materials and UsdInIsolate
================================
The :kat:node:`UsdInIsolate` node type and the
:kat:node:`UsdIn`' **isolatePath** parameter isolate the prims of the USD stage
before the UsdIn node's Ops (In particular ``UsdInCore_LooksGroupOp``) can
reparent the child underneath the parent. For this reason, isolating a parent
material will not show the child material underneath, because at the USD stage,
this is still a sibling. Similarly, to isolate the child material, the full
path to the location in the USD file must be used, for example
``/root/materials/metal_shiny`` instead of ``/root/materials/metal/shiny.``