|
| 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 | +} |
0 commit comments