4import bevy_render::view::View; 5import bevy_pbr::render::mesh_view_types::OitFragmentNode; 7@group(0) @binding(0) var<uniform> view: View; 8@group(0) @binding(1) var<storage, read> nodes: array<OitFragmentNode>; 9@group(0) @binding(2) var<storage, read_write> heads: array<u32>; 10@group(0) @binding(3) var<storage, read_write> atomic_counter: u32; 13@group(1) @binding(0) var depth: texture_depth_2d; 20struct FullscreenVertexOutput { 21 @builtin(position) position: vec4<f32>, 22 @location(0) uv: vec2<f32>, 25const LINKED_LIST_END_SENTINEL: u32 = 0xFFFFFFFFu; 26const SORTED_FRAGMENT_MAX_COUNT: u32 = constants::SORTED_FRAGMENT_MAX_COUNT; 29fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> { 31 let screen_index = u32(floor(in.position.x) + floor(in.position.y) * view.viewport.z); 33 let head = heads[screen_index] - 1u; 34 if head == LINKED_LIST_END_SENTINEL { 46 let d = textureLoad(depth, vec2<i32>(in.position.xy), 0); 49 let color = resolve(head, d); 50 heads[screen_index] = 0u; 55fn resolve(head: u32, opaque_depth: f32) -> vec4<f32> { 60 var fragment_list: array<OitFragment, SORTED_FRAGMENT_MAX_COUNT>; 61 var final_color = vec4<f32>(0.0); 63 var packed_opaque_depth = package::oit::draw::pack_24bit_depth_8bit_alpha(opaque_depth, 1.0); 66 var current_node = head; 67 var sorted_frag_count = 0u; 68 while current_node != LINKED_LIST_END_SENTINEL { 69 let fragment_node = nodes[current_node]; 70 current_node = fragment_node.next; 74 if fragment_node.depth_alpha < packed_opaque_depth { 78 if sorted_frag_count < SORTED_FRAGMENT_MAX_COUNT { 81 var i = sorted_frag_count; 82 for (; i > 0 && fragment_node.depth_alpha > fragment_list[i - 1].depth_alpha; i -= 1) { 83 fragment_list[i] = fragment_list[i - 1]; 85 fragment_list[i].color = fragment_node.color; 86 fragment_list[i].depth_alpha = fragment_node.depth_alpha; 87 sorted_frag_count += 1; 88 } else if fragment_list[0].depth_alpha > fragment_node.depth_alpha { 93 let nearest_color = bevy_pbr::render::rgb9e5::rgb9e5_to_vec3_(fragment_list[0].color); 94 let nearest_alpha = packed_depth_alpha_get_alpha(fragment_list[0].depth_alpha); 95 final_color = blend(final_color, vec4f(nearest_color * nearest_alpha, nearest_alpha)); 97 for (; i < SORTED_FRAGMENT_MAX_COUNT - 1 && fragment_node.depth_alpha < fragment_list[i + 1].depth_alpha; i += 1) { 98 fragment_list[i] = fragment_list[i + 1]; 100 fragment_list[i].color = fragment_node.color; 101 fragment_list[i].depth_alpha = fragment_node.depth_alpha; 106 let color = bevy_pbr::render::rgb9e5::rgb9e5_to_vec3_(fragment_node.color); 107 let alpha = packed_depth_alpha_get_alpha(fragment_node.depth_alpha); 108 final_color = blend(final_color, vec4f(color * alpha, alpha)); 113 for (var i = 0u; i < sorted_frag_count; i += 1) { 114 let color = bevy_pbr::render::rgb9e5::rgb9e5_to_vec3_(fragment_list[i].color); 115 let alpha = packed_depth_alpha_get_alpha(fragment_list[i].depth_alpha); 116 var base_color = vec4(color.rgb, alpha); 117 final_color = blend(final_color, base_color); 118 if final_color.a == 1.0 { 128fn blend(color_a: vec4<f32>, color_b: vec4<f32>) -> vec4<f32> { 129 let final_color = color_a.rgb + (1.0 - color_a.a) * color_b.rgb; 130 let alpha = color_a.a + (1.0 - color_a.a) * color_b.a; 131 return vec4(final_color.rgb, alpha); 134fn packed_depth_alpha_get_alpha(packed: u32) -> f32 { 135 return package::oit::draw::unpack_24bit_depth_8bit_alpha(packed).y;