Skip to content

Commit d8a022a

Browse files
authored
Render Debug Overlay (#22412)
# Objective - Make it easy to peek at the depth/normals/motion/hi-z ## Solution - Add a small crate and a plugin behind a flag ## Testing - Robust against components, deferred, etc --- ## Showcase https://github.com/user-attachments/assets/7d3d3ad9-b7b5-4a52-931f-b39587c843c9
1 parent b8d756d commit d8a022a

File tree

5 files changed

+844
-0
lines changed

5 files changed

+844
-0
lines changed

crates/bevy_dev_tools/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ bevy_app = { path = "../bevy_app", version = "0.19.0-dev" }
2020
bevy_asset = { path = "../bevy_asset", version = "0.19.0-dev" }
2121
bevy_camera = { path = "../bevy_camera", version = "0.19.0-dev" }
2222
bevy_color = { path = "../bevy_color", version = "0.19.0-dev" }
23+
bevy_core_pipeline = { path = "../bevy_core_pipeline", version = "0.19.0-dev" }
2324
bevy_diagnostic = { path = "../bevy_diagnostic", version = "0.19.0-dev" }
2425
bevy_ecs = { path = "../bevy_ecs", version = "0.19.0-dev" }
2526
bevy_image = { path = "../bevy_image", version = "0.19.0-dev" }
2627
bevy_input = { path = "../bevy_input", version = "0.19.0-dev" }
28+
bevy_log = { path = "../bevy_log", version = "0.19.0-dev" }
2729
bevy_math = { path = "../bevy_math", version = "0.19.0-dev" }
30+
bevy_pbr = { path = "../bevy_pbr", version = "0.19.0-dev" }
2831
bevy_picking = { path = "../bevy_picking", version = "0.19.0-dev" }
2932
bevy_render = { path = "../bevy_render", version = "0.19.0-dev" }
3033
bevy_reflect = { path = "../bevy_reflect", version = "0.19.0-dev" }
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#import bevy_pbr::mesh_view_bindings::view
2+
#import bevy_pbr::mesh_view_bindings::depth_prepass_texture
3+
#import bevy_pbr::mesh_view_bindings::normal_prepass_texture
4+
#import bevy_pbr::mesh_view_bindings::motion_vector_prepass_texture
5+
#import bevy_pbr::mesh_view_bindings::deferred_prepass_texture
6+
#import bevy_pbr::view_transformations::depth_ndc_to_view_z
7+
#import bevy_pbr::pbr_deferred_types::unpack_24bit_normal
8+
#import bevy_pbr::pbr_deferred_types::unpack_unorm4x8_
9+
#import bevy_pbr::pbr_deferred_types::unpack_unorm3x4_plus_unorm_20_
10+
#import bevy_pbr::rgb9e5::rgb9e5_to_vec3_
11+
#import bevy_pbr::utils::octahedral_decode
12+
13+
struct DebugBufferConfig {
14+
opacity: f32,
15+
mip_level: u32,
16+
}
17+
18+
@group(1) @binding(0) var<uniform> config: DebugBufferConfig;
19+
@group(1) @binding(1) var background_texture: texture_2d<f32>;
20+
@group(1) @binding(2) var background_sampler: sampler;
21+
22+
#ifdef DEBUG_DEPTH_PYRAMID
23+
@group(1) @binding(3) var depth_pyramid_texture: texture_2d<f32>;
24+
@group(1) @binding(4) var depth_pyramid_sampler: sampler;
25+
#endif
26+
27+
@fragment
28+
fn fragment(@builtin(position) frag_coord: vec4<f32>) -> @location(0) vec4<f32> {
29+
let uv = frag_coord.xy / view.viewport.zw;
30+
let background = textureSampleLevel(background_texture, background_sampler, uv, 0.0);
31+
var output_color: vec4<f32> = vec4(0.0);
32+
33+
#ifdef DEBUG_DEPTH
34+
#ifdef DEPTH_PREPASS
35+
let depth = textureLoad(depth_prepass_texture, vec2<i32>(frag_coord.xy), 0);
36+
output_color = vec4(vec3(depth), 1.0);
37+
#else
38+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
39+
#endif
40+
#endif
41+
42+
#ifdef DEBUG_NORMAL
43+
#ifdef NORMAL_PREPASS
44+
let normal_sample = textureLoad(normal_prepass_texture, vec2<i32>(frag_coord.xy), 0);
45+
output_color = vec4(normal_sample.xyz, 1.0);
46+
#else
47+
#ifdef DEFERRED_PREPASS
48+
let deferred = textureLoad(deferred_prepass_texture, vec2<i32>(frag_coord.xy), 0);
49+
let normal = octahedral_decode(unpack_24bit_normal(deferred.a));
50+
output_color = vec4(normal * 0.5 + 0.5, 1.0);
51+
#else
52+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
53+
#endif
54+
#endif
55+
#endif
56+
57+
#ifdef DEBUG_MOTION_VECTORS
58+
#ifdef MOTION_VECTOR_PREPASS
59+
let motion_vector = textureLoad(motion_vector_prepass_texture, vec2<i32>(frag_coord.xy), 0).rg;
60+
// These motion vectors are stored in a format where 1.0 represents full-screen movement.
61+
// We use a power curve to amplify small movements while keeping them centered.
62+
let mapped_motion = sign(motion_vector) * pow(abs(motion_vector), vec2(0.2)) * 0.5 + 0.5;
63+
output_color = vec4(mapped_motion, 0.5, 1.0);
64+
#else
65+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
66+
#endif
67+
#endif
68+
69+
#ifdef DEBUG_DEFERRED
70+
#ifdef DEFERRED_PREPASS
71+
let deferred = textureLoad(deferred_prepass_texture, vec2<i32>(frag_coord.xy), 0);
72+
output_color = vec4(vec3(f32(deferred.x) / 255.0, f32(deferred.y) / 255.0, f32(deferred.z) / 255.0), 1.0);
73+
#else
74+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
75+
#endif
76+
#endif
77+
78+
#ifdef DEBUG_DEFERRED_BASE_COLOR
79+
#ifdef DEFERRED_PREPASS
80+
let deferred = textureLoad(deferred_prepass_texture, vec2<i32>(frag_coord.xy), 0);
81+
let base_rough = unpack_unorm4x8_(deferred.x);
82+
output_color = vec4(pow(base_rough.rgb, vec3(2.2)), 1.0);
83+
#else
84+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
85+
#endif
86+
#endif
87+
88+
#ifdef DEBUG_DEFERRED_EMISSIVE
89+
#ifdef DEFERRED_PREPASS
90+
let deferred = textureLoad(deferred_prepass_texture, vec2<i32>(frag_coord.xy), 0);
91+
let emissive = rgb9e5_to_vec3_(deferred.y);
92+
output_color = vec4(emissive, 1.0);
93+
#else
94+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
95+
#endif
96+
#endif
97+
98+
#ifdef DEBUG_DEFERRED_METALLIC_ROUGHNESS
99+
#ifdef DEFERRED_PREPASS
100+
let deferred = textureLoad(deferred_prepass_texture, vec2<i32>(frag_coord.xy), 0);
101+
let base_rough = unpack_unorm4x8_(deferred.x);
102+
let props = unpack_unorm4x8_(deferred.z);
103+
// R: Reflectance, G: Metallic, B: Occlusion, A: Perceptual Roughness
104+
output_color = vec4(props.r, props.g, props.b, base_rough.a);
105+
#else
106+
output_color = vec4(1.0, 0.0, 1.0, 1.0);
107+
#endif
108+
#endif
109+
110+
#ifdef DEBUG_DEPTH_PYRAMID
111+
let depth_pyramid = textureSampleLevel(depth_pyramid_texture, depth_pyramid_sampler, uv, f32(config.mip_level)).r;
112+
output_color = vec4(vec3(depth_pyramid), 1.0);
113+
#endif
114+
115+
let alpha = output_color.a * config.opacity;
116+
return vec4(mix(background.rgb, output_color.rgb, alpha), 1.0);
117+
}

crates/bevy_dev_tools/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ pub mod picking_debug;
2020
pub mod states;
2121

2222
pub use easy_screenshot::*;
23+
24+
pub mod render_debug;

0 commit comments

Comments
 (0)