Skip to content

Commit

Permalink
Document all StandardMaterial fields (#5921)
Browse files Browse the repository at this point in the history
# Objective

Add more documentation on `StandardMaterial` and improve
consistency on existing doc.

Co-authored-by: Nicola Papale <nicopap@users.noreply.github.com>
  • Loading branch information
nicopap and nicopap committed Sep 28, 2022
1 parent e8e541e commit 6b8cc26
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 18 deletions.
18 changes: 14 additions & 4 deletions crates/bevy_pbr/src/alpha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
138 changes: 124 additions & 14 deletions crates/bevy_pbr/src/pbr_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Handle<Image>>,
Expand All @@ -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<Handle<Image>>,
/// 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<Handle<Image>>,
/// 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.
Expand All @@ -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
Expand Down Expand Up @@ -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<Face>,

/// 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,
}

Expand Down Expand Up @@ -175,6 +282,8 @@ impl From<Handle<Image>> 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);
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 6b8cc26

Please sign in to comment.