#![allow(clippy::excessive_precision)]
use super::types::{Color3, InputError, InputSpec, Value, ValueType, Vector3};
pub const NODEDEF_NAME: &str = "ND_open_pbr_surface_surfaceshader";
pub const NODE_NAME: &str = "open_pbr_surface";
pub const VERSION: &str = "1.1.1";
pub const NODE_GROUP: &str = "pbr";
pub const OUTPUT_TYPE: &str = "surfaceshader";
#[derive(Debug, Clone, PartialEq)]
pub struct OpenPbrSurface {
pub base_weight: f32,
pub base_color: Color3,
pub base_diffuse_roughness: f32,
pub base_metalness: f32,
pub specular_weight: f32,
pub specular_color: Color3,
pub specular_roughness: f32,
pub specular_ior: f32,
pub specular_roughness_anisotropy: f32,
pub transmission_weight: f32,
pub transmission_color: Color3,
pub transmission_depth: f32,
pub transmission_scatter: Color3,
pub transmission_scatter_anisotropy: f32,
pub transmission_dispersion_scale: f32,
pub transmission_dispersion_abbe_number: f32,
pub subsurface_weight: f32,
pub subsurface_color: Color3,
pub subsurface_radius: f32,
pub subsurface_radius_scale: Color3,
pub subsurface_scatter_anisotropy: f32,
pub fuzz_weight: f32,
pub fuzz_color: Color3,
pub fuzz_roughness: f32,
pub coat_weight: f32,
pub coat_color: Color3,
pub coat_roughness: f32,
pub coat_roughness_anisotropy: f32,
pub coat_ior: f32,
pub coat_darkening: f32,
pub thin_film_weight: f32,
pub thin_film_thickness: f32,
pub thin_film_ior: f32,
pub emission_luminance: f32,
pub emission_color: Color3,
pub geometry_opacity: f32,
pub geometry_thin_walled: bool,
pub geometry_normal: Option<Vector3>,
pub geometry_coat_normal: Option<Vector3>,
pub geometry_tangent: Option<Vector3>,
pub geometry_coat_tangent: Option<Vector3>,
}
impl Default for OpenPbrSurface {
fn default() -> Self {
Self {
base_weight: 1.0,
base_color: Color3::new(0.8, 0.8, 0.8),
base_diffuse_roughness: 0.0,
base_metalness: 0.0,
specular_weight: 1.0,
specular_color: Color3::new(1.0, 1.0, 1.0),
specular_roughness: 0.3,
specular_ior: 1.5,
specular_roughness_anisotropy: 0.0,
transmission_weight: 0.0,
transmission_color: Color3::new(1.0, 1.0, 1.0),
transmission_depth: 0.0,
transmission_scatter: Color3::new(0.0, 0.0, 0.0),
transmission_scatter_anisotropy: 0.0,
transmission_dispersion_scale: 0.0,
transmission_dispersion_abbe_number: 20.0,
subsurface_weight: 0.0,
subsurface_color: Color3::new(0.8, 0.8, 0.8),
subsurface_radius: 1.0,
subsurface_radius_scale: Color3::new(1.0, 0.5, 0.25),
subsurface_scatter_anisotropy: 0.0,
fuzz_weight: 0.0,
fuzz_color: Color3::new(1.0, 1.0, 1.0),
fuzz_roughness: 0.5,
coat_weight: 0.0,
coat_color: Color3::new(1.0, 1.0, 1.0),
coat_roughness: 0.0,
coat_roughness_anisotropy: 0.0,
coat_ior: 1.6,
coat_darkening: 1.0,
thin_film_weight: 0.0,
thin_film_thickness: 0.5,
thin_film_ior: 1.4,
emission_luminance: 0.0,
emission_color: Color3::new(1.0, 1.0, 1.0),
geometry_opacity: 1.0,
geometry_thin_walled: false,
geometry_normal: None,
geometry_coat_normal: None,
geometry_tangent: None,
geometry_coat_tangent: None,
}
}
}
pub static INPUTS: [InputSpec; 41] = [
InputSpec {
name: "base_weight",
ty: ValueType::Float,
default: Some(Value::Float(1.0)),
default_geom_prop: None,
ui_name: "Base Weight",
ui_folder: "Base",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Multiplier on the intensity of the reflection from the diffuse and metallic base.",
},
InputSpec {
name: "base_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(0.8, 0.8, 0.8))),
default_geom_prop: None,
ui_name: "Base Color",
ui_folder: "Base",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Color of the reflection from the diffuse and metallic base.",
},
InputSpec {
name: "base_diffuse_roughness",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Base Diffuse Roughness",
ui_folder: "Base",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Roughness of the diffuse reflection. Higher values cause the surface to appear flatter.",
},
InputSpec {
name: "base_metalness",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Base Metalness",
ui_folder: "Base",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Specifies how metallic the base material appears (dials the base from pure dielectric to pure metal).",
},
InputSpec {
name: "specular_weight",
ty: ValueType::Float,
default: Some(Value::Float(1.0)),
default_geom_prop: None,
ui_name: "Specular Weight",
ui_folder: "Specular",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: None,
ui_soft_max: Some(Value::Float(1.0)),
ui_advanced: false,
uniform: false,
hint: None,
doc: "Multiplies the specular reflectivity.",
},
InputSpec {
name: "specular_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
default_geom_prop: None,
ui_name: "Specular Color",
ui_folder: "Specular",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Color of the specular reflection (controls the physical edge-tint for metals, and a non-physical overall tint for dielectrics).",
},
InputSpec {
name: "specular_roughness",
ty: ValueType::Float,
default: Some(Value::Float(0.3)),
default_geom_prop: None,
ui_name: "Specular Roughness",
ui_folder: "Specular",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "The roughness of the specular reflection. Lower numbers produce sharper reflections, higher numbers produce blurrier reflections.",
},
InputSpec {
name: "specular_ior",
ty: ValueType::Float,
default: Some(Value::Float(1.5)),
default_geom_prop: None,
ui_name: "Specular Index of Refraction",
ui_folder: "Specular",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: Some(Value::Float(1.0)),
ui_soft_max: Some(Value::Float(3.0)),
ui_advanced: false,
uniform: false,
hint: None,
doc: "Index of refraction of the dielectric base.",
},
InputSpec {
name: "specular_roughness_anisotropy",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Specular Anisotropy",
ui_folder: "Specular",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The directional bias of the roughness of the metal/dielectric base, resulting in increasingly stretched highlights along the tangent direction.",
},
InputSpec {
name: "transmission_weight",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Transmission Weight",
ui_folder: "Transmission",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: Some("transparency"),
doc: "Mixture weight between the transparent and opaque dielectric base. The greater the value the more transparent the material.",
},
InputSpec {
name: "transmission_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
default_geom_prop: None,
ui_name: "Transmission Color",
ui_folder: "Transmission",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Controls color of the transparent base due to Beer's law volumetric absorption under the surface (reverts to a non-physical tint when transmission_depth is zero).",
},
InputSpec {
name: "transmission_depth",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Transmission Depth",
ui_folder: "Transmission",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: None,
ui_soft_max: Some(Value::Float(1.0)),
ui_advanced: true,
uniform: false,
hint: None,
doc: "Specifies the distance light travels inside the transparent base before it becomes exactly the transmission_color according to Beer's law.",
},
InputSpec {
name: "transmission_scatter",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
default_geom_prop: None,
ui_name: "Transmission Scatter",
ui_folder: "Transmission",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Controls the color of light volumetrically scattered inside the transparent base. Suitable for materials with visually significant scattering such as honey, fruit juice, murky water, opalescent glass, or milky glass.",
},
InputSpec {
name: "transmission_scatter_anisotropy",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Transmission Anisotropy",
ui_folder: "Transmission",
ui_min: Some(Value::Float(-1.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The amount of directional bias, or anisotropy, of the volumetric scattering in the transparent base.",
},
InputSpec {
name: "transmission_dispersion_scale",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Transmission Dispersion Scale",
ui_folder: "Transmission",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Linearly scales the amount of dispersion.",
},
InputSpec {
name: "transmission_dispersion_abbe_number",
ty: ValueType::Float,
default: Some(Value::Float(20.0)),
default_geom_prop: None,
ui_name: "Transmission Dispersion Abbe Number",
ui_folder: "Transmission",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: Some(Value::Float(9.0)),
ui_soft_max: Some(Value::Float(91.0)),
ui_advanced: true,
uniform: false,
hint: None,
doc: "Physical Abbe number of the dielectric medium, describing how much the dielectric index of refraction varies across wavelengths.",
},
InputSpec {
name: "subsurface_weight",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Subsurface Weight",
ui_folder: "Subsurface",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Mixture weight which dials the opaque dielectric base between diffuse reflection and subsurface scattering. A value of 1.0 indicates full subsurface scattering and a value 0 for diffuse reflection only.",
},
InputSpec {
name: "subsurface_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(0.8, 0.8, 0.8))),
default_geom_prop: None,
ui_name: "Subsurface Color",
ui_folder: "Subsurface",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The observed reflection color of the subsurface scattering medium.",
},
InputSpec {
name: "subsurface_radius",
ty: ValueType::Float,
default: Some(Value::Float(1.0)),
default_geom_prop: None,
ui_name: "Subsurface Radius",
ui_folder: "Subsurface",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: None,
ui_soft_max: Some(Value::Float(1.0)),
ui_advanced: true,
uniform: false,
hint: None,
doc: "Length scale of the subsurface scattering mean free path.",
},
InputSpec {
name: "subsurface_radius_scale",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(1.0, 0.5, 0.25))),
default_geom_prop: None,
ui_name: "Subsurface Radius Scale",
ui_folder: "Subsurface",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "RGB multiplier to subsurface_radius, giving the per-channel scattering mean-free-paths.",
},
InputSpec {
name: "subsurface_scatter_anisotropy",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Subsurface Anisotropy",
ui_folder: "Subsurface",
ui_min: Some(Value::Float(-1.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Controls the phase-function of subsurface scattering, where zero scatters light evenly, positive values scatter forwards, and negative values scatter backwards.",
},
InputSpec {
name: "fuzz_weight",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Fuzz Weight",
ui_folder: "Fuzz",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The presence weight of a fuzz layer that can be used to approximate microfibers, for fabrics such as velvet and satin as well as dust grains.",
},
InputSpec {
name: "fuzz_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
default_geom_prop: None,
ui_name: "Fuzz Color",
ui_folder: "Fuzz",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The color of the fuzz layer.",
},
InputSpec {
name: "fuzz_roughness",
ty: ValueType::Float,
default: Some(Value::Float(0.5)),
default_geom_prop: None,
ui_name: "Fuzz Roughness",
ui_folder: "Fuzz",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The roughness of the fuzz layer.",
},
InputSpec {
name: "coat_weight",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Coat Weight",
ui_folder: "Coat",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "The presence weight of a reflective clear-coat layer on top of the material. Use for materials such as car paint or an oily layer.",
},
InputSpec {
name: "coat_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
default_geom_prop: None,
ui_name: "Coat Color",
ui_folder: "Coat",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "The color of the clear-coat layer's transparency, due to absorption in the coat.",
},
InputSpec {
name: "coat_roughness",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Coat Roughness",
ui_folder: "Coat",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "The roughness of the clear-coat reflections. The lower the value, the sharper the reflection.",
},
InputSpec {
name: "coat_roughness_anisotropy",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Coat Anisotropy",
ui_folder: "Coat",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "The directional bias of the roughness of the clear-coat layer, resulting in increasingly stretched highlights along the coat tangent direction.",
},
InputSpec {
name: "coat_ior",
ty: ValueType::Float,
default: Some(Value::Float(1.6)),
default_geom_prop: None,
ui_name: "Coat Index of Refraction",
ui_folder: "Coat",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: Some(Value::Float(1.0)),
ui_soft_max: Some(Value::Float(3.0)),
ui_advanced: false,
uniform: false,
hint: None,
doc: "The index of refraction of the clear-coat layer.",
},
InputSpec {
name: "coat_darkening",
ty: ValueType::Float,
default: Some(Value::Float(1.0)),
default_geom_prop: None,
ui_name: "Coat Darkening",
ui_folder: "Coat",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Modulates the physical coat darkening effect.",
},
InputSpec {
name: "thin_film_weight",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Thin Film Weight",
ui_folder: "Thin Film",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: false,
hint: None,
doc: "Coverage weight of the thin-film. Use for materials such as multi-tone car paint or soap bubbles.",
},
InputSpec {
name: "thin_film_thickness",
ty: ValueType::Float,
default: Some(Value::Float(0.5)),
default_geom_prop: None,
ui_name: "Thin Film Thickness",
ui_folder: "Thin Film",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: None,
ui_soft_max: Some(Value::Float(1.0)),
ui_advanced: true,
uniform: false,
hint: None,
doc: "The thickness of the thin-film layer on the base (in micrometers).",
},
InputSpec {
name: "thin_film_ior",
ty: ValueType::Float,
default: Some(Value::Float(1.4)),
default_geom_prop: None,
ui_name: "Thin Film Index of Refraction",
ui_folder: "Thin Film",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: Some(Value::Float(1.0)),
ui_soft_max: Some(Value::Float(3.0)),
ui_advanced: true,
uniform: false,
hint: None,
doc: "The index of refraction of the thin-film.",
},
InputSpec {
name: "emission_luminance",
ty: ValueType::Float,
default: Some(Value::Float(0.0)),
default_geom_prop: None,
ui_name: "Emission Luminance",
ui_folder: "Emission",
ui_min: Some(Value::Float(0.0)),
ui_max: None,
ui_soft_min: None,
ui_soft_max: Some(Value::Float(1000.0)),
ui_advanced: false,
uniform: false,
hint: None,
doc: "The amount of emitted light, as a luminance in nits.",
},
InputSpec {
name: "emission_color",
ty: ValueType::Color3,
default: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
default_geom_prop: None,
ui_name: "Emission Color",
ui_folder: "Emission",
ui_min: Some(Value::Color3(Color3::new(0.0, 0.0, 0.0))),
ui_max: Some(Value::Color3(Color3::new(1.0, 1.0, 1.0))),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "The color of the emitted light.",
},
InputSpec {
name: "geometry_opacity",
ty: ValueType::Float,
default: Some(Value::Float(1.0)),
default_geom_prop: None,
ui_name: "Opacity",
ui_folder: "Geometry",
ui_min: Some(Value::Float(0.0)),
ui_max: Some(Value::Float(1.0)),
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: Some("opacity"),
doc: "The opacity of the entire material.",
},
InputSpec {
name: "geometry_thin_walled",
ty: ValueType::Boolean,
default: Some(Value::Boolean(false)),
default_geom_prop: None,
ui_name: "Thin Walled",
ui_folder: "Geometry",
ui_min: None,
ui_max: None,
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: true,
uniform: true,
hint: None,
doc: "If true the surface is double-sided and represents an infinitesimally thin shell. Suitable for extremely geometrically thin objects such as leaves or paper.",
},
InputSpec {
name: "geometry_normal",
ty: ValueType::Vector3,
default: None,
default_geom_prop: Some("Nworld"),
ui_name: "Normal",
ui_folder: "Geometry",
ui_min: None,
ui_max: None,
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Input geometric normal",
},
InputSpec {
name: "geometry_coat_normal",
ty: ValueType::Vector3,
default: None,
default_geom_prop: Some("Nworld"),
ui_name: "Coat Normal",
ui_folder: "Geometry",
ui_min: None,
ui_max: None,
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Input normal for coat layer",
},
InputSpec {
name: "geometry_tangent",
ty: ValueType::Vector3,
default: None,
default_geom_prop: Some("Tworld"),
ui_name: "Tangent",
ui_folder: "Geometry",
ui_min: None,
ui_max: None,
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Input geometric tangent",
},
InputSpec {
name: "geometry_coat_tangent",
ty: ValueType::Vector3,
default: None,
default_geom_prop: Some("Tworld"),
ui_name: "Coat Tangent",
ui_folder: "Geometry",
ui_min: None,
ui_max: None,
ui_soft_min: None,
ui_soft_max: None,
ui_advanced: false,
uniform: false,
hint: None,
doc: "Input geometric tangent for coat layer",
},
];
impl OpenPbrSurface {
pub const INPUTS: &'static [InputSpec] = &INPUTS;
pub const INPUT_NAMES: [&'static str; 41] = [
"base_weight",
"base_color",
"base_diffuse_roughness",
"base_metalness",
"specular_weight",
"specular_color",
"specular_roughness",
"specular_ior",
"specular_roughness_anisotropy",
"transmission_weight",
"transmission_color",
"transmission_depth",
"transmission_scatter",
"transmission_scatter_anisotropy",
"transmission_dispersion_scale",
"transmission_dispersion_abbe_number",
"subsurface_weight",
"subsurface_color",
"subsurface_radius",
"subsurface_radius_scale",
"subsurface_scatter_anisotropy",
"fuzz_weight",
"fuzz_color",
"fuzz_roughness",
"coat_weight",
"coat_color",
"coat_roughness",
"coat_roughness_anisotropy",
"coat_ior",
"coat_darkening",
"thin_film_weight",
"thin_film_thickness",
"thin_film_ior",
"emission_luminance",
"emission_color",
"geometry_opacity",
"geometry_thin_walled",
"geometry_normal",
"geometry_coat_normal",
"geometry_tangent",
"geometry_coat_tangent",
];
pub fn input_spec(name: &str) -> Option<&'static InputSpec> {
INPUTS.iter().find(|s| s.name == name)
}
pub fn get(&self, name: &str) -> Result<Option<Value>, InputError> {
Ok(match name {
"base_weight" => Some(Value::Float(self.base_weight)),
"base_color" => Some(Value::Color3(self.base_color)),
"base_diffuse_roughness" => Some(Value::Float(self.base_diffuse_roughness)),
"base_metalness" => Some(Value::Float(self.base_metalness)),
"specular_weight" => Some(Value::Float(self.specular_weight)),
"specular_color" => Some(Value::Color3(self.specular_color)),
"specular_roughness" => Some(Value::Float(self.specular_roughness)),
"specular_ior" => Some(Value::Float(self.specular_ior)),
"specular_roughness_anisotropy" => {
Some(Value::Float(self.specular_roughness_anisotropy))
}
"transmission_weight" => Some(Value::Float(self.transmission_weight)),
"transmission_color" => Some(Value::Color3(self.transmission_color)),
"transmission_depth" => Some(Value::Float(self.transmission_depth)),
"transmission_scatter" => Some(Value::Color3(self.transmission_scatter)),
"transmission_scatter_anisotropy" => {
Some(Value::Float(self.transmission_scatter_anisotropy))
}
"transmission_dispersion_scale" => {
Some(Value::Float(self.transmission_dispersion_scale))
}
"transmission_dispersion_abbe_number" => {
Some(Value::Float(self.transmission_dispersion_abbe_number))
}
"subsurface_weight" => Some(Value::Float(self.subsurface_weight)),
"subsurface_color" => Some(Value::Color3(self.subsurface_color)),
"subsurface_radius" => Some(Value::Float(self.subsurface_radius)),
"subsurface_radius_scale" => Some(Value::Color3(self.subsurface_radius_scale)),
"subsurface_scatter_anisotropy" => {
Some(Value::Float(self.subsurface_scatter_anisotropy))
}
"fuzz_weight" => Some(Value::Float(self.fuzz_weight)),
"fuzz_color" => Some(Value::Color3(self.fuzz_color)),
"fuzz_roughness" => Some(Value::Float(self.fuzz_roughness)),
"coat_weight" => Some(Value::Float(self.coat_weight)),
"coat_color" => Some(Value::Color3(self.coat_color)),
"coat_roughness" => Some(Value::Float(self.coat_roughness)),
"coat_roughness_anisotropy" => Some(Value::Float(self.coat_roughness_anisotropy)),
"coat_ior" => Some(Value::Float(self.coat_ior)),
"coat_darkening" => Some(Value::Float(self.coat_darkening)),
"thin_film_weight" => Some(Value::Float(self.thin_film_weight)),
"thin_film_thickness" => Some(Value::Float(self.thin_film_thickness)),
"thin_film_ior" => Some(Value::Float(self.thin_film_ior)),
"emission_luminance" => Some(Value::Float(self.emission_luminance)),
"emission_color" => Some(Value::Color3(self.emission_color)),
"geometry_opacity" => Some(Value::Float(self.geometry_opacity)),
"geometry_thin_walled" => Some(Value::Boolean(self.geometry_thin_walled)),
"geometry_normal" => self.geometry_normal.map(Value::Vector3),
"geometry_coat_normal" => self.geometry_coat_normal.map(Value::Vector3),
"geometry_tangent" => self.geometry_tangent.map(Value::Vector3),
"geometry_coat_tangent" => self.geometry_coat_tangent.map(Value::Vector3),
_ => return Err(InputError::Unknown(name.to_string())),
})
}
pub fn set(&mut self, name: &str, value: Value) -> Result<(), InputError> {
match (name, value) {
("base_weight", Value::Float(v)) => self.base_weight = v,
("base_color", Value::Color3(v)) => self.base_color = v,
("base_diffuse_roughness", Value::Float(v)) => self.base_diffuse_roughness = v,
("base_metalness", Value::Float(v)) => self.base_metalness = v,
("specular_weight", Value::Float(v)) => self.specular_weight = v,
("specular_color", Value::Color3(v)) => self.specular_color = v,
("specular_roughness", Value::Float(v)) => self.specular_roughness = v,
("specular_ior", Value::Float(v)) => self.specular_ior = v,
("specular_roughness_anisotropy", Value::Float(v)) => {
self.specular_roughness_anisotropy = v
}
("transmission_weight", Value::Float(v)) => self.transmission_weight = v,
("transmission_color", Value::Color3(v)) => self.transmission_color = v,
("transmission_depth", Value::Float(v)) => self.transmission_depth = v,
("transmission_scatter", Value::Color3(v)) => self.transmission_scatter = v,
("transmission_scatter_anisotropy", Value::Float(v)) => {
self.transmission_scatter_anisotropy = v
}
("transmission_dispersion_scale", Value::Float(v)) => {
self.transmission_dispersion_scale = v
}
("transmission_dispersion_abbe_number", Value::Float(v)) => {
self.transmission_dispersion_abbe_number = v
}
("subsurface_weight", Value::Float(v)) => self.subsurface_weight = v,
("subsurface_color", Value::Color3(v)) => self.subsurface_color = v,
("subsurface_radius", Value::Float(v)) => self.subsurface_radius = v,
("subsurface_radius_scale", Value::Color3(v)) => self.subsurface_radius_scale = v,
("subsurface_scatter_anisotropy", Value::Float(v)) => {
self.subsurface_scatter_anisotropy = v
}
("fuzz_weight", Value::Float(v)) => self.fuzz_weight = v,
("fuzz_color", Value::Color3(v)) => self.fuzz_color = v,
("fuzz_roughness", Value::Float(v)) => self.fuzz_roughness = v,
("coat_weight", Value::Float(v)) => self.coat_weight = v,
("coat_color", Value::Color3(v)) => self.coat_color = v,
("coat_roughness", Value::Float(v)) => self.coat_roughness = v,
("coat_roughness_anisotropy", Value::Float(v)) => self.coat_roughness_anisotropy = v,
("coat_ior", Value::Float(v)) => self.coat_ior = v,
("coat_darkening", Value::Float(v)) => self.coat_darkening = v,
("thin_film_weight", Value::Float(v)) => self.thin_film_weight = v,
("thin_film_thickness", Value::Float(v)) => self.thin_film_thickness = v,
("thin_film_ior", Value::Float(v)) => self.thin_film_ior = v,
("emission_luminance", Value::Float(v)) => self.emission_luminance = v,
("emission_color", Value::Color3(v)) => self.emission_color = v,
("geometry_opacity", Value::Float(v)) => self.geometry_opacity = v,
("geometry_thin_walled", Value::Boolean(v)) => self.geometry_thin_walled = v,
("geometry_normal", Value::Vector3(v)) => self.geometry_normal = Some(v),
("geometry_coat_normal", Value::Vector3(v)) => self.geometry_coat_normal = Some(v),
("geometry_tangent", Value::Vector3(v)) => self.geometry_tangent = Some(v),
("geometry_coat_tangent", Value::Vector3(v)) => self.geometry_coat_tangent = Some(v),
(_, value) => {
let spec =
Self::input_spec(name).ok_or_else(|| InputError::Unknown(name.to_string()))?;
return Err(InputError::TypeMismatch {
name: name.to_string(),
expected: spec.ty,
found: value.value_type(),
});
}
}
Ok(())
}
pub fn set_from_str(&mut self, name: &str, text: &str) -> Result<(), InputError> {
let spec = Self::input_spec(name).ok_or_else(|| InputError::Unknown(name.to_string()))?;
let value = spec.ty.parse_value(text).map_err(InputError::Parse)?;
self.set(name, value)
}
pub fn reset(&mut self, name: &str) -> Result<(), InputError> {
let defaults = Self::default();
match name {
"base_weight" => self.base_weight = defaults.base_weight,
"base_color" => self.base_color = defaults.base_color,
"base_diffuse_roughness" => {
self.base_diffuse_roughness = defaults.base_diffuse_roughness
}
"base_metalness" => self.base_metalness = defaults.base_metalness,
"specular_weight" => self.specular_weight = defaults.specular_weight,
"specular_color" => self.specular_color = defaults.specular_color,
"specular_roughness" => self.specular_roughness = defaults.specular_roughness,
"specular_ior" => self.specular_ior = defaults.specular_ior,
"specular_roughness_anisotropy" => {
self.specular_roughness_anisotropy = defaults.specular_roughness_anisotropy
}
"transmission_weight" => self.transmission_weight = defaults.transmission_weight,
"transmission_color" => self.transmission_color = defaults.transmission_color,
"transmission_depth" => self.transmission_depth = defaults.transmission_depth,
"transmission_scatter" => self.transmission_scatter = defaults.transmission_scatter,
"transmission_scatter_anisotropy" => {
self.transmission_scatter_anisotropy = defaults.transmission_scatter_anisotropy
}
"transmission_dispersion_scale" => {
self.transmission_dispersion_scale = defaults.transmission_dispersion_scale
}
"transmission_dispersion_abbe_number" => {
self.transmission_dispersion_abbe_number =
defaults.transmission_dispersion_abbe_number
}
"subsurface_weight" => self.subsurface_weight = defaults.subsurface_weight,
"subsurface_color" => self.subsurface_color = defaults.subsurface_color,
"subsurface_radius" => self.subsurface_radius = defaults.subsurface_radius,
"subsurface_radius_scale" => {
self.subsurface_radius_scale = defaults.subsurface_radius_scale
}
"subsurface_scatter_anisotropy" => {
self.subsurface_scatter_anisotropy = defaults.subsurface_scatter_anisotropy
}
"fuzz_weight" => self.fuzz_weight = defaults.fuzz_weight,
"fuzz_color" => self.fuzz_color = defaults.fuzz_color,
"fuzz_roughness" => self.fuzz_roughness = defaults.fuzz_roughness,
"coat_weight" => self.coat_weight = defaults.coat_weight,
"coat_color" => self.coat_color = defaults.coat_color,
"coat_roughness" => self.coat_roughness = defaults.coat_roughness,
"coat_roughness_anisotropy" => {
self.coat_roughness_anisotropy = defaults.coat_roughness_anisotropy
}
"coat_ior" => self.coat_ior = defaults.coat_ior,
"coat_darkening" => self.coat_darkening = defaults.coat_darkening,
"thin_film_weight" => self.thin_film_weight = defaults.thin_film_weight,
"thin_film_thickness" => self.thin_film_thickness = defaults.thin_film_thickness,
"thin_film_ior" => self.thin_film_ior = defaults.thin_film_ior,
"emission_luminance" => self.emission_luminance = defaults.emission_luminance,
"emission_color" => self.emission_color = defaults.emission_color,
"geometry_opacity" => self.geometry_opacity = defaults.geometry_opacity,
"geometry_thin_walled" => self.geometry_thin_walled = defaults.geometry_thin_walled,
"geometry_normal" => self.geometry_normal = defaults.geometry_normal,
"geometry_coat_normal" => self.geometry_coat_normal = defaults.geometry_coat_normal,
"geometry_tangent" => self.geometry_tangent = defaults.geometry_tangent,
"geometry_coat_tangent" => self.geometry_coat_tangent = defaults.geometry_coat_tangent,
_ => return Err(InputError::Unknown(name.to_string())),
}
Ok(())
}
pub fn is_default(&self, name: &str) -> Result<bool, InputError> {
Ok(self.get(name)? == Self::default().get(name)?)
}
pub fn changed_inputs(&self) -> Vec<(&'static str, Value)> {
let defaults = Self::default();
INPUTS
.iter()
.filter_map(|spec| {
let value = self.get(spec.name).ok().flatten()?;
(Some(value) != defaults.get(spec.name).ok().flatten())
.then_some((spec.name, value))
})
.collect()
}
}