Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions crates/bevy_pbr/src/decal/forward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use bevy_math::{prelude::Rectangle, Quat, Vec2, Vec3};
use bevy_mesh::{Mesh, Mesh3d, MeshBuilder, MeshVertexBufferLayoutRef, Meshable};
use bevy_reflect::{Reflect, TypePath};
use bevy_render::{
alpha::AlphaMode,
render_asset::RenderAssets,
render_resource::{
AsBindGroup, AsBindGroupShaderType, CompareFunction, RenderPipelineDescriptor, ShaderType,
Expand Down Expand Up @@ -111,8 +110,12 @@ impl AsBindGroupShaderType<ForwardDecalMaterialExtUniform> for ForwardDecalMater
}

impl MaterialExtension for ForwardDecalMaterialExt {
fn alpha_mode() -> Option<AlphaMode> {
Some(AlphaMode::Blend)
fn enable_shadows() -> bool {
false
}

fn enable_prepass() -> bool {
false
}

fn specialize(
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_pbr/src/extended_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl<B: Material, E: MaterialExtension> Material for ExtendedMaterial<B, E> {
}

fn enable_shadows() -> bool {
E::enable_prepass()
E::enable_shadows()
}

fn prepass_vertex_shader() -> ShaderRef {
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2379,8 +2379,9 @@ impl SpecializedMeshPipeline for MeshPipeline {
let (mut is_opaque, mut alpha_to_coverage_enabled) = (false, false);
if key.contains(MeshPipelineKey::OIT_ENABLED) && pass == MeshPipelineKey::BLEND_ALPHA {
label = "oit_mesh_pipeline".into();
// TODO tail blending would need alpha blending
blend = None;
// TODO tail blending would need to return color in shader to do alpha blending
// Alpha blending is also needed by forward decals.
blend = Some(BlendState::ALPHA_BLENDING);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused. This is only relevant when using forward decal with OIT right? But in pbr.wgsl you added a comment saying forward decal is incompatible with OIT.

Also, do we have a way to check here if this is for a forward decal or just a standard mesh?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forward decal is just a quad mesh and has no specific mesh key, so we can't check it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I added enable_oit to material as a way to opt out OIT. Let me known if you prefer that.

shader_defs.push("OIT_ENABLED".into());
// TODO it should be possible to use this to combine MSAA and OIT
// alpha_to_coverage_enabled = true;
Expand Down
8 changes: 5 additions & 3 deletions crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ fn fragment(
out.color = main_pass_post_lighting_processing(pbr_input, out.color);
#endif

#ifdef FORWARD_DECAL
out.color.a = min(forward_decal_info.alpha, out.color.a);
#else
// Forward decal is incompatible with OIT as it needs to be rendered
// even it's occluded by opaque objects, but OIT will exclude the fragments.
#ifdef OIT_ENABLED
let alpha_mode = pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS;
if alpha_mode != pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE {
Expand All @@ -98,9 +103,6 @@ fn fragment(
discard;
}
#endif // OIT_ENABLED

#ifdef FORWARD_DECAL
out.color.a = min(forward_decal_info.alpha, out.color.a);
#endif

return out;
Expand Down
46 changes: 44 additions & 2 deletions examples/3d/decal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,60 @@ fn setup(
) {
// Spawn the forward decal
commands.spawn((
Name::new("Decal"),
Name::new("Decal Red"),
ForwardDecal,
MeshMaterial3d(decal_standard_materials.add(ForwardDecalMaterial {
base: StandardMaterial {
base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
base_color: Color::srgba(1.0, 0.0, 0.0, 0.5),
// Use alpha blending for decals
alpha_mode: AlphaMode::Blend,
depth_bias: 0.0,
..default()
},
extension: ForwardDecalMaterialExt {
depth_fade_factor: 1.0,
},
})),
Transform::from_scale(Vec3::splat(4.0)),
Transform::from_scale(Vec3::splat(2.0)).with_translation(Vec3::new(0.5, 0.0, -0.5)),
));

commands.spawn((
Name::new("Decal Green"),
ForwardDecal,
MeshMaterial3d(decal_standard_materials.add(ForwardDecalMaterial {
base: StandardMaterial {
base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
base_color: Color::srgba(0.0, 1.0, 0.0, 0.5),
// Use alpha blending for decals
alpha_mode: AlphaMode::Blend,
depth_bias: 1.0,
..default()
},
extension: ForwardDecalMaterialExt {
depth_fade_factor: 1.0,
},
})),
Transform::from_scale(Vec3::splat(2.0)).with_translation(Vec3::new(-0.5, 0.0, -0.5)),
));

commands.spawn((
Name::new("Decal Blue"),
ForwardDecal,
MeshMaterial3d(decal_standard_materials.add(ForwardDecalMaterial {
base: StandardMaterial {
base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
base_color: Color::srgba(0.0, 0.0, 1.0, 0.5),
// Use alpha blending for decals
alpha_mode: AlphaMode::Blend,
depth_bias: 2.0,
..default()
},
extension: ForwardDecalMaterialExt {
depth_fade_factor: 1.0,
},
})),
Transform::from_scale(Vec3::splat(2.0)).with_translation(Vec3::new(0.0, 0.0, 0.5)),
));

commands.spawn((
Expand Down