Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
61a1e0c
Implement per-pixel linked list for OIT
beicause Nov 14, 2025
8a3c399
update
beicause Nov 14, 2025
7ebd383
Fix
beicause Nov 14, 2025
9d0dbc3
make use of depth prepass to filter out fragments
beicause Nov 16, 2025
c414d2e
Fix corrupted linked list on startup
beicause Nov 16, 2025
395acf0
change OIT default value
beicause Nov 26, 2025
a2583f6
Sort in desc order and fix early termination in blending
beicause Nov 26, 2025
cd963ea
Merge remote-tracking branch 'upstream' into oit-opt
beicause Nov 26, 2025
6398884
format
beicause Nov 26, 2025
a8028b5
fmt
beicause Dec 6, 2025
ae57011
Merge remote-tracking branch 'upstream' into oit-opt
beicause Dec 6, 2025
1fbeaa7
Merge remote-tracking branch 'upstream' into oit-opt
beicause Jan 9, 2026
2babad2
Rename header -> head
beicause Jan 9, 2026
0290b64
Add some methods and optimizations in buffer vec
beicause Jan 10, 2026
c07054a
Avoid writing oit heads buffer by offseting values by 1
beicause Jan 10, 2026
41fb34a
Save local memory for sorted frags
beicause Jan 12, 2026
fe52562
Merge remote-tracking branch 'upstream/main' into oit-opt
beicause Jan 12, 2026
545d99a
Store packed depth and alpha to save local memory
goodartistscopy Jan 12, 2026
77c783d
Swap depth/alpha in packed repr. to make it monotonic with depth
goodartistscopy Jan 12, 2026
47b9642
Finalize previous commit
goodartistscopy Jan 12, 2026
706529f
Merge branch 'oit-depth-opt' into oit-opt
beicause Jan 12, 2026
1c68b0d
beicause Jan 12, 2026
e98bee5
Merge remote-tracking branch 'upstream/main' into oit-opt
beicause Jan 29, 2026
a97aa85
Fix merging
beicause Jan 29, 2026
ab1e342
Merge remote-tracking branch 'upstream/main' into oit-opt
beicause Feb 5, 2026
e955608
docs, rm unnecessary clone
beicause Feb 5, 2026
4c7c38e
Bind oit nodes buffer capacity
beicause Feb 5, 2026
23feaa2
Release oit buffers if no camera enables OIT
beicause Feb 5, 2026
2b3dd5f
Resize oit buffers instead of reserve when changed
beicause Feb 5, 2026
d455ee5
CI
beicause Feb 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions crates/bevy_core_pipeline/src/oit/resolve/oit_resolve.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#endif

struct OitFragment {
color: vec3<f32>,
color: u32,
alpha: f32,
depth: f32,
}
Expand Down Expand Up @@ -65,8 +65,7 @@ fn resolve(head: u32, opaque_depth: f32) -> vec4<f32> {
var sorted_frag_count = 0u;
while current_node != LINKED_LIST_END_SENTINEL {
let fragment_node = nodes[current_node];
// unpack color, alpha, depth
let color = bevy_pbr::rgb9e5::rgb9e5_to_vec3_(fragment_node.color);
// unpack alpha, depth, except color to save local memory.
Comment thread
beicause marked this conversation as resolved.
Outdated
let depth_alpha = bevy_core_pipeline::oit::unpack_24bit_depth_8bit_alpha(fragment_node.depth_alpha);
current_node = fragment_node.next;

Expand All @@ -89,7 +88,7 @@ fn resolve(head: u32, opaque_depth: f32) -> vec4<f32> {
break;
}
}
fragment_list[i].color = color;
fragment_list[i].color = fragment_node.color;
fragment_list[i].alpha = depth_alpha.y;
fragment_list[i].depth = depth_alpha.x;
sorted_frag_count += 1;
Expand All @@ -98,7 +97,7 @@ fn resolve(head: u32, opaque_depth: f32) -> vec4<f32> {
// First, make room by blending the nearest fragment from the sorted list.
// Then, insert the fragment in the sorted list.
// This is an approximation.
let nearest_color = fragment_list[0].color;
let nearest_color = bevy_pbr::rgb9e5::rgb9e5_to_vec3_(fragment_list[0].color);
let nearest_alpha = fragment_list[0].alpha;
final_color = blend(final_color, vec4f(nearest_color * nearest_alpha, nearest_alpha));
var i = 0u;
Expand All @@ -110,20 +109,21 @@ fn resolve(head: u32, opaque_depth: f32) -> vec4<f32> {
break;
}
}
fragment_list[i].color = color;
fragment_list[i].color = fragment_node.color;
fragment_list[i].alpha = depth_alpha.y;
fragment_list[i].depth = depth_alpha.x;
} else {
// The next fragment is nearer than any of the sorted ones.
// Blend it early.
// This is an approximation.
let color = bevy_pbr::rgb9e5::rgb9e5_to_vec3_(fragment_node.color);
final_color = blend(final_color, vec4f(color * depth_alpha.y, depth_alpha.y));
}
}

// blend sorted fragments
for (var i = 0u; i < sorted_frag_count; i += 1) {
let color = fragment_list[i].color;
let color = bevy_pbr::rgb9e5::rgb9e5_to_vec3_(fragment_list[i].color);
let alpha = fragment_list[i].alpha;
var base_color = vec4(color.rgb * alpha, alpha);
final_color = blend(final_color, base_color);
Expand Down