1pub trait ExposeHud {
2 fn populate_hud(&mut self, ui: &mut egui::Ui);
3}
4
5impl ExposeHud for blade_render::RayConfig {
6 fn populate_hud(&mut self, ui: &mut egui::Ui) {
7 ui.add(
8 egui::Slider::new(&mut self.num_environment_samples, 1..=100u32)
9 .text("Num env samples")
10 .logarithmic(true),
11 );
12 ui.checkbox(
13 &mut self.environment_importance_sampling,
14 "Env importance sampling",
15 );
16 ui.add(egui::widgets::Slider::new(&mut self.tap_count, 0..=10).text("Tap count"));
17 ui.add(egui::widgets::Slider::new(&mut self.tap_radius, 1..=50).text("Tap radius (px)"));
18 ui.add(
19 egui::widgets::Slider::new(&mut self.tap_confidence_near, 1..=50)
20 .text("Max confidence"),
21 );
22 ui.add(
23 egui::widgets::Slider::new(&mut self.tap_confidence_far, 1..=50).text("Min confidence"),
24 );
25 ui.add(
26 egui::widgets::Slider::new(&mut self.t_start, 0.001..=0.5)
27 .text("T min")
28 .logarithmic(true),
29 );
30 ui.checkbox(&mut self.pairwise_mis, "Pairwise MIS");
31 ui.add(
32 egui::widgets::Slider::new(&mut self.defensive_mis, 0.0..=1.0).text("Defensive MIS"),
33 );
34 }
35}
36
37impl ExposeHud for blade_render::DenoiserConfig {
38 fn populate_hud(&mut self, ui: &mut egui::Ui) {
39 ui.add(egui::Slider::new(&mut self.temporal_weight, 0.0..=1.0f32).text("Temporal weight"));
40 ui.add(egui::Slider::new(&mut self.num_passes, 0..=5u32).text("A-trous passes"));
41 }
42}
43
44impl ExposeHud for blade_render::PostProcConfig {
45 fn populate_hud(&mut self, ui: &mut egui::Ui) {
46 ui.add(
47 egui::Slider::new(&mut self.average_luminocity, 0.1f32..=1_000f32)
48 .text("Average luminocity")
49 .logarithmic(true),
50 );
51 ui.add(
52 egui::Slider::new(&mut self.exposure_key_value, 0.01f32..=10f32)
53 .text("Key value")
54 .logarithmic(true),
55 );
56 ui.add(egui::Slider::new(&mut self.white_level, 0.1f32..=2f32).text("White level"));
57 }
58}
59
60impl ExposeHud for blade_render::DebugConfig {
61 fn populate_hud(&mut self, ui: &mut egui::Ui) {
62 use strum::IntoEnumIterator as _;
63
64 egui::ComboBox::from_label("View mode")
65 .selected_text(format!("{:?}", self.view_mode))
66 .show_ui(ui, |ui| {
67 for value in blade_render::DebugMode::iter() {
68 ui.selectable_value(&mut self.view_mode, value, format!("{value:?}"));
69 }
70 });
71
72 ui.label("Draw debug:");
73 for (name, bit) in blade_render::DebugDrawFlags::all().iter_names() {
74 let mut enabled = self.draw_flags.contains(bit);
75 ui.checkbox(&mut enabled, name);
76 self.draw_flags.set(bit, enabled);
77 }
78 ui.label("Ignore textures:");
79 for (name, bit) in blade_render::DebugTextureFlags::all().iter_names() {
80 let mut enabled = self.texture_flags.contains(bit);
81 ui.checkbox(&mut enabled, name);
82 self.texture_flags.set(bit, enabled);
83 }
84 }
85}
86
87pub fn populate_debug_selection(
88 mouse_pos: &mut Option<[i32; 2]>,
89 selection: &blade_render::SelectionInfo,
90 asset_hub: &blade_render::AssetHub,
91 ui: &mut egui::Ui,
92) {
93 let screen_pos = match *mouse_pos {
94 Some(pos) => pos,
95 None => return,
96 };
97
98 let style = ui.style();
99 egui::Frame::group(style).show(ui, |ui| {
100 ui.horizontal(|ui| {
101 ui.label("Pixel:");
102 ui.colored_label(
103 egui::Color32::WHITE,
104 format!("{}x{}", screen_pos[0], screen_pos[1]),
105 );
106 if ui.button("Unselect").clicked() {
107 *mouse_pos = None;
108 }
109 });
110 ui.horizontal(|ui| {
111 let sd = &selection.std_deviation;
112 ui.label("Std Deviation:");
113 ui.colored_label(
114 egui::Color32::WHITE,
115 format!("{:.2} {:.2} {:.2}", sd.x, sd.y, sd.z),
116 );
117 });
118 ui.horizontal(|ui| {
119 ui.label("Samples:");
120 let power = selection
121 .std_deviation_history
122 .next_power_of_two()
123 .trailing_zeros();
124 ui.colored_label(egui::Color32::WHITE, format!("2^{}", power));
125 });
126 ui.horizontal(|ui| {
127 ui.label("Depth:");
128 ui.colored_label(egui::Color32::WHITE, format!("{:.2}", selection.depth));
129 });
130 ui.horizontal(|ui| {
131 let tc = &selection.tex_coords;
132 ui.label("Texture coords:");
133 ui.colored_label(egui::Color32::WHITE, format!("{:.2} {:.2}", tc.x, tc.y));
134 });
135 ui.horizontal(|ui| {
136 let wp = &selection.position;
137 ui.label("World pos:");
138 ui.colored_label(
139 egui::Color32::WHITE,
140 format!("{:.2} {:.2} {:.2}", wp.x, wp.y, wp.z),
141 );
142 });
143 ui.horizontal(|ui| {
144 ui.label("Base color:");
145 if let Some(handle) = selection.base_color_texture {
146 let name = asset_hub
147 .textures
148 .get_main_source_path(handle)
149 .map(|path| path.display().to_string())
150 .unwrap_or_default();
151 ui.colored_label(egui::Color32::WHITE, name);
152 }
153 });
154 ui.horizontal(|ui| {
155 ui.label("Normal:");
156 if let Some(handle) = selection.normal_texture {
157 let name = asset_hub
158 .textures
159 .get_main_source_path(handle)
160 .map(|path| path.display().to_string())
161 .unwrap_or_default();
162 ui.colored_label(egui::Color32::WHITE, name);
163 }
164 });
165 });
166}