diff --git a/crates/bevy_pbr/src/pbr_material.rs b/crates/bevy_pbr/src/pbr_material.rs index 6be68dfdd3e646..3384b10a92263c 100644 --- a/crates/bevy_pbr/src/pbr_material.rs +++ b/crates/bevy_pbr/src/pbr_material.rs @@ -47,7 +47,15 @@ pub struct StandardMaterial { pub reflectance: f32, pub normal_map_texture: Option>, pub occlusion_texture: Option>, + /// 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`. pub double_sided: bool, + /// Whether to cull the "front", "back" or neither side of a mesh + /// defaults to `Face::Back` + pub cull_mode: Option, pub unlit: bool, pub alpha_mode: AlphaMode, } @@ -76,6 +84,7 @@ impl Default for StandardMaterial { occlusion_texture: None, normal_map_texture: None, double_sided: false, + cull_mode: Some(Face::Back), unlit: false, alpha_mode: AlphaMode::Opaque, } @@ -153,6 +162,7 @@ pub struct GpuStandardMaterial { pub flags: StandardMaterialFlags, pub base_color_texture: Option>, pub alpha_mode: AlphaMode, + pub cull_mode: Option } impl RenderAsset for StandardMaterial { @@ -320,6 +330,7 @@ impl RenderAsset for StandardMaterial { has_normal_map, base_color_texture: material.base_color_texture, alpha_mode: material.alpha_mode, + cull_mode: material.cull_mode, }) } } @@ -327,6 +338,7 @@ impl RenderAsset for StandardMaterial { #[derive(Clone, PartialEq, Eq, Hash)] pub struct StandardMaterialKey { normal_map: bool, + cull_mode: Option } impl SpecializedMaterial for StandardMaterial { @@ -335,6 +347,7 @@ impl SpecializedMaterial for StandardMaterial { fn key(render_asset: &::PreparedAsset) -> Self::Key { StandardMaterialKey { normal_map: render_asset.has_normal_map, + cull_mode: render_asset.cull_mode, } } @@ -347,6 +360,7 @@ impl SpecializedMaterial for StandardMaterial { .shader_defs .push(String::from("STANDARDMATERIAL_NORMAL_MAP")); } + descriptor.primitive.cull_mode = key.cull_mode; if let Some(label) = &mut descriptor.label { *label = format!("pbr_{}", *label).into(); }