Skip to content

Commit af27226

Browse files
committed
feat: implement premultiplied and add alpha modes in OIT
Signed-off-by: Schmarni <marnistromer@gmail.com>
1 parent f8bdd2b commit af27226

File tree

5 files changed

+25
-6
lines changed

5 files changed

+25
-6
lines changed

crates/bevy_core_pipeline/src/oit/oit_draw.wgsl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ fn oit_draw(position: vec4f, color: vec4f) {
1414
#endif
1515
// Don't add fully transparent fragments to the list
1616
// because we don't want to have to sort them in the resolve pass
17-
if color.a < oit_settings.alpha_threshold {
17+
if color.r < oit_settings.alpha_threshold
18+
&& color.g < oit_settings.alpha_threshold
19+
&& color.b < oit_settings.alpha_threshold
20+
&& color.a < oit_settings.alpha_threshold
21+
{
1822
return;
1923
}
2024
// get the index of the current fragment relative to the screen size

crates/bevy_core_pipeline/src/oit/resolve/oit_resolve.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ fn resolve(head: u32, opaque_depth: f32) -> vec4<f32> {
116116
for (var i = 0u; i < sorted_frag_count; i += 1) {
117117
let color = bevy_pbr::rgb9e5::rgb9e5_to_vec3_(fragment_list[i].color);
118118
let alpha = packed_depth_alpha_get_alpha(fragment_list[i].depth_alpha);
119-
var base_color = vec4(color.rgb * alpha, alpha);
119+
var base_color = vec4(color.rgb, alpha);
120120
final_color = blend(final_color, base_color);
121121
if final_color.a == 1.0 {
122122
break;

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3416,7 +3416,12 @@ impl SpecializedMeshPipeline for MeshPipeline {
34163416
let (label, blend, depth_write_enabled);
34173417
let pass = key.intersection(MeshPipelineKey::BLEND_RESERVED_BITS);
34183418
let (mut is_opaque, mut alpha_to_coverage_enabled) = (false, false);
3419-
if key.contains(MeshPipelineKey::OIT_ENABLED) && pass == MeshPipelineKey::BLEND_ALPHA {
3419+
if key.contains(MeshPipelineKey::OIT_ENABLED)
3420+
&& matches!(
3421+
pass,
3422+
MeshPipelineKey::BLEND_ALPHA | MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA
3423+
)
3424+
{
34203425
label = "oit_mesh_pipeline".into();
34213426
// TODO tail blending would need alpha blending
34223427
blend = None;

crates/bevy_pbr/src/render/pbr.wgsl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,17 @@ fn fragment(
9191

9292
#ifdef OIT_ENABLED
9393
let alpha_mode = pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS;
94-
if alpha_mode != pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE {
94+
if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_BLEND {
95+
// The fragments will only be drawn during the oit resolve pass.
96+
oit_draw(in.position, vec4(out.color.rgb * out.color.a, out.color.a));
97+
discard;
98+
}
99+
if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_PREMULTIPLIED {
100+
// The fragments will only be drawn during the oit resolve pass.
101+
oit_draw(in.position, out.color);
102+
discard;
103+
}
104+
if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ADD {
95105
// The fragments will only be drawn during the oit resolve pass.
96106
oit_draw(in.position, out.color);
97107
discard;

examples/3d/order_independent_transparency.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ fn spawn_spheres(
162162
Mesh3d(sphere_handle.clone()),
163163
MeshMaterial3d(materials.add(StandardMaterial {
164164
base_color: GREEN.with_alpha(alpha).into(),
165-
alpha_mode: AlphaMode::Blend,
165+
alpha_mode: AlphaMode::Premultiplied,
166166
..default()
167167
})),
168168
Transform::from_translation(pos_b + offset),
@@ -172,7 +172,7 @@ fn spawn_spheres(
172172
Mesh3d(sphere_handle.clone()),
173173
MeshMaterial3d(materials.add(StandardMaterial {
174174
base_color: BLUE.with_alpha(alpha).into(),
175-
alpha_mode: AlphaMode::Blend,
175+
alpha_mode: AlphaMode::Add,
176176
..default()
177177
})),
178178
Transform::from_translation(pos_c + offset),

0 commit comments

Comments
 (0)