@@ -54,7 +54,9 @@ fn fragment(in: FullscreenVertexOutput) -> @location(0) vec4<f32> {
5454
5555fn resolve (header : u32 , opaque_depth : f32 ) -> vec4 <f32 > {
5656 // Contains all the colors and depth for this specific fragment
57- // Fragments are sorted from back to front.
57+ // Fragments are sorted from front to back (depth values are in descending order)
58+ // This should make insertion sort slightly faster
59+ // because transparent pass sorts objects so the linked list iteration is usually in descending order.
5860 var fragment_list : array <OitFragment , SORTED_FRAGMENT_MAX_COUNT >;
5961 var final_color = vec4 <f32 >(0 .0 );
6062
@@ -81,7 +83,7 @@ fn resolve(header: u32, opaque_depth: f32) -> vec4<f32> {
8183 var i = sorted_frag_count ;
8284 for (; i > 0 ; i -= 1 ) {
8385 // short-circuit can't be used in for(;;;), https://github.com/gfx-rs/wgpu/issues/4394
84- if depth_alpha . x < fragment_list [i - 1 ]. depth {
86+ if depth_alpha . x > fragment_list [i - 1 ]. depth {
8587 fragment_list [i ] = fragment_list [i - 1 ];
8688 } else {
8789 break ;
@@ -91,16 +93,18 @@ fn resolve(header: u32, opaque_depth: f32) -> vec4<f32> {
9193 fragment_list [i ]. alpha = depth_alpha . y ;
9294 fragment_list [i ]. depth = depth_alpha . x ;
9395 sorted_frag_count += 1 ;
94- } else if fragment_list [0 ]. depth < depth_alpha . x {
95- // The fragment is closer than the farthest sorted one.
96- // First, make room by blending the farthest fragment from the sorted list.
96+ } else if fragment_list [0 ]. depth > depth_alpha . x {
97+ // The fragment is farther than the nearest sorted one.
98+ // First, make room by blending the nearest fragment from the sorted list.
9799 // Then, insert the fragment in the sorted list.
98100 // This is an approximation.
99- final_color = blend (vec4f (fragment_list [0 ]. color * fragment_list [0 ]. alpha , fragment_list [0 ]. alpha ), final_color );
101+ let nearest_color = fragment_list [0 ]. color ;
102+ let nearest_alpha = fragment_list [0 ]. alpha ;
103+ final_color = blend (final_color , vec4f (nearest_color * nearest_alpha , nearest_alpha ));
100104 var i = 0u ;
101105 for (; i < SORTED_FRAGMENT_MAX_COUNT - 1 ; i += 1 ) {
102106 // short-circuit can't be used in for(;;;), https://github.com/gfx-rs/wgpu/issues/4394
103- if fragment_list [i + 1 ]. depth < depth_alpha . x {
107+ if depth_alpha . x < fragment_list [i + 1 ]. depth {
104108 fragment_list [i ] = fragment_list [i + 1 ];
105109 } else {
106110 break ;
@@ -110,10 +114,10 @@ fn resolve(header: u32, opaque_depth: f32) -> vec4<f32> {
110114 fragment_list [i ]. alpha = depth_alpha . y ;
111115 fragment_list [i ]. depth = depth_alpha . x ;
112116 } else {
113- // The next fragment is farther than any of the sorted ones.
117+ // The next fragment is nearer than any of the sorted ones.
114118 // Blend it early.
115119 // This is an approximation.
116- final_color = blend (vec4f (color * depth_alpha . y , depth_alpha . y ), final_color );
120+ final_color = blend (final_color , vec4f (color * depth_alpha . y , depth_alpha . y ));
117121 }
118122 }
119123
@@ -122,7 +126,7 @@ fn resolve(header: u32, opaque_depth: f32) -> vec4<f32> {
122126 let color = fragment_list [i ]. color ;
123127 let alpha = fragment_list [i ]. alpha ;
124128 var base_color = vec4 (color . rgb * alpha , alpha );
125- final_color = blend (base_color , final_color );
129+ final_color = blend (final_color , base_color );
126130 if final_color . a == 1 .0 {
127131 break ;
128132 }
0 commit comments