@@ -13,15 +13,14 @@ struct OitFragment {
1313 alpha : f32 ,
1414 depth : f32 ,
1515}
16- // Contains all the colors and depth for this specific fragment
17- var <private > fragment_list : array <OitFragment , #{SORTED_FRAGMENT_MAX_COUNT }>;
1816
1917struct FullscreenVertexOutput {
2018 @builtin (position ) position : vec4 <f32 >,
2119 @location (0 ) uv : vec2 <f32 >,
2220};
2321
2422const LINKED_LIST_END_SENTINEL : u32 = 0xFFFFFFFFu ;
23+ const SORTED_FRAGMENT_MAX_COUNT : u32 = #{SORTED_FRAGMENT_MAX_COUNT };
2524
2625@fragment
2726fn fragment (in : FullscreenVertexOutput ) -> @location (0 ) vec4 <f32 > {
@@ -41,31 +40,34 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
4140 // This should be done during the draw pass so those fragments simply don't exist in the list,
4241 // but this requires a bigger refactor
4342 let d = textureLoad (depth , vec2 <i32 >(in . position . xy ), 0 );
44- let result = resolve (header , d );
43+ let color = resolve (header , d );
4544 headers [screen_index ] = LINKED_LIST_END_SENTINEL ;
46- return result . color ;
45+ return color ;
4746 }
4847}
4948
50- struct SortResult {
51- color : vec4f ,
52- depth : f32 ,
53- }
54-
55- fn resolve (header : u32 , opaque_depth : f32 ) -> SortResult {
56- var final_color = vec4 (0 .0 );
49+ fn resolve (header : u32 , opaque_depth : f32 ) -> vec4 <f32 > {
50+ // Contains all the colors and depth for this specific fragment
51+ // Fragments are sorted from back to front.
52+ var fragment_list : array <OitFragment , SORTED_FRAGMENT_MAX_COUNT >;
53+ var final_color = vec4 <f32 >(0 .0 );
5754
5855 // fill list
5956 var current_node = header ;
6057 var sorted_frag_count = 0u ;
6158 while current_node != LINKED_LIST_END_SENTINEL {
6259 let fragment_node = nodes [current_node ];
63- // unpack color/ alpha/ depth
60+ // unpack color, alpha, depth
6461 let color = bevy_pbr :: rgb9e5 :: rgb9e5_to_vec3_ (fragment_node . color );
6562 let depth_alpha = bevy_core_pipeline :: oit :: unpack_24bit_depth_8bit_alpha (fragment_node . depth_alpha );
6663 current_node = fragment_node . next ;
6764
68- if sorted_frag_count < #{SORTED_FRAGMENT_MAX_COUNT } {
65+ // depth testing
66+ if depth_alpha . x < opaque_depth {
67+ continue ;
68+ }
69+
70+ if sorted_frag_count < SORTED_FRAGMENT_MAX_COUNT {
6971 // There is still room in the sorted list.
7072 // Insert the fragment so that the list stay sorted.
7173 var i = sorted_frag_count ;
@@ -83,7 +85,7 @@ fn resolve(header: u32, opaque_depth: f32) -> SortResult {
8385 // This is an approximation.
8486 final_color = blend (vec4f (fragment_list [0 ]. color * fragment_list [0 ]. alpha , fragment_list [0 ]. alpha ), final_color );
8587 var i = 0u ;
86- for (; (i < #{ SORTED_FRAGMENT_MAX_COUNT } - 1 ) && (fragment_list [i + 1 ]. depth < depth_alpha . x ); i += 1 ) {
88+ for (; (i < SORTED_FRAGMENT_MAX_COUNT - 1 ) && (fragment_list [i + 1 ]. depth < depth_alpha . x ); i += 1 ) {
8789 fragment_list [i ] = fragment_list [i + 1 ];
8890 }
8991 fragment_list [i ]. color = color ;
@@ -99,12 +101,6 @@ fn resolve(header: u32, opaque_depth: f32) -> SortResult {
99101
100102 // blend sorted fragments
101103 for (var i = 0u ; i < sorted_frag_count ; i += 1 ) {
102- // depth testing
103- // This needs to happen here because we can only stop iterating if the fragment is
104- // occluded by something opaque and the fragments need to be sorted first
105- if fragment_list [i ]. depth < opaque_depth {
106- break ;
107- }
108104 let color = fragment_list [i ]. color ;
109105 let alpha = fragment_list [i ]. alpha ;
110106 var base_color = vec4 (color . rgb * alpha , alpha );
@@ -113,11 +109,8 @@ fn resolve(header: u32, opaque_depth: f32) -> SortResult {
113109 break ;
114110 }
115111 }
116- var result : SortResult ;
117- result . color = final_color ;
118- result . depth = fragment_list [0 ]. depth ;
119112
120- return result ;
113+ return final_color ;
121114}
122115
123116// OVER operator using premultiplied alpha
0 commit comments