Search across packages, versions, files, declarations, and comments. Use multiple terms to narrow results (AND), and add @vertex, @fragment, or @compute to filter by shader stage.
1#define_import_path bevy_core_pipeline::oit
3#import bevy_pbr::mesh_view_bindings::{view, oit_nodes_capacity, oit_nodes, oit_heads, oit_atomic_counter, oit_settings}
4#import bevy_pbr::mesh_view_types::OitFragmentNode
5#import bevy_pbr::prepass_utils
7#ifdef OIT_ENABLED
8// Add the fragment to the oit buffer
9fn oit_draw(position: vec4f, color: vec4f) {
10#ifdef DEPTH_PREPASS
11 if position.z < prepass_utils::prepass_depth(position, 0u) {
12 return;
13 }
14#endif
15 // Don't add fully transparent fragments to the list
16 // because we don't want to have to sort them in the resolve pass
17 if color.a < oit_settings.alpha_threshold {
18 return;
19 }
20 // get the index of the current fragment relative to the screen size
21 let screen_index = u32(floor(position.x) + floor(position.y) * view.viewport.z);
23 var new_node_index = atomicAdd(&oit_atomic_counter, 1u);
24 // exit early if we've reached the maximum amount of fragments nodes
25 if new_node_index >= oit_nodes_capacity {
26 // TODO for tail blending we should return the color here
27 return;
28 }
30 var node: OitFragmentNode;
31 // In `oit_heads` buffer, index starts from 1, end sentinel is 0 so that we can avoid writing `u32::MAX` from CPU. wgpu guarantees buffers are zero-initialized.
32 node.next = atomicExchange(&oit_heads[screen_index], new_node_index + 1u) - 1u;
33 node.color = bevy_pbr::rgb9e5::vec3_to_rgb9e5_(color.rgb);
34 node.depth_alpha = pack_24bit_depth_8bit_alpha(position.z, color.a);
35 oit_nodes[new_node_index] = node;
37#endif // OIT_ENABLED
39// The packing scheme puts depth in the higher bits so that
40// depth(a) < depth(b) <=> packed(a) < packed(b)
41// irregardless of alpha(a) and alpha(b)
42// The property is used to optimize the resolve step
43fn pack_24bit_depth_8bit_alpha(depth: f32, alpha: f32) -> u32 {
44 let depth_bits = u32(saturate(depth) * f32(0xFFFFFFu) + 0.5);
45 let alpha_bits = u32(saturate(alpha) * f32(0xFFu) + 0.5);
46 return (depth_bits << 8u) | alpha_bits;
49fn unpack_24bit_depth_8bit_alpha(packed: u32) -> vec2<f32> {
50 let depth_bits = packed >> 8u;
51 let alpha_bits = packed & 0xFFu;
52 return vec2(f32(depth_bits) / f32(0xFFFFFFu), f32(alpha_bits) / f32(0xFFu));
Contents