Skip to content

Commit

Permalink
Fix OIT shaders error with DX12 backend (#15782)
Browse files Browse the repository at this point in the history
# Objective

- Fixes #15781

## Solution

- DX12 backend seems to require functions with return types to return
value. [WebGPU spec also requires
this](https://gpuweb.github.io/gpuweb/wgsl/#behaviors-rules).

Upstream issue: gfx-rs/wgpu#4458
gpuweb/gpuweb#2523

## Testing

- Tested `order_independent_transparency` example with both dx12 and
vulkan backend on Windows
  • Loading branch information
akimakinai authored Oct 10, 2024
1 parent 0944499 commit 11d1ebe
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 6 deletions.
5 changes: 2 additions & 3 deletions crates/bevy_core_pipeline/src/oit/oit_draw.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#ifdef OIT_ENABLED
// Add the fragment to the oit buffer
fn oit_draw(position: vec4f, color: vec4f) -> vec4f {
fn oit_draw(position: vec4f, color: vec4f) {
// get the index of the current fragment relative to the screen size
let screen_index = i32(floor(position.x) + floor(position.y) * view.viewport.z);
// get the size of the buffer.
Expand All @@ -19,15 +19,14 @@ fn oit_draw(position: vec4f, color: vec4f) -> vec4f {
// accidentally increase the index above the maximum value
atomicStore(&oit_layer_ids[screen_index], oit_layers_count);
// TODO for tail blending we should return the color here
discard;
return;
}

// get the layer_index from the screen
let layer_index = screen_index + layer_id * buffer_size;
let rgb9e5_color = bevy_pbr::rgb9e5::vec3_to_rgb9e5_(color.rgb);
let depth_alpha = pack_24bit_depth_8bit_alpha(position.z, color.a);
oit_layers[layer_index] = vec2(rgb9e5_color, depth_alpha);
discard;
}
#endif // OIT_ENABLED

Expand Down
7 changes: 6 additions & 1 deletion crates/bevy_core_pipeline/src/oit/resolve/oit_resolve.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
let counter = atomicLoad(&layer_ids[screen_index]);
if counter == 0 {
reset_indices(screen_index);
discard;

// https://github.com/gfx-rs/wgpu/issues/4416
if true {
discard;
}
return vec4(0.0);
} else {
let result = sort(screen_index, buffer_size);
reset_indices(screen_index);
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_pbr/src/render/pbr.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ fn fragment(
#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 {
// This will always return 0.0. The fragments will only be drawn during the oit resolve pass.
out.color = oit_draw(in.position, out.color);
// The fragments will only be drawn during the oit resolve pass.
oit_draw(in.position, out.color);
discard;
}
#endif // OIT_ENABLED

Expand Down

0 comments on commit 11d1ebe

Please sign in to comment.