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// The vignette postprocessing effect.
3#define_import_path bevy_post_process::effect_stack::vignette
5#import bevy_post_process::effect_stack::chromatic_aberration::source_texture
7// See `bevy_post_process::effect_stack::Vignette` for more
8// information on these fields.
9struct VignetteSettings {
10 intensity: f32,
11 radius: f32,
12 smoothness: f32,
13 roundness: f32,
14 center: vec2<f32>,
15 edge_compensation: f32,
16 unused: u32,
17 color: vec4<f32>
20const VISUAL_THRESHOLD: f32 = 1e-4;
22// The settings supplied by the developer.
23@group(0) @binding(4) var<uniform> vignette_settings: VignetteSettings;
25fn vignette(uv: vec2<f32>, color: vec3<f32>) -> vec3<f32> {
26 let intensity = vignette_settings.intensity;
27 if (intensity < VISUAL_THRESHOLD) {
28 return color;
29 }
30 let radius = vignette_settings.radius;
31 let smoothness = vignette_settings.smoothness;
32 let roundness = vignette_settings.roundness;
33 let edge_comp = vignette_settings.edge_compensation;
35 // Get the screen resolution.
36 let dims = textureDimensions(source_texture);
37 let resolution = vec2<f32>(dims.xy);
38 let screen_aspect = resolution.x / resolution.y;
40 // Calculate the aspect ratio.
41 //
42 // We divide by the smallest dimension to normalize the scale.
43 // This will be used later to force the vignette to be circular, not oval.
44 let aspect_ratio = resolution / min(resolution.x, resolution.y);
46 // Center the UV coordinates at (0,0).
47 let centered_uv = uv - 0.5;
49 // Calculate the normalized offset from the center.
50 //
51 // (vignette_settings.center - 0.5) maps the 0.0-1.0 input to -0.5-0.5.
52 // Multiplying by (1.0, y/x) compensates for the screen's aspect ratio.
53 // This ensures that a movement of 0.1 looks the same distance horizontally and vertically.
54 let offset = (vignette_settings.center - 0.5) * vec2<f32>(1.0, resolution.y / resolution.x);
56 let uv_from_center = centered_uv - offset;
57 var scale_vec = aspect_ratio * vec2<f32>(1.0, 1.0 / roundness);
59 // Apply edge compensation to make the vignette fit the screen better.
60 if (screen_aspect >= 1.0) {
61 let compensation_factor = mix(1.0, 1.0 / screen_aspect, edge_comp);
62 scale_vec.x *= compensation_factor;
63 } else {
64 let compensation_factor = mix(1.0, screen_aspect, edge_comp);
65 scale_vec.y *= compensation_factor;
66 }
68 let final_uv = uv_from_center * scale_vec;
70 // Calculate distance from center.
71 let dist = length(final_uv) * (1.0 / radius);
72 let base_curve = 1.0 - (dist * dist);
73 let clamped_factor = clamp(base_curve, 0.0, 1.0);
74 let factor = pow(clamped_factor, smoothness);
76 // Blend the original color with the vignette color.
77 return mix(color, vignette_settings.color.rgb, (1.0 - factor) * intensity);
Contents