To guarantee a non-ambiguous way to transport and present the model across different tools, for each parameter we specify in the following table:
- Identifier: its unique identifier string (used in the formal description of the material, and in code).
- Label: a suggested, non-unique UI name, where parameter grouping for UI purposes can be inferred based on the common identifier prefix.
-
Type: one of
float,boolean,color3,vector3. Acolor3value is associated with a color space (ACEScg by default), while avector3value is a raw 3-component vector. -
Range: the allowed value range for scalar parameters (per-channel for color and vector parameters).
- Square brackets
$[]$ indicate a range the value must be within.- Parenthesis
$()$ indicate bounds are excluded from that range.
- Parenthesis
- Curly brackets
{}indicate a discrete set of possible values.
- Square brackets
-
Norm: when the range of possible values differs from the range of typically useful values, the latter is indicated in this column. For example, a
specular_iorcan take arbitrarily high values, but a refractive index of 3 is considered a very high value already, above that of diamond. - Default: the suggested default value.
-
Unit: where relevant, otherwise assumed to be dimensionless. Note that lengths (other than
thin_film_thickness) can be assumed to be in the world space units of the scene.
| Identifier | Label | Type | Range | Norm | Default | Unit |
|---|---|---|---|---|---|---|
| Base | ||||||
base_weight |
Weight | float |
$ [0, 1] $ | $ 1 $ | ||
base_color |
Color | color3 |
$ [0, 1]^3 $ | $ (0.8, 0.8, 0.8) $ | ||
base_metalness |
Metalness | float |
$ [0, 1] $ | $ 0 $ | ||
base_diffuse_roughness |
Diffuse Roughness | float |
$ [0, 1] $ | $ 0 $ | ||
| Specular | ||||||
specular_weight |
Weight | float |
$ [0, \infty) $ | $ [0, 1] $ | $ 1 $ | |
specular_color |
Color | color3 |
$ [0, 1]^3 $ | $ (1, 1, 1) $ | ||
specular_roughness |
Roughness | float |
$ [0, 1] $ | $ 0.3 $ | ||
specular_roughness_anisotropy |
Anisotropy | float |
$ [0, 1] $ | $ 0 $ | ||
specular_ior |
IOR | float |
$ (0, \infty) $ | $ [1, 3] $ | $ 1.5 $ | |
| Transmission | ||||||
transmission_weight |
Weight | float |
$ [0, 1] $ | $ 0 $ | ||
transmission_color |
Color | color3 |
$ [0, 1]^3 $ | $ (1, 1, 1) $ | ||
transmission_depth |
Depth | float |
$ [0, \infty) $ | $ [0, 1] $ | $ 0 $ | length |
transmission_scatter |
Scatter | color3 |
$ [0, 1]^3 $ | $ (0, 0, 0) $ | ||
transmission_scatter_anisotropy |
Anisotropy | float |
$ [-1, 1] $ | $ 0 $ | ||
transmission_dispersion_scale |
Dispersion scale | float |
$ [0, 1] $ | $ 0 $ | ||
transmission_dispersion_abbe_number |
Abbe number | float |
$ (0, \infty) $ | $ [9, 91] $ | $ 20 $ | |
| Subsurface | ||||||
subsurface_weight |
Weight | float |
$ [0, 1] $ | $ 0 $ | ||
subsurface_color |
Color | color3 |
$ [0, 1] $ | $ (0.8, 0.8, 0.8) $ | ||
subsurface_radius |
Radius | float |
$ [0, \infty) $ | $ [0, 1] $ | $ 1 $ | length |
subsurface_radius_scale |
Radius scale | color3 |
$ [0, 1]^3 $ | $ (1.0, 0.5, 0.25) $ | ||
subsurface_scatter_anisotropy |
Anisotropy | float |
$ [-1, 1] $ | $ 0 $ | ||
| Coat | ||||||
coat_weight |
Weight | float |
$ [0, 1] $ | $ 0 $ | ||
coat_color |
Color | color3 |
$ [0, 1]^3 $ | $ (1, 1, 1) $ | ||
coat_roughness |
Roughness | float |
$ [0, 1] $ | $ 0 $ | ||
coat_roughness_anisotropy |
Anisotropy | float |
$ [0, 1] $ | $ 0 $ | ||
coat_ior |
IOR | float |
$ (0, \infty) $ | $ [1, 3] $ | $ 1.6 $ | |
coat_darkening |
Darkening | float |
$ [0, 1] $ | $ 1 $ | ||
| Fuzz | ||||||
fuzz_weight |
Weight | float |
$ [0, 1] $ | $ 0 $ | ||
fuzz_color |
Color | color3 |
$ [0, 1]^3 $ | $ (1, 1, 1) $ | ||
fuzz_roughness |
Roughness | float |
$ [0, 1] $ | $ 0.5 $ | ||
| Emission | ||||||
emission_luminance |
Luminance | float |
$ [0, \infty) $ | $ [0, 1000] $ | $ 0 $ | nits |
emission_color |
Color | color3 |
$ [0, 1]^3 $ | $ (1, 1, 1) $ | ||
| Thin-film | ||||||
thin_film_weight |
Weight | float |
$ [0, 1] $ | $ 0 $ | ||
thin_film_thickness |
Thickness | float |
$ [0, \infty) $ | $ [0, 1] $ | $ 0.5 $ | |
thin_film_ior |
IOR | float |
$ (0, \infty) $ | $ [1, 3] $ | $ 1.4 $ | |
| Geometry | ||||||
geometry_opacity |
Opacity | float |
$ [0, 1] $ | $ 1 $ | ||
geometry_thin_walled |
Thin walled | boolean |
{false, true} | false | ||
geometry_normal |
Normal | vector3 |
N/A | unperturbed normal | ||
geometry_tangent |
Tangent | vector3 |
N/A | unperturbed tangent | ||
geometry_coat_normal |
Coat Normal | vector3 |
N/A | unperturbed normal | ||
geometry_coat_tangent |
Coat Tangent | vector3 |
N/A | unperturbed tangent |
The structure of the OpenPBR tree of layer and mix operations implies that some parameters have no effect if other parameters take certain values. It can be a helpful cue for artists if the UI design for the shader reflects this by disabling (e.g. greying out) those controls which are irrelevant in the current context.
To facilitate this aspect of the UI design, we provide here in Python pseudocode form the recommended logic needed to determine which of the parameters can be disabled. This employs a function disable(P, skip=[]) where the arguments P and the optional skip are a prefix string (or list of prefix strings). Then all parameters with names matching any of the prefixes in P should be disabled, except for those matching any in skip.
has_fuzz = (fuzz_weight > 0.0)
has_coat = (coat_weight > 0.0)
has_metal = (base_metalness > 0.0)
has_dielectric = (base_metalness < 1.0)
has_dielectric_transp = has_dielectric and (transmission_weight > 0.0)
has_dielectric_opaque = has_dielectric and (transmission_weight < 1.0)
has_subsurface = has_dielectric_opaque and (subsurface_weight > 0.0)
has_diffuse = has_dielectric_opaque and (subsurface_weight < 1.0)
if not has_fuzz: disable("fuzz", skip="fuzz_weight")
if not has_coat:
disable("coat", skip="coat_weight")
disable("geometry_coat_tangent")
if not has_dielectric: disable("specular_ior")
if not has_dielectric_transp: disable("transmission", skip="transmission_weight")
if (not has_diffuse and not has_metal): disable(["base_weight", "base_color"])
if not has_subsurface: disable("subsurface", skip="subsurface_weight")
if not has_diffuse: disable("base_diffuse_roughness")
if (specular_weight == 0): disable("specular", skip="specular_weight")
if (thin_film_weight == 0): disable("thin_film", skip="thin_film_weight")
# In thin-walled mode, the volumetric medium is infinitesimally thin so the parameters controlling
# the MFP of the medium are irrelevant
if (geometry_thin_walled):
disable("transmission", skip=["transmission_weight", "transmission_color"])
disable("subsurface_radius") # (NB, also disables subsurface_radius_scale)