Fix OIT shaders error with DX12 backend (#15782)

# 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: https://github.com/gfx-rs/wgpu/issues/4458
https://github.com/gpuweb/gpuweb/issues/2523

## Testing

- Tested `order_independent_transparency` example with both dx12 and
vulkan backend on Windows
This commit is contained in:
akimakinai 2024-10-10 23:17:09 +09:00 committed by GitHub
parent 0944499f90
commit 11d1ebeed3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 11 additions and 6 deletions

View File

@ -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.
@ -19,7 +19,7 @@ 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
@ -27,7 +27,6 @@ fn oit_draw(position: vec4f, color: vec4f) -> vec4f {
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

View File

@ -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);

View File

@ -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