From 2acddaa2a433ca97d4c2cd35ddedd5dc5d0a02b6 Mon Sep 17 00:00:00 2001 From: Nicola Papale Date: Wed, 28 Sep 2022 21:20:29 +0000 Subject: [PATCH] Document all StandardMaterial fields (#5921) # Objective Add more documentation on `StandardMaterial` and improve consistency on existing doc. Co-authored-by: Nicola Papale --- crates/bevy_pbr/src/alpha.rs | 18 +++- crates/bevy_pbr/src/pbr_material.rs | 138 +++++++++++++++++++++++++--- 2 files changed, 138 insertions(+), 18 deletions(-) diff --git a/crates/bevy_pbr/src/alpha.rs b/crates/bevy_pbr/src/alpha.rs index 55f0a7ff9858da..79fb198f54b8e0 100644 --- a/crates/bevy_pbr/src/alpha.rs +++ b/crates/bevy_pbr/src/alpha.rs @@ -2,16 +2,26 @@ use bevy_ecs::{component::Component, reflect::ReflectComponent}; use bevy_reflect::std_traits::ReflectDefault; use bevy_reflect::Reflect; -// FIXME: This should probably be part of bevy_render2! -/// Alpha mode +// TODO: add discussion about performance. +/// Sets how a material's base color alpha channel is used for transparency. #[derive(Component, Debug, Default, Reflect, Copy, Clone, PartialEq)] #[reflect(Component, Default)] pub enum AlphaMode { + /// Base color alpha values are overridden to be fully opaque (1.0). #[default] Opaque, - /// An alpha cutoff must be supplied where alpha values >= the cutoff - /// will be fully opaque and < will be fully transparent + /// Reduce transparency to fully opaque or fully transparent + /// based on a threshold. + /// + /// Compares the base color alpha value to the specified threshold. + /// If the value is below the threshold, + /// considers the color to be fully transparent (alpha is set to 0.0). + /// If it is equal to or above the threshold, + /// considers the color to be fully opaque (alpha is set to 1.0). Mask(f32), + /// The base color alpha value defines the opacity of the color. + /// Standard alpha-blending is used to blend the fragment's color + /// with the color behind it. Blend, } diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index cf2076dae31d3b..db61a1fe70e38c 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -17,10 +17,28 @@ use bevy_render::{ #[bind_group_data(StandardMaterialKey)] #[uniform(0, StandardMaterialUniform)] pub struct StandardMaterial { + /// The color of the surface of the material before lighting. + /// /// Doubles as diffuse albedo for non-metallic, specular for metallic and a mix for everything - /// in between. If used together with a base_color_texture, this is factored into the final + /// in between. If used together with a `base_color_texture`, this is factored into the final /// base color as `base_color * base_color_texture_value` + /// + /// Defaults to [`Color::WHITE`]. pub base_color: Color, + + /// The texture component of the material's color before lighting. + /// The actual pre-lighting color is `base_color * this_texture`. + /// + /// See [`base_color`] for details. + /// + /// You should set `base_color` to [`Color::WHITE`] (the default) + /// if you want the texture to show as-is. + /// + /// Setting `base_color` to something else than white will tint + /// the texture. For example, setting `base_color` to pure red will + /// tint the texture red. + /// + /// [`base_color`]: StandardMaterial::base_color #[texture(1)] #[sampler(2)] pub base_color_texture: Option>, @@ -42,24 +60,72 @@ pub struct StandardMaterial { /// it just adds a value to the color seen on screen. pub emissive: Color, + /// The emissive map, multiplies pixels with [`emissive`] + /// to get the final "emitting" color of a surface. + /// + /// This color is multiplied by [`emissive`] to get the final emitted color. + /// Meaning that you should set [`emissive`] to [`Color::WHITE`] + /// if you want to use the full range of color of the emissive texture. + /// + /// [`emissive`]: StandardMaterial::emissive #[texture(3)] #[sampler(4)] pub emissive_texture: Option>, - /// Linear perceptual roughness, clamped to [0.089, 1.0] in the shader - /// Defaults to minimum of 0.089 + + /// Linear perceptual roughness, clamped to `[0.089, 1.0]` in the shader. + /// + /// Defaults to minimum of `0.089`. + /// + /// Low values result in a "glossy" material with specular highlights, + /// while values close to `1` result in rough materials. + /// /// If used together with a roughness/metallic texture, this is factored into the final base - /// color as `roughness * roughness_texture_value` + /// color as `roughness * roughness_texture_value`. pub perceptual_roughness: f32, - /// From [0.0, 1.0], dielectric to pure metallic + + /// How "metallic" the material appears, within `[0.0, 1.0]`, + /// going from dielectric to pure metallic. + /// + /// Defaults to `0.01`. + /// + /// The closer to `1` the value, the more the material will + /// reflect light like a metal such as steel or gold. + /// /// If used together with a roughness/metallic texture, this is factored into the final base - /// color as `metallic * metallic_texture_value` + /// color as `metallic * metallic_texture_value`. pub metallic: f32, + /// Metallic and roughness maps, stored as a single texture. + /// + /// The blue channel contains metallic values, + /// and the green channel contains the roughness values. + /// Other channels are unused. + /// + /// Those values are multiplied by the scalar ones of the material, + /// see [`metallic`] and [`perceptual_roughness`] for details. + /// + /// Note that with the default values of [`metallic`] and [`perceptual_roughness`], + /// setting this texture has no effect. If you want to exclusively use the + /// `metallic_roughness_texture` values for your material, make sure to set [`metallic`] + /// and [`perceptual_roughness`] to `1.0`. + /// + /// [`metallic`]: StandardMaterial::metallic + /// [`perceptual_roughness`]: StandardMaterial::perceptual_roughness #[texture(5)] #[sampler(6)] pub metallic_roughness_texture: Option>, - /// Specular intensity for non-metals on a linear scale of [0.0, 1.0] - /// defaults to 0.5 which is mapped to 4% reflectance in the shader + + /// Specular intensity for non-metals on a linear scale of `[0.0, 1.0]`. + /// + /// Use the value as a way to control the intensity of the + /// specular highlight of the material, i.e. how reflective is the material, + /// rather than the physical property "reflectance." + /// + /// Set to `0.0`, no specular highlight is visible, the highlight is strongest + /// when `reflectance` is set to `1.0`. + /// + /// Defaults to `0.5` which is mapped to 4% reflectance in the shader. + #[doc(alias = "specular_intensity")] pub reflectance: f32, /// Used to fake the lighting of bumps and dents on a material. @@ -68,7 +134,6 @@ pub struct StandardMaterial { /// /// # Notes /// - /// /// Normal mapping with `StandardMaterial` and the core bevy PBR shaders requires: /// - A normal map texture /// - Vertex UVs @@ -105,15 +170,57 @@ pub struct StandardMaterial { /// Support two-sided lighting by automatically flipping the normals for "back" faces /// within the PBR lighting shader. - /// Defaults to false. - /// This does not automatically configure backface culling, which can be done via - /// `cull_mode`. + /// + /// Defaults to `false`. + /// This does not automatically configure backface culling, + /// which can be done via `cull_mode`. pub double_sided: bool, - /// Whether to cull the "front", "back" or neither side of a mesh - /// defaults to `Face::Back` + + /// Whether to cull the "front", "back" or neither side of a mesh. + /// If set to `None`, the two sides of the mesh are visible. + /// + /// Defaults to `Some(Face::Back)`. + /// In bevy, the order of declaration of a triangle's vertices + /// in [`Mesh`] defines the triangle's front face. + /// + /// When a triangle is in a viewport, + /// if its vertices appear counter-clockwise from the viewport's perspective, + /// then the viewport is seeing the triangle's front face. + /// Conversly, if the vertices appear clockwise, you are seeing the back face. + /// + /// In short, in bevy, front faces winds counter-clockwise. + /// + /// Your 3D editing software should manage all of that. + /// + /// [`Mesh`]: bevy_render::mesh::Mesh pub cull_mode: Option, + + /// Whether to apply only the base color to this material. + /// + /// Normals, occlusion textures, roughness, metallic, reflectance, emissive, + /// shadows, alpha mode and ambient light are ignored if this is set to `true`. pub unlit: bool, + + /// How to apply the alpha channel of the `base_color_texture`. + /// + /// See [`AlphaMode`] for details. Defaults to [`AlphaMode::Opaque`]. pub alpha_mode: AlphaMode, + + /// Re-arrange render ordering. + /// + /// A material with a positive depth bias will render closer to the + /// camera while negative values cause the material to render behind + /// other objects. This is independent of the viewport. + /// + /// `depth_bias` only affects render ordering. This means that for opaque materials, + /// `depth_bias` will only have any effect if two materials are overlapping, + /// which only serves as a [z-fighting] resolver. + /// + /// `depth_bias` can however reorder [`AlphaMode::Blend`] materials. + /// This is useful if your transparent materials are not rendering + /// in the expected order. + /// + /// [z-fighting]: https://en.wikipedia.org/wiki/Z-fighting pub depth_bias: f32, } @@ -175,6 +282,8 @@ impl From> for StandardMaterial { // NOTE: These must match the bit flags in bevy_pbr/src/render/pbr_types.wgsl! bitflags::bitflags! { + /// Bitflags info about the material a shader is currently rendering. + /// This is accessible in the shader in the [`StandardMaterialUniform`] #[repr(transparent)] pub struct StandardMaterialFlags: u32 { const BASE_COLOR_TEXTURE = (1 << 0); @@ -210,6 +319,7 @@ pub struct StandardMaterialUniform { /// Specular intensity for non-metals on a linear scale of [0.0, 1.0] /// defaults to 0.5 which is mapped to 4% reflectance in the shader pub reflectance: f32, + /// 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, /// and any below means fully transparent.