Skip to content

Commit

Permalink
Initial implementation of Disney Principled (#2004)
Browse files Browse the repository at this point in the history
This changelist adds an initial MaterialX graph for the Disney Principled BSDF, as described in Brent Burley's 2012 and 2015 presentations.

For simplicity, the original separated interfaces for `disney_brdf_2012` and `disney_bsdf_2015` have been merged into a single `disney_principled` interface, providing artists with a unified entry point for the shading model.

Where possible, the original empirical approach of Disney Principled has been preserved, including the use of the `burley_diffuse_bsdf` and `generalized_schlick_bsdf` nodes, though a few simplifications have been employed, including the use of the `layer` node for physically based layering and the `sheen_bsdf` node for the sheen layer.
  • Loading branch information
jstone-lucasfilm authored Sep 7, 2024
1 parent 81e3e24 commit 093b819
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 35 deletions.
10 changes: 10 additions & 0 deletions documents/Specification/MaterialX.PBRSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,14 @@ Note that the standard library includes definitions for [**`displacement`**](./M
This section contains examples of shading model implementations using the MaterialX PBS library. For all examples, the shading model is defined via a <nodedef> interface plus a nodegraph implementation. The resulting nodes can be used as shaders by a MaterialX material definition.


## Disney Principled BSDF

This shading model was presented by Brent Burley from Walt Disney Animation Studios in 2012[^Burley2012], with additional refinements presented in 2015[^Burley2015].

A MaterialX definition and nodegraph implementation of the Disney Principled BSDF can be found here:
[https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/bxdf/disney_principled.mtlx](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/bxdf/disney_principled.mtlx)


## Autodesk Standard Surface

This is a surface shading model used in Autodesk products created by the Solid Angle team for the Arnold renderer. It is an über shader built from ten different BSDF layers[^Georgiev2019].
Expand Down Expand Up @@ -430,6 +438,8 @@ The MaterialX PBS Library includes a number of nodegraphs that can be used to ap

[^Burley2012]: Brent Burley, **Physically-Based Shading at Disney**, <https://media.disneyanimation.com/uploads/production/publication_asset/48/asset/s2012_pbs_disney_brdf_notes_v3.pdf>, 2012

[^Burley2015]: Brent Burley, **Extending the Disney BRDF to a BSDF with Integrated Subsurface Scattering**, <https://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf>, 2015

[^Christensen2015]: Per H. Christensen, Brent Burley, **Approximate Reflectance Profiles for Efficient Subsurface Scattering**, <http://graphics.pixar.com/library/ApproxBSSRDF/> 2015

[^Conty2017]: Alejandro Conty, Christopher Kulla, **Production Friendly Microfacet Sheen BRDF**, <https://fpsunflower.github.io/ckulla/data/s2017_pbs_imageworks_sheen.pdf>, 2017
Expand Down
4 changes: 1 addition & 3 deletions documents/Specification/MaterialX.Specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -2387,7 +2387,7 @@ Custom nodes that output data types with a "shader" semantic are referred to in
The attributes for &lt;nodedef> elements as they pertain to the declaration of shaders are:

* `name` (string, required): a user-chosen name for this shader node definition element.
* `node` (string, required): the name of the shader node being defined, which typically matches the name of an associated shader function such as “blinn_phong”, “Disney_BRDF_2012”, “volumecloud_vol”. Just as for custom nodes, this shading program may be defined precisely through an &lt;implementation> or &lt;nodegraph>, or left to the application to locate by name using any shader definition method that it chooses.
* `node` (string, required): the name of the shader node being defined, which typically matches the name of an associated shader function such as “blinn_phong”, “disney_principled”, “volumecloud_vol”. Just as for custom nodes, this shading program may be defined precisely through an &lt;implementation> or &lt;nodegraph>, or left to the application to locate by name using any shader definition method that it chooses.

The child &lt;output> element within the &lt;nodedef> defines the "data type" of the output for this shader, which must have been defined with a "shader" semantic; see the [Custom Data Types](#custom-data-types) section above and discussion below for details.

Expand Down Expand Up @@ -2707,8 +2707,6 @@ Example uses for variants include defining a number of allowable colors and text
Variants and variantsets are not intrinsically associated with any particular material; they merely state a number of values for a number of named inputs/tokens. However, variantsets may state that they are associated with specific shader-semantic nodes and/or &lt;nodedef> declarations by providing stringarray-type `node` and/or `nodedef` attributes:

```xml
<variantset name="damagevars" node="Disney_BRDF_2012,Disney_BRDF_2015">
...
<variantset name="costumevars" nodedef="ND_unifiedsrf_studio">
...
```
Expand Down
25 changes: 0 additions & 25 deletions libraries/bxdf/disney_brdf_2015.mtlx

This file was deleted.

140 changes: 140 additions & 0 deletions libraries/bxdf/disney_principled.mtlx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">

<nodedef name="ND_disney_principled" node="disney_principled" nodegroup="pbr" doc="The Disney Principled BSDF">
<input name="baseColor" type="color3" value="0.16, 0.16, 0.16" uiname="Base Color" uifolder="Base" />
<input name="metallic" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Metallic" uifolder="Base" />
<input name="roughness" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Roughness" uifolder="Base" />
<input name="anisotropic" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Anisotropic" uifolder="Specular" />
<input name="specular" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Specular" uifolder="Specular" />
<input name="specularTint" type="float" value="0" uimin="0.0" uimax="1.0" uiname="Specular Tint" uifolder="Specular" />
<input name="sheen" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Sheen" uifolder="Sheen" />
<input name="sheenTint" type="float" value="0.5" uimin="0.0" uimax="1.0" uiname="Sheen Tint" uifolder="Sheen" />
<input name="clearcoat" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Clearcoat" uifolder="Clearcoat" />
<input name="clearcoatGloss" type="float" value="1.0" uimin="0.0" uimax="1.0" uiname="Clearcoat Gloss" uifolder="Clearcoat" />
<input name="specTrans" type="float" value="0.0" uimin="0.0" uimax="1.0" uiname="Spec Trans" uifolder="Transmission" />
<input name="ior" type="float" value="1.5" uisoftmin="1.0" uisoftmax="3.0" uiname="IOR" uifolder="Transmission" />
<input name="subsurface" type="float" value="0.0" uiname="Subsurface" uifolder="Subsurface" />
<input name="subsurfaceDistance" type="color3" value="1.0, 1.0, 1.0" uiname="Subsurface Distance" uifolder="Subsurface" />
<output name="out" type="surfaceshader" />
</nodedef>

<nodegraph name="NG_disney_principled" nodedef="ND_disney_principled">

<!-- Diffuse Layer -->
<invert name="invert_metalness" type="float">
<input name="in" type="float" interfacename="metallic" />
</invert>
<burley_diffuse_bsdf name="diffuse_bsdf" type="BSDF">
<input name="weight" type="float" nodename="invert_metalness" />
<input name="color" type="color3" interfacename="baseColor" />
<input name="roughness" type="float" interfacename="roughness" />
</burley_diffuse_bsdf>

<!-- Subsurface Layer -->
<subsurface_bsdf name="subsurface_bsdf" type="BSDF">
<input name="color" type="color3" interfacename="baseColor" />
<input name="radius" type="color3" interfacename="subsurfaceDistance" />
</subsurface_bsdf>
<mix name="subsurface_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="diffuse_bsdf" />
<input name="fg" type="BSDF" nodename="subsurface_bsdf" />
<input name="mix" type="float" interfacename="subsurface" />
</mix>

<!-- Sheen Layer -->
<mix name="sheen_color" type="color3">
<input name="bg" type="color3" value="1, 1, 1" />
<input name="fg" type="color3" interfacename="baseColor" />
<input name="mix" type="float" interfacename="sheenTint" />
</mix>
<sheen_bsdf name="sheen_bsdf" type="BSDF">
<input name="weight" type="float" interfacename="sheen" />
<input name="color" type="color3" nodename="sheen_color" />
</sheen_bsdf>
<layer name="sheen_layer" type="BSDF">
<input name="top" type="BSDF" nodename="sheen_bsdf" />
<input name="base" type="BSDF" nodename="subsurface_mix" />
</layer>

<!-- Transmission Layer -->
<dielectric_bsdf name="transmission_bsdf" type="BSDF">
<input name="tint" type="color3" interfacename="baseColor" />
<input name="ior" type="float" interfacename="ior" />
<input name="roughness" type="vector2" value="0.0, 0.0" />
<input name="scatter_mode" type="string" value="T" />
</dielectric_bsdf>
<mix name="transmission_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="sheen_layer" />
<input name="fg" type="BSDF" nodename="transmission_bsdf" />
<input name="mix" type="float" interfacename="specTrans" />
</mix>

<!-- Dielectric Layer -->
<roughness_anisotropy name="specular_roughness" type="vector2">
<input name="roughness" type="float" interfacename="roughness" />
<input name="anisotropy" type="float" interfacename="anisotropic" />
</roughness_anisotropy>
<multiply name="dielectric_intensity" type="float">
<input name="in1" type="float" interfacename="specular" />
<input name="in2" type="float" value="0.08" />
</multiply>
<mix name="dielectric_tint" type="color3">
<input name="bg" type="color3" value="1, 1, 1" />
<input name="fg" type="color3" interfacename="baseColor" />
<input name="mix" type="float" interfacename="specularTint" />
</mix>
<generalized_schlick_bsdf name="dielectric_bsdf" type="BSDF">
<input name="weight" type="float" nodename="dielectric_intensity" />
<input name="color0" type="color3" nodename="dielectric_tint" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
</generalized_schlick_bsdf>
<layer name="dielectric_layer" type="BSDF">
<input name="top" type="BSDF" nodename="dielectric_bsdf" />
<input name="base" type="BSDF" nodename="transmission_mix" />
</layer>

<!-- Metallic Layer -->
<generalized_schlick_bsdf name="metallic_bsdf" type="BSDF">
<input name="color0" type="color3" interfacename="baseColor" />
<input name="roughness" type="vector2" nodename="specular_roughness" />
</generalized_schlick_bsdf>
<mix name="metallic_mix" type="BSDF">
<input name="bg" type="BSDF" nodename="dielectric_layer" />
<input name="fg" type="BSDF" nodename="metallic_bsdf" />
<input name="mix" type="float" interfacename="metallic" />
</mix>

<!-- Coat Layer -->
<multiply name="coat_intensity" type="float">
<input name="in1" type="float" interfacename="clearcoat" />
<input name="in2" type="float" value="0.04" />
</multiply>
<invert name="coat_roughness" type="float">
<input name="in" type="float" interfacename="clearcoatGloss" />
</invert>
<convert name="coat_roughness_vector" type="vector2">
<input name="in" type="float" nodename="coat_roughness" />
</convert>
<roughness_dual name="coat_roughness_dual" type="vector2">
<input name="roughness" type="vector2" nodename="coat_roughness_vector" />
</roughness_dual>
<generalized_schlick_bsdf name="coat_bsdf" type="BSDF">
<input name="weight" type="float" nodename="coat_intensity" />
<input name="roughness" type="vector2" nodename="coat_roughness_dual" />
</generalized_schlick_bsdf>
<layer name="coat_layer" type="BSDF">
<input name="top" type="BSDF" nodename="coat_bsdf" />
<input name="base" type="BSDF" nodename="metallic_mix" />
</layer>

<!-- Surface Constructor -->
<surface name="surface_constructor" type="surfaceshader">
<input name="bsdf" type="BSDF" nodename="coat_layer" />
</surface>

<!-- Output -->
<output name="out" type="surfaceshader" nodename="surface_constructor" />
</nodegraph>

</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">
<disney_principled name="SR_carpaint" type="surfaceshader">
<input name="baseColor" type="color3" value="0.0518895, 0.29606, 0.425324" />
<input name="roughness" type="float" value="0.4" />
<input name="anisotropic" type="float" value="0.5" />
<input name="clearcoat" type="float" value="1.0" />
</disney_principled>
<surfacematerial name="DisneyPrincipled_Carpaint" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="SR_carpaint" />
</surfacematerial>
</materialx>
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">
<nodedef name="ND_disney_brdf_2012_surface" node="disney_brdf_2012" nodegroup="pbr">
<disney_principled name="SR_default" type="surfaceshader">
<input name="baseColor" type="color3" value="0.16, 0.16, 0.16" />
<input name="metallic" type="float" value="0" />
<input name="subsurface" type="float" value="0" />
<input name="specular" type="float" value="0.5" />
<input name="roughness" type="float" value="0.5" />
<input name="specularTint" type="float" value="0" />
<input name="anisotropic" type="float" value="0" />
<input name="specularTint" type="float" value="0" />
<input name="sheen" type="float" value="0" />
<input name="sheenTint" type="float" value="0.5" />
<input name="clearcoat" type="float" value="0" />
<input name="clearcoatGloss" type="float" value="1" />
<output name="out" type="surfaceshader" />
</nodedef>
<implementation name="IM_disney_brdf_2012_surface_brdf_explorer" nodedef="ND_disney_brdf_2012_surface" target="brdf_explorer" file="https://github.com/wdas/brdf/blob/master/src/brdfs/disney.brdf" />
<input name="specTrans" type="float" value="0" />
<input name="ior" type="float" value="1.5" />
<input name="subsurface" type="float" value="0" />
<input name="subsurfaceDistance" type="color3" value="1, 1, 1" />
</disney_principled>
<surfacematerial name="DisneyPrincipled_Default" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="SR_default" />
</surfacematerial>
</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">
<disney_principled name="SR_glass" type="surfaceshader">
<input name="baseColor" type="color3" value="1, 1, 1" />
<input name="roughness" type="float" value="0.01" />
<input name="specTrans" type="float" value="1" />
<input name="ior" type="float" value="1.52" />
</disney_principled>
<surfacematerial name="DisneyPrincipled_Glass" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="SR_glass" />
</surfacematerial>
</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">
<disney_principled name="SR_gold" type="surfaceshader">
<input name="baseColor" type="color3" value="0.944, 0.776, 0.373" />
<input name="metallic" type="float" value="1" />
<input name="roughness" type="float" value="0.02" />
</disney_principled>
<surfacematerial name="DisneyPrincipled_Gold" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="SR_gold" />
</surfacematerial>
</materialx>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<materialx version="1.39" colorspace="lin_rec709">
<disney_principled name="SR_plastic" type="surfaceshader">
<input name="baseColor" type="color3" value="0.104704, 0.241883, 0.818" />
<input name="roughness" type="float" value="0.324675" />
</disney_principled>
<surfacematerial name="DisneyPrincipled_Plastic" type="material">
<input name="surfaceshader" type="surfaceshader" nodename="SR_plastic" />
</surfacematerial>
</materialx>

0 comments on commit 093b819

Please sign in to comment.