calculate predicted render time

This commit is contained in:
Crispy 2023-07-14 14:30:31 +02:00
parent 583299c136
commit 8b4dcb39c8
2 changed files with 48 additions and 46 deletions

View file

@ -7,7 +7,7 @@ pub struct RenderOptions {
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,
pub unit_width: f64, pub unit_width: f64,
pub max_iterations: u32, pub iterations: u32,
pub cx: f64, pub cx: f64,
pub cy: f64, pub cy: f64,
pub fill_style: FillStyle, pub fill_style: FillStyle,
@ -25,7 +25,7 @@ impl Default for RenderOptions {
width: 512, width: 512,
height: 512, height: 512,
unit_width: 4.0, unit_width: 4.0,
max_iterations: 128, iterations: 128,
cx: -0.8, cx: -0.8,
cy: -0.27, cy: -0.27,
fill_style: FillStyle::Bright, fill_style: FillStyle::Bright,
@ -49,8 +49,8 @@ pub fn view_point(q: &RenderOptions, image: RgbImage) -> RgbImage {
pub fn render(q: &RenderOptions, color: (u8, u8, u8)) -> RgbImage { pub fn render(q: &RenderOptions, color: (u8, u8, u8)) -> RgbImage {
let img = RgbImage::new(q.width, q.height); let img = RgbImage::new(q.width, q.height);
apply_fn(img, q, |x, y| { apply_fn(img, q, |x, y| {
let i = julia(x, y, q.cx, q.cy, q.max_iterations); let i = julia(x, y, q.cx, q.cy, q.iterations);
if q.fill_style == FillStyle::Black && i == q.max_iterations { if q.fill_style == FillStyle::Black && i == q.iterations {
None None
} else { } else {
let i = i.min(255) as u8; let i = i.min(255) as u8;

View file

@ -41,7 +41,7 @@ struct JuliaGUI {
color: (u8, u8, u8), color: (u8, u8, u8),
#[serde(skip)] #[serde(skip)]
preview: Option<TextureHandle>, preview: Option<TextureHandle>,
render_options: RenderOptions, settings: RenderOptions,
#[serde(skip)] #[serde(skip)]
preview_render_ms: f64, preview_render_ms: f64,
#[serde(skip)] #[serde(skip)]
@ -73,7 +73,7 @@ impl Default for JuliaGUI {
Self { Self {
color: (12, 5, 10), color: (12, 5, 10),
preview: None, preview: None,
render_options: RenderOptions::default(), settings: RenderOptions::default(),
preview_render_ms: 0.0, preview_render_ms: 0.0,
export_render_ms: None, export_render_ms: None,
export_res_power: 3, export_res_power: 3,
@ -142,9 +142,9 @@ impl JuliaGUI {
fn update_preview(&mut self) { fn update_preview(&mut self) {
let start_time = SystemTime::now(); let start_time = SystemTime::now();
let mut frame = render(&self.render_options, self.color); let mut frame = render(&self.settings, self.color);
if self.preview_point { if self.preview_point {
frame = view_point(&self.render_options, frame); frame = view_point(&self.settings, frame);
} }
if let Some(preview) = &mut self.preview { if let Some(preview) = &mut self.preview {
@ -164,10 +164,10 @@ impl JuliaGUI {
if let Some(channel) = &self.render_thread { if let Some(channel) = &self.render_thread {
let res_mul = 1 << self.export_res_power; let res_mul = 1 << self.export_res_power;
let settings = RenderOptions { let settings = RenderOptions {
width: self.render_options.width * res_mul, width: self.settings.width * res_mul,
height: self.render_options.height * res_mul, height: self.settings.height * res_mul,
max_iterations: self.export_iterations, iterations: self.export_iterations,
..self.render_options.clone() ..self.settings.clone()
}; };
channel channel
@ -217,23 +217,18 @@ impl eframe::App for JuliaGUI {
let set_point_vis = ui.checkbox(&mut self.preview_point, "View C point"); let set_point_vis = ui.checkbox(&mut self.preview_point, "View C point");
ui.label("C point (X, Y):"); ui.label("C point (X, Y):");
let set_cx = ui.add(Slider::new(&mut self.render_options.cx, -2.0..=2.0)); let set_cx =
let set_cy = ui.add(Slider::new(&mut self.render_options.cy, -2.0..=2.0)); ui.add(Slider::new(&mut self.settings.cx, -1.0..=1.0).clamp_to_range(false));
let set_cy =
ui.add(Slider::new(&mut self.settings.cy, -1.0..=1.0).clamp_to_range(false));
ui.label("render width:"); ui.label("render width:");
let set_unit_width = let set_unit_width = ui.add(Slider::new(&mut self.settings.unit_width, 0.1..=6.0));
ui.add(Slider::new(&mut self.render_options.unit_width, 0.1..=6.0));
ui.label("Fill style:"); ui.label("Fill style:");
ui.horizontal(|ui| { ui.horizontal(|ui| {
let set_black = ui.radio_value( let set_black =
&mut self.render_options.fill_style, ui.radio_value(&mut self.settings.fill_style, FillStyle::Black, "Black");
FillStyle::Black, let set_bright =
"Black", ui.radio_value(&mut self.settings.fill_style, FillStyle::Bright, "Bright");
);
let set_bright = ui.radio_value(
&mut self.render_options.fill_style,
FillStyle::Bright,
"Bright",
);
if set_bright.changed() || set_black.changed() { if set_bright.changed() || set_black.changed() {
self.settings_changed = true; self.settings_changed = true;
} }
@ -277,22 +272,19 @@ impl eframe::App for JuliaGUI {
let set_blue = ui.add(Slider::new(&mut self.color.2, 0..=16)); let set_blue = ui.add(Slider::new(&mut self.color.2, 0..=16));
ui.label("Preview iterations:"); ui.label("Preview iterations:");
let set_iter = ui.add( let set_iter = ui
Slider::new(&mut self.render_options.max_iterations, 5..=256) .add(Slider::new(&mut self.settings.iterations, 5..=256).clamp_to_range(false));
.clamp_to_range(false),
);
ui.label(RichText::new("Render settings").heading());
ui.label("Preview resolution:"); ui.label("Preview resolution:");
ui.horizontal(|ui| { ui.horizontal(|ui| {
let set_width = ui.add( let set_width = ui.add(
DragValue::new(&mut self.render_options.width) DragValue::new(&mut self.settings.width)
.clamp_range(128..=2048) .clamp_range(128..=2048)
.suffix("px"), .suffix("px"),
); );
ui.label("x"); ui.label("x");
let set_height = ui.add( let set_height = ui.add(
DragValue::new(&mut self.render_options.height) DragValue::new(&mut self.settings.height)
.clamp_range(128..=2048) .clamp_range(128..=2048)
.suffix("px"), .suffix("px"),
); );
@ -302,23 +294,18 @@ impl eframe::App for JuliaGUI {
}); });
ui.menu_button("presets", |ui| { ui.menu_button("presets", |ui| {
if ui.button("1:1 512x512").clicked() { if ui.button("1:1 512x512").clicked() {
self.render_options.width = 512; self.settings.width = 512;
self.render_options.height = 512; self.settings.height = 512;
self.settings_changed = true; self.settings_changed = true;
} }
if ui.button("16:9 960x540 (half hd)").clicked() { if ui.button("16:9 960x540 (half hd)").clicked() {
self.render_options.width = 960; self.settings.width = 960;
self.render_options.height = 540; self.settings.height = 540;
self.settings_changed = true;
}
if ui.button("4:3 640x540").clicked() {
self.render_options.width = 640;
self.render_options.height = 540;
self.settings_changed = true; self.settings_changed = true;
} }
if ui.button("2:1 1024x512").clicked() { if ui.button("2:1 1024x512").clicked() {
self.render_options.width = 1024; self.settings.width = 1024;
self.render_options.height = 512; self.settings.height = 512;
self.settings_changed = true; self.settings_changed = true;
} }
}); });
@ -329,8 +316,8 @@ impl eframe::App for JuliaGUI {
ui.add(Slider::new(&mut self.export_res_power, 0..=6).clamp_to_range(false)); ui.add(Slider::new(&mut self.export_res_power, 0..=6).clamp_to_range(false));
ui.label(format!( ui.label(format!(
"Render resolution: {}x{}", "Render resolution: {}x{}",
(1 << self.export_res_power) * self.render_options.width, (1 << self.export_res_power) * self.settings.width,
(1 << self.export_res_power) * self.render_options.height (1 << self.export_res_power) * self.settings.height
)); ));
ui.horizontal(|ui| { ui.horizontal(|ui| {
@ -358,6 +345,21 @@ impl eframe::App for JuliaGUI {
.to_string_lossy() .to_string_lossy()
.to_string(), .to_string(),
); );
let predicted_render_time = (self.preview_render_ms
* (1 << self.export_res_power * 2) as f64
* (self.export_iterations as f64 / self.settings.iterations as f64)
/ 1000.0)
.floor();
if predicted_render_time < 60.0 {
ui.label(format!("Predicted render time: {predicted_render_time}s"));
} else {
ui.label(format!(
"Predicted render time: {:.1} min",
predicted_render_time / 60.0
));
}
if let Some(ms) = self.export_render_ms { if let Some(ms) = self.export_render_ms {
ui.label(format!("(took {ms:.2}ms)")); ui.label(format!("(took {ms:.2}ms)"));
} }