Add attenuation_distance and attenuation_color material attributes

This commit is contained in:
Marco Buono 2023-04-24 23:23:54 -03:00
parent 3d55cce4ab
commit 23711c8d3e
3 changed files with 39 additions and 0 deletions

View file

@ -265,6 +265,31 @@ pub struct StandardMaterial {
#[doc(alias = "refraction_index")]
pub ior: f32,
/// How far, on average, light travels through the volume beneath the material's
/// surface before being absorbed.
///
/// Defaults to [`f32::INFINITY`], i.e. light is never absorbed.
///
/// **Note:** To have any effect, must be used in conjunction with:
/// - [`StandardMaterial::attenuation_color`];
/// - [`StandardMaterial::thickness`];
/// - [`StandardMaterial::diffuse_transmission`] or [`StandardMaterial::transmission`].
#[doc(alias = "absorption_distance")]
#[doc(alias = "extinction_distance")]
pub attenuation_distance: f32,
/// The resulting (non-absorbed) color after white light travels through the attenuation distance.
///
/// Defaults to [`Color::WHITE`], i.e. no change.
///
/// **Note:** To have any effect, must be used in conjunction with:
/// - [`StandardMaterial::attenuation_distance`];
/// - [`StandardMaterial::thickness`];
/// - [`StandardMaterial::diffuse_transmission`] or [`StandardMaterial::transmission`].
#[doc(alias = "absorption_color")]
#[doc(alias = "extinction_color")]
pub attenuation_color: Color,
/// Used to fake the lighting of bumps and dents on a material.
///
/// A typical usage would be faking cobblestones on a flat plane mesh in 3D.
@ -464,6 +489,8 @@ impl Default for StandardMaterial {
thickness: 0.0,
thickness_texture: None,
ior: 1.5,
attenuation_color: Color::WHITE,
attenuation_distance: f32::INFINITY,
occlusion_texture: None,
normal_map_texture: None,
flip_normal_map_y: false,
@ -565,6 +592,10 @@ pub struct StandardMaterialUniform {
pub thickness: f32,
/// Index of Refraction
pub ior: f32,
/// How far light travels through the volume underneath the material surface before being absorbed
pub attenuation_distance: f32,
/// Color white light takes after travelling through the attenuation distance underneath the material surface
pub attenuation_color: Vec4,
/// The [`StandardMaterialFlags`] accessible in the `wgsl` shader.
pub flags: u32,
/// When the alpha mode mask flag is set, any base color alpha above this cutoff means fully opaque,
@ -660,6 +691,8 @@ impl AsBindGroupShaderType<StandardMaterialUniform> for StandardMaterial {
transmission: self.transmission,
thickness: self.thickness,
ior: self.ior,
attenuation_distance: self.attenuation_distance,
attenuation_color: self.attenuation_color.as_linear_rgba_f32().into(),
flags: flags.bits(),
alpha_cutoff,
parallax_depth_scale: self.parallax_depth_scale,

View file

@ -64,6 +64,8 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
pbr_input.material.base_color = output_color;
pbr_input.material.reflectance = material.reflectance;
pbr_input.material.ior = material.ior;
pbr_input.material.attenuation_color = material.attenuation_color;
pbr_input.material.attenuation_distance = material.attenuation_distance;
pbr_input.material.flags = material.flags;
pbr_input.material.alpha_cutoff = material.alpha_cutoff;

View file

@ -10,6 +10,8 @@ struct StandardMaterial {
transmission: f32,
thickness: f32,
ior: f32,
attenuation_distance: f32,
attenuation_color: vec4<f32>,
// 'flags' is a bit field indicating various options. u32 is 32 bits so we have up to 32 options.
flags: u32,
alpha_cutoff: f32,
@ -55,6 +57,8 @@ fn standard_material_new() -> StandardMaterial {
material.transmission = 0.0;
material.thickness = 0.0;
material.ior = 1.5;
material.attenuation_distance = 1.0 / 0.0; // f32::INFINITY
material.attenuation_color = vec4<f32>(1.0, 1.0, 1.0, 1.0);
material.flags = STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE;
material.alpha_cutoff = 0.5;
material.parallax_depth_scale = 0.1;