A Practical Guide to PxrLM

A Practical Guide to PxrLM

PxrLM: The Design Principles

Rather than providing a big, uber-style shader interface, the PxrLM material interface is designed to be simple without taking away any extensibility, flexibility, or robustness. By design, the materials provide the minimum set of parameters needed to create an amazing look. Each parameter is carefully included/tuned so that it allows us "to drive very fast but safe". The ability to have a super-fast turnaround times is critical in production, and the PxrLM materials are designed with that goal in mind.


PxrLM: The System

The PxrLM system is comprised of nodes can be divided into three categories:

Base Materials (Substrates)

A "substrate" is simply a base material. Although the following substrates have default material parameters tuned for creating a certain type of common material, by adjusting their material parameters we can use them to create other types of materials. PxrLM materials are not rigid, so they will not break if we change a metal material to a plastic material.

If the material you are looking for is not listed below, you can alter any of the existing substrates by adjusting its parameters, or you can write your own substrate based on the PxrLM substrate.

PxrLMDiffuse

A diffuse-only substrate. This provides a basic substrate that is used to build other material by adding the specular via PxrLMLayer.

images/pxrLM/PxrLMDiffuse.png

LMDiffuse with default settings, except a bluish Front Color.

The image below was created by modifying the default parameter settings to create a clay-like material:

images/pxrLM/PxrLMDiffuse_specLayer_clay.png
images/pxrLM/PxrLMDiffuse_clay1Graph.png

The Shading Graph

The image below was also created by modifying the default parameter settings to create a clay-like material, but with a color variation as well as specular roughness blending:

images/pxrLM/PxrLMDiffuse_specLayer_clay_specRoughnessDiff.png
images/pxrLM/PxrLMDiffuse_clay2Graph.png

The Shading Graph

PxrLMSubsurface

A subsurface base material. The specular and clearcoat are disabled by default.

images/pxrLM/PxrLMSubsurface.png

PxrLMSubsurface, using the out-of-the-box material defaults.

Though the default parameter settings are for the human skin, you could use PxrLMSubsurface to create any material with subsurface scattering, such as marble, or waxy cheese.

PxrLMMetal

A metallic base material. Presets are provided, so it is very easy to use PxrLMMetal to create, for example, the chrome-like material below.

images/pxrLM/PxrLMMetal.png

We can also use the Shading Tangent to create a brushed metal material, or add a layer of paint with PxrLMLayer:

images/pxrLM/PxrLMMetal_shadingTangent.png
images/pxrLM/PxrLMMetal_brushedMetalGraph.png

The brushed metal shading graph

images/pxrLM/PxrLMMetal_paintLayer.png
images/pxrLM/PxrLMMetal_paintOnMetalGraph.png

The paint-on-metal shading graph

PxrLMPlastic

A plastic substrate. It could be used for other types of materials.

images/pxrLM/PxrLMPlastic.png

PxrLMPlastic, default settings, except a green Diffuse Color

We can also use this plastic substrate to create a glowing material by setting its Incandescence color. In this example, we also turn off specular by setting the specular color to 0, since we may not want to see the specular response in the glowing material. Note that this is a "fake" emission.

images/pxrLM/PxrLMPlastic_incandescence.png
PxrLMGlass

PxrLMGlass is a glass-like base material. It can also be used for creating other refractive materials, such as a gelatin or translucent plastic.

Since this substrate uses refraction, it is important to increase the maximum specular depth. The image on the left below is produced with PxrLMGlass with the default parameters. Note that it is quite dark inside the teapot. This is because there is/are not enough specular depth/bounces specified. The image on the right shows the results when Specular Depth is increased to 6.

images/pxrLM/PxrLMGlass_noAttr.png

Default Settings

images/pxrLM/PxrLMGlass_withAttr.png

Specular Depth = 6

Changing the shadow to Thin makes the teapot's shadow to behave like a "thin" glass shadow, which allows more light to go through. We see the dark area at the base of the teapot went away. In this example, we also tint the reflection color for a more interesing look. Note that "thin" shadows are not physically accurate.

images/pxrLM/PxrLMGlass_thinShadow.png

We can make the glass refraction blurry by increasing the roughness, as seen in the image on the left, below. Note that the reflection is also blurry. We can sharpen the reflection but still keep the refraction blurry by using layers. If we add a PxrLMLayer and turn off the reflection coming from the substrate, we can set the reflection color to 0 in the substrate. We could improve the image by leaving some reflection color in the substrate so we are not seeing the dark in the image on the right, below.

images/pxrLM/PxrLMGlass_soft.png
images/pxrLM/PxrLMGlass_softRefr_sharpReflect.png

Material Layering

PxrLMLayer is optional. Use the PxrLMLayer only if you need to create a layer to override/modify the lobe(s) in the substrates. It is very important to know that PxrLMLayer is not additive to the base material. Instead, it blends with the base material's parameters. It is, technically, a Pattern node; there is only one Bxdf call using the blended parameters. A PxrLMLayer can be wired into another PxrLMLayer.

The images below show various uses for PxrLMLayer. In the image at left we are modifying the diffuse color; the layer mask is set to 1, so it completely overrides the diffuse color in the substrate. In the image at right we are disabling the layer by setting its mask to 0; this may be most useful for debugging purposes - note that it is a simple way to stop overriding the settings in the substrate.

images/pxrLM/PxrLMDiffuse_layerMask1.png

layerMask = 1

images/pxrLM/PxrLMDiffuse_layerMask0.png

layerMask = 0

The images below demonstrate using the mask to blend a layer with the substrate. The image on the left uses 20% from the layer, so we expect to see more contribution from the base layer. The image on the right uses 80%, so we see less contribution from the base layer.

images/pxrLM/PxrLMDiffuse_layerMaskpt2.png

layerMask = .2

images/pxrLM/PxrLMDiffuse_layerMaskpt8.png

layerMask = .8

The images below demonstrate using layers to override a lobe; in this case, we are overriding the specular. The image on the left shows the first layer, which has a rough specular (the diffuse color set to 0 so we can see what is going in the specular). In the image on the right we have a second layer with a sharper specular (and the specular behavior of the first layer is turned off, so we're only seeing the specular lobe of the second layer).

images/pxrLM/PxrLMDiffuse_layer_bigSpecRough.png
images/pxrLM/PxrLMDiffuse_layer_smallSpecRough.png

Now, when the layer mask is set to 1 for both layers, as in the image below, we see that the top layer wins.

images/pxrLM/PxrLMDiffuse_layer_smallSpecRough.png

Layers and Bumps

The images below show using a layer to override the diffuse bump.

images/pxrLM/PxrLMDiffuse_baseBump.png

PxrLMDiffuse with Diffuse Bump

images/pxrLM/PxrLMDiffuse_layer1Bump.png

PxrLMLayer with A Different Diffuse Bump

images/pxrLM/PxrLMDiffuse_layerMask.png

Layer Mask for PxrLMLayer

images/pxrLM/PxrLMDiffuse_withLayer1Bump.png

PxrLMDiffuse with PxrLMLayer Bump

images/pxrLM/PxrLMDiffuse_layerBumpGraph.png

The Shading Graph


Layer Combining

PxrLMMixer can be used for combining layers. If you have more than one PxrLMLayer, you can use either a PxrLMMixer to combine them. Parameters are combined from the top input down. Each PxrLMMixer supports up to five layers, but, like PxrLMLayer, the Mixer nodes can be nested to support combining additional layers.



Appendices: RIB Examples

PxrLMDiffuse Examples

images/pxrLM/PxrLMDiffuse.png

LMDiffuse with default settings, except a bluish Front Color.

RIB Declaration:

# Using default settings with a different frontColor
  Bxdf "PxrLMDiffuse" "diffuseOnlyMaterial" "color frontColor" [0.00062709 0.153578 0.337242]
images/pxrLM/PxrLMDiffuse_specLayer_clay.png

Clay

RIB Declaration:

# Displacement bound and turn on trace displacement
Attribute "displacementbound" "constant float sphere" [0.5]
Attribute "trace" "constant int displacements" [1]

# specular only layer
Pattern "PxrLMLayer" "claySpec_PxrLMLayer" "int diffuseBehavior" [0]
        "color specularColor" [0.1 0.1 0.1] "float specularRoughness" [0.2]
        "color specularEta" [1.553 1.553 1.553]

# fractal for clay color mix
Pattern "PxrFractal" "clay_PxrFractal" "float frequency" [1]
Pattern "PxrMix" "clayColor_PxrMix" "color color1" [0.528296 0.187493 0.0699699]
        "color color2" [0.551763 0.195495 0.0728056]
        "reference float mix" ["clay_PxrFractal:resultF"]

# diffuse only bxdf
Bxdf "PxrLMDiffuse" "clay_PxrLMDiffuse"
     "reference struct lmlayer" ["claySpec_PxrLMLayer:result"]
     "reference color frontColor" ["clayColor_PxrMix:resultRGB"]

# clay displacement
  Displacement "RMSDisplacement" "uniform float displacementAmount" [0.02]
               "uniform float displacementCenter" [0]
               "reference float displacementScalar"
               ["clay_fractal:resultF"]
images/pxrLM/PxrLMDiffuse_specLayer_clay_specRoughnessDiff.png

Clay With Color/Specular Variation

RIB Declaration:

# Displacement bound and turn on trace displacement
Attribute "displacementbound" "constant float sphere" [0.5]
Attribute "trace" "constant int displacements" [1]

# clay color manifold
Pattern "PxrManifold2D" "clayColor_PxrManifold2D"
        "float scaleS" [1] "float scaleT" [10]
Pattern "PxrFractal" "clayDisp_PxrFractal" "float frequency" [1]
Pattern "PxrFractal" "clayColor_PxrFractal" "float frequency" [1]
        "reference struct manifold" ["clayColor_PxrManifold2D:result"]

# clay specular blend
Pattern "PxrBlend" "claySpecRoughness_PxrBlend"
        "int operation" [10]
        "color topRGB" [0.05 0.05 0.05]
        "color bottomRGB" [0.2 0.2 0.2]
        "reference float topA" ["clayColor_PxrFractal:resultF"]

# clay color mix
Pattern "PxrMix" "clayColor_PxrMix"
        "color color1" [0.528296 0.187493 0.0699699]
        "color color2" [0.800144 0.391712 0.218277]
        "reference float mix" ["clayColor_PxrFractal:resultF"]

# specular only layer
Pattern "PxrLMLayer" "claySpec_PxrLMLayer" "int diffuseBehavior" [0]
        "color specularColor" [0.1 0.1 0.1]
        "reference float specularRoughness" ["claySpecRoughness_PxrBlend:resultR"]
        "color specularEta" [1.553 1.553 1.553]

# clay Bxdf
Bxdf "PxrLMDiffuse" "clay_PxrLMDiffuse"
     "reference struct lmlayer" ["claySpec_PxrLMLayer:result"]
     "reference color frontColor" ["clayColor_PxrMix:resultRGB"]

# clay displacement
Displacement "RMSDisplacement" "uniform float displacementAmount" [0.02]
             "uniform float displacementCenter" [0]
             "reference float displacementScalar" ["clayDisp_PxrFractal:resultF"]

PxrLMSubsurface Example

images/pxrLM/PxrLMSubsurface.png

PxrLMSubsurface

RIB Declaration:

Bxdf "PxrLMSubsurface" "subsurfaceMaterial"

PxrLMMetal Examples

images/pxrLM/PxrLMMetal.png

Chrome

RIB Declaration:

Bxdf "PxrLMMetal" "chrome"
images/pxrLM/PxrLMMetal_shadingTangent.png

Brushed Metal

RIB Declaration:

Pattern "PxrManifold2D" "rotationAngleVector_PxrManifold2D"
        "float scaleS" [20] "float scaleT" [20]
Pattern "PxrTexture" "rotationAngleVector_PxrTexture"
        "string filename" ["aniso_vec_circles.tex"]
        "reference struct manifold" ["rotationAngleVector_PxrManifold2D:result"]
Pattern "PxrTangentField" "brushedMetal_PxrTangentField"
        "reference color inputVector" ["rotationAngleVector_PxrTexture:resultRGB"]
Bxdf "PxrLMMetal" "brushedMetal_PxrLMMetal" "color eta" [2.36763 1.66336 1.46706]
     "color kappa" [4.49884 3.05016 2.34543]
     "float roughness" [0.5]
     "float anisotropy" [-0.99]
     "color specularColor" [0.902094 0.462061 0.321606]
     "reference vector shadingTangent" ["brushedMetal_PxrTangentField:resultXYZ"]
images/pxrLM/PxrLMMetal_paintLayer.png

Paint on Chrome

RIB Declaration:

Pattern "PxrManifold3D" "flake_PxrManifold3D" "float scale" [0.5]
Pattern "PxrFlakes" "metalPaintMask_PxrFlakes" "float flakeFreq" [5]
        "float size" [1] "reference struct manifold" ["flake_PxrManifold3D:result"]
Pattern "PxrLMLayer" "paintLayer_PxrLMLayer"
        "color diffuseColor" [0.00217329 0.0204367 0.971155]
        "color specularColor" [0.645431 0.71656 0.996728]
        "float specularRoughness" [0.15]
        "reference float layerMask" ["metalPaintMask_PxrFlakes:resultA"]
        "reference normal diffuseNn" ["metalPaintMask_PxrFlakes:resultN"]
        "reference normal specularNn" ["metalPaintMask_PxrFlakes:resultN"]
Bxdf "PxrLMMetal" "paintOnMetal" "reference struct lmlayer" ["paintLayer_PxrLMLayer:result"]

PxrLMPlastic Examples

images/pxrLM/PxrLMPlastic.png

Green Plastic

RIB Declaration:

Bxdf "PxrLMPlastic" "plastic" "color diffuseColor" [0.000952557 0.139168 0.00209999]
images/pxrLM/PxrLMPlastic_incandescence.png

Plastic what glows...

RIB Declaration:

Bxdf "PxrLMPlastic" "plastic" "reference color incandescence" ["emissive_PxrExposure:resultRGB"]
     "color specularColor" [0 0 0]

PxrLMGlass Examples

images/pxrLM/PxrLMGlass_noAttr.png

Default Glass

RIB Declaration:

Bxdf "PxrLMGlass" "glass"
images/pxrLM/PxrLMGlass_withAttr.png

Glass with Specular Depth = 6

RIB Declaration:

Attribute "trace" "constant int maxspeculardepth" [6]
Attribute "visibility" "constant int transmission" [1] "constant int indirect" [1]
Bxdf "PxrLMGlass" "glass"
images/pxrLM/PxrLMGlass_thinShadow.png

"Thin" Glass

RIB Declaration:

Attribute "trace" "constant int maxspeculardepth" [6]
Attribute "visibility" "constant int transmission" [1] "constant int indirect" [1]
Bxdf "PxrLMGlass" "glass" "color reflectionColor" [0.4891 0.7303 0.7759]
     "color refractionColor" [0.9 0.9 0.9]
     "int shadows" [1]
images/pxrLM/PxrLMGlass_soft.png

Glass with Blurred Refraction

RIB Declaration:

Attribute "trace" "constant int maxspeculardepth" [6]
Attribute "visibility" "constant int transmission" [1] "constant int indirect" [1]
Bxdf "PxrLMGlass" "glass" "color reflectionColor" [0.4891 0.7303 0.7759]
     "color refractionColor" [0.9 0.9 0.9]
     "int shadows" [1]
     "float roughness" [0.3]
images/pxrLM/PxrLMGlass_softRefr_sharpReflect.png

Glass with Blurred Refraction, Sharp Reflection

RIB Declaration:

Attribute "trace" "constant int maxspeculardepth" [6]
Attribute "visibility" "constant int transmission" [1] "constant int indirect" [1]
Pattern "PxrLMLayer" "sharpReflection" "int diffuseBehavior" [0]
        "int clearcoatBehavior" [0]
        "int specularBehavior" [1]
        "float specularRoughness" [0.01]
Bxdf "PxrLMGlass" "glass" "color reflectionColor" [0 0 0]
     "color refractionColor" [0.963798 0.0301911 0.0637397]
     "float roughness" [0.2]
     "reference struct lmlayer" ["sharpReflection_PxrLMLayer:result"]

PxrLMLayer Examples

images/pxrLM/PxrLMDiffuse_layerMask1.png

PxrLMLayer with layerMask = 1

RIB Declaration:

Pattern "PxrLMLayer" "overrideDiffuse" "color diffuseColor" [0 0.5 0.5]
        "int specularBehavior" [0]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0.5 0 0]
     "reference struct lmlayer" ["overrideDiffuse:result"]
images/pxrLM/PxrLMDiffuse_layerMask0.png

PxrLMLayer with layerMask = 0

RIB Declaration:

Pattern "PxrLMLayer" "overrideDiffuse" "float layerMask" [0]
        "color diffuseColor" [0 0.5 0.5] "int specularBehavior" [0]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0.5 0 0]
     "reference struct lmlayer" ["overrideDiffuse:result"]
images/pxrLM/PxrLMDiffuse_layerMaskpt2.png

layerMask = .2 (20% of the layer is blended with the substrate)

RIB Declaration:

Pattern "PxrLMLayer" "overrideDiffuse" "float layerMask" [0.2]
        "color diffuseColor" [0 0.5 0.5] "int specularBehavior" [0]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0.5 0 0]
     "reference struct lmlayer" ["overrideDiffuse:result"]
images/pxrLM/PxrLMDiffuse_layerMaskpt8.png

layerMask = .8 (80% of the layer is blended with the substrate)

RIB Declaration:

Pattern "PxrLMLayer" "overrideDiffuse" "float layerMask" [0.8]
        "color diffuseColor" [0 0.5 0.5] "int specularBehavior" [0]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0.5 0 0]
     "reference struct lmlayer" ["overrideDiffuse:result"]
images/pxrLM/PxrLMDiffuse_layer_bigSpecRough.png

A layered material: the layer adds a rough specular, but no diffuse contribution

RIB Declaration:

Pattern "PxrLMLayer" "overrideSpec1" "int diffuseBehavior" [0]
        "int specularBehavior" [1] "color specularColor" [1 0 0]
        "float specularRoughness" [0.3]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0 0 0]
     "color backColor" [0 0 0] "reference struct lmlayer" ["overrideSpec1:result"]
images/pxrLM/PxrLMDiffuse_layer_smallSpecRough.png

The same material as above, with a second layer that adds a sharp specular

RIB Declaration:

Pattern "PxrLMLayer" "overrideSpec2" "int diffuseBehavior" [0]
        "int specularBehavior" [1] "color specularColor" [0 1 0]
        "float specularRoughness" [0.05]
Pattern "PxrLMLayer" "overrideSpec1" "int diffuseBehavior" [0]
        "int specularBehavior" [0] "color specularColor" [1 0 0]
        "float specularRoughness" [0.3] "reference struct lmlayer" ["overrideSpec2:result"]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0 0 0]
     "color backColor" [0 0 0] "reference struct lmlayer" ["overrideSpec1:result"]
images/pxrLM/PxrLMDiffuse_layer_smallSpecRough.png

The same material, with the layerMask = 1 for both layers - Top Layer Wins!

RIB Declaration:

Pattern "PxrLMLayer" "overrideSpec2" "int diffuseBehavior" [0]
        "int specularBehavior" [1] "color specularColor" [0 1 0]
        "float specularRoughness" [0.05]
Pattern "PxrLMLayer" "overrideSpec1" "int diffuseBehavior" [0]
        "int specularBehavior" [1] "color specularColor" [1 0 0]
        "float specularRoughness" [0.3] "reference struct lmlayer" ["overrideSpec2:result"]
Bxdf "PxrLMDiffuse" "layerMaterial" "color frontColor" [0 0 0]
     "color backColor" [0 0 0] "reference struct lmlayer" ["overrideSpec1:result"]