1#import bevy_render::view::View 3@group(0) @binding(0) var<uniform> view: View; 4@group(0) @binding(1) var<storage, read_write> layers: array<vec2<u32>>; 5@group(0) @binding(2) var<storage, read_write> layer_ids: array<atomic<i32>>; 7@group(1) @binding(0) var depth: texture_depth_2d; 15var<private> fragment_list: array<OitFragment, #{LAYER_COUNT}>; 17struct FullscreenVertexOutput { 18 @builtin(position) position: vec4<f32>, 19 @location(0) uv: vec2<f32>, 23fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> { 24 let buffer_size = i32(view.viewport.z * view.viewport.w); 25 let screen_index = i32(floor(in.position.x) + floor(in.position.y) * view.viewport.z); 27 let counter = atomicLoad(&layer_ids[screen_index]); 29 reset_indices(screen_index); 41 let d = textureLoad(depth, vec2<i32>(in.position.xy), 0); 42 let result = sort(screen_index, buffer_size, d); 43 reset_indices(screen_index); 51fn reset_indices(screen_index: i32) { 52 atomicStore(&layer_ids[screen_index], 0); 53 layers[screen_index] = vec2(0u); 61fn sort(screen_index: i32, buffer_size: i32, opaque_depth: f32) -> SortResult { 62 var counter = atomicLoad(&layer_ids[screen_index]); 65 for (var i = 0; i < counter; i += 1) { 66 let fragment = layers[screen_index + buffer_size * i]; 68 let color = bevy_pbr::rgb9e5::rgb9e5_to_vec3_(fragment.x); 69 let depth_alpha = bevy_core_pipeline::oit::unpack_24bit_depth_8bit_alpha(fragment.y); 70 fragment_list[i].color = color; 71 fragment_list[i].alpha = depth_alpha.y; 72 fragment_list[i].depth = depth_alpha.x; 76 for (var i = counter; i >= 0; i -= 1) { 77 for (var j = 0; j < i; j += 1) { 78 if fragment_list[j].depth < fragment_list[j + 1].depth { 80 let temp = fragment_list[j + 1]; 81 fragment_list[j + 1] = fragment_list[j]; 82 fragment_list[j] = temp; 88 var final_color = vec4(0.0); 89 for (var i = 0; i <= counter; i += 1) { 93 if fragment_list[i].depth < opaque_depth { 96 let color = fragment_list[i].color; 97 let alpha = fragment_list[i].alpha; 98 var base_color = vec4(color.rgb * alpha, alpha); 99 final_color = blend(final_color, base_color); 100 if final_color.a == 1.0 { 104 var result: SortResult; 105 result.color = final_color; 106 result.depth = fragment_list[0].depth; 113fn blend(color_a: vec4<f32>, color_b: vec4<f32>) -> vec4<f32> { 114 let final_color = color_a.rgb + (1.0 - color_a.a) * color_b.rgb; 115 let alpha = color_a.a + (1.0 - color_a.a) * color_b.a; 116 return vec4(final_color.rgb, alpha);