Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - use alpha mask even when unlit #6047

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> {
pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic);

output_color = tone_mapping(pbr(pbr_input));
} else {
output_color = alpha_discard(material, output_color);
}

return output_color;
Expand Down
33 changes: 20 additions & 13 deletions crates/bevy_pbr/src/render/pbr_functions.wgsl
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
#define_import_path bevy_pbr::pbr_functions

fn alpha_discard(material: StandardMaterial, output_color: vec4<f32>) -> vec4<f32>{
var color = output_color;
if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE) != 0u) {
// NOTE: If rendering as opaque, alpha should be ignored so set to 1.0
color.a = 1.0;
} else if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) {
if (color.a >= material.alpha_cutoff) {
// NOTE: If rendering as masked alpha and >= the cutoff, render as fully opaque
color.a = 1.0;
} else {
// NOTE: output_color.a < in.material.alpha_cutoff should not is not rendered
// NOTE: This and any other discards mean that early-z testing cannot be done!
discard;
}
}
return color;
}

// NOTE: This ensures that the world_normal is normalized and if
// vertex tangents and normal maps then normal mapping may be applied.
fn prepare_normal(
Expand Down Expand Up @@ -142,19 +160,7 @@ fn pbr(

let occlusion = in.occlusion;

if ((in.material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE) != 0u) {
// NOTE: If rendering as opaque, alpha should be ignored so set to 1.0
output_color.a = 1.0;
} else if ((in.material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) {
if (output_color.a >= in.material.alpha_cutoff) {
// NOTE: If rendering as masked alpha and >= the cutoff, render as fully opaque
output_color.a = 1.0;
} else {
// NOTE: output_color.a < in.material.alpha_cutoff should not is not rendered
// NOTE: This and any other discards mean that early-z testing cannot be done!
discard;
}
}
output_color = alpha_discard(in.material, output_color);

// Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886"
let NdotV = max(dot(in.N, in.V), 0.0001);
Expand Down Expand Up @@ -247,3 +253,4 @@ fn tone_mapping(in: vec4<f32>) -> vec4<f32> {
// Not needed with sRGB buffer
// output_color.rgb = pow(output_color.rgb, vec3(1.0 / 2.2));
}

15 changes: 15 additions & 0 deletions examples/3d/transparency_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ fn setup(
transform: Transform::from_xyz(1.0, 0.5, -1.5),
..default()
});
// transparent unlit sphere, uses `alpha_mode: Mask(f32)`
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Icosphere {
radius: 0.5,
subdivisions: 3,
})),
material: materials.add(StandardMaterial {
base_color: Color::rgba(0.2, 0.7, 0.1, 0.0),
alpha_mode: AlphaMode::Mask(0.5),
unlit: true,
..default()
}),
transform: Transform::from_xyz(-1.0, 0.5, -1.5),
..default()
});
// transparent cube, uses `alpha_mode: Blend`
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
Expand Down