diff --git a/src/application.rs b/src/application.rs index 3a45b7a..932494c 100644 --- a/src/application.rs +++ b/src/application.rs @@ -132,7 +132,11 @@ impl Application { (size.width - INITIAL_SIDEBAR_WIDTH as u32, size.height), Some("texture"), ); - let reference_view_texture = Texture::new(&device, (200, 200), Some("reference_texture")); + let reference_view_texture = Texture::new( + &device, + (INITIAL_SIDEBAR_WIDTH as u32, INITIAL_SIDEBAR_WIDTH as u32), + Some("reference_texture"), + ); let gui = Gui::new( size, diff --git a/src/compute.wgsl b/src/compute.wgsl index 831ffbf..303baba 100644 --- a/src/compute.wgsl +++ b/src/compute.wgsl @@ -56,12 +56,37 @@ let linear_mode: bool = false; let use_lighting: bool = true; let eps: f32 = 0.0000001; -fn rotate(phi: f32) -> mat4x4 { - return mat4x4( - vec4(cos(phi), sin(phi), 0.0, 0.0), - vec4(-sin(phi), cos(phi), 0.0, 0.0), - vec4(0.0, 0.0, 1.0, 0.0), - vec4(0.0, 0.0, 0.0, 1.0), +let PI: f32 = 3.141592653589793; + +fn rotateX(v: vec3, phi: f32) -> vec3 { + return mat3x3( + vec3(1.0, 0.0, 0.0), + vec3(0.0, cos(phi), sin(phi)), + vec3(0.0, -sin(phi), cos(phi)), + ) * v; +} + +fn rotateY(v: vec3, phi: f32) -> vec3 { + return mat3x3( + vec3(cos(phi), 0.0, -sin(phi)), + vec3(0.0, 1.0, 0.0), + vec3(sin(phi), 0.0, cos(phi)), + ) * v; +} + +fn rotateZ(v: vec3, phi: f32) -> vec3 { + return mat3x3( + vec3(cos(phi), sin(phi), 0.0), + vec3(-sin(phi), cos(phi), 0.0), + vec3(0.0, 0.0, 0.0), + ) * v; +} + +fn translate(v: vec3, dx: f32, dy: f32, dz: f32) -> vec3 { + return vec3( + v.x + dx, + v.y + dy, + v.z + dz, ); } @@ -138,8 +163,8 @@ fn ray_color(origin: vec3, direction: vec3, max_dist: f32) -> vec4, dim: vec2) -> vec2 { - let x = round(((point.x + 1.0) / 1.05 + 0.01) * f32(dim.x)); - let y = round(((point.z + 1.0) / 1.05 + 0.01) * f32(dim.y)); + let x = round(((point.x + 1.0) / 2.0 + 0.25) * f32(dim.x)); + let y = round(((point.z + 1.0) / 2.0 + 0.25) * f32(dim.y)); return vec2(i32(x), i32(y)); } @@ -152,14 +177,16 @@ fn draw_reference_point(p: vec3, color: vec4) { } fn nonlinear_ray_color(start_point: vec3, start_dir: vec3) -> vec4 { - let h = 0.5; + let h = 0.25; let steps = 100; var cur_point: vec3 = start_point; var cur_dir: vec3 = start_dir; var color: vec4; for (var i: i32 = 0; i < steps; i = i + 1) { - draw_reference_point(cur_point, vec4(1.0, 1.0, 1.0, 1.0)); + if (i % 2 == 0) { + draw_reference_point(cur_point, vec4(1.0, 1.0, 1.0, 1.0)); + } // Runge-Kutta method let k1 = vector_fn(cur_point, cur_dir); diff --git a/src/functions.rs b/src/functions.rs index 38a2984..5e273a4 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -1,6 +1,8 @@ #[derive(Debug, PartialEq)] pub enum PredefinedFunction { Custom, + TranslationX, + TranslationZ, Rotation, LorenzAttractor, RoesslerAttractor, @@ -10,6 +12,8 @@ impl ToString for PredefinedFunction { fn to_string(&self) -> String { match self { Self::Custom => "Custom".to_string(), + Self::TranslationX => "Translation (x-axis)".to_string(), + Self::TranslationZ => "Translation (z-axis)".to_string(), Self::Rotation => "Rotation".to_string(), Self::LorenzAttractor => "Lorenz attractor".to_string(), Self::RoesslerAttractor => "Roessler attractor".to_string(), @@ -21,11 +25,17 @@ impl PredefinedFunction { pub fn to_code(&self) -> String { match self { Self::Custom => "".to_string(), - Self::Rotation => "let phi = 1.5; -let A = rotate(phi); -let u = A * vec4(v, 1.0); -return u.xyz;" + Self::TranslationX => "let dx = 0.001; +let dy = 0.000; +let dz = 0.000; +return translate(v, dx, dy, dz);" .to_string(), + Self::TranslationZ => "let dx = 0.000; +let dy = 0.000; +let dz = 0.005; +return translate(v, dx, dy, dz);" + .to_string(), + Self::Rotation => "return rotateZ(v, PI / 2.0);".to_string(), Self::LorenzAttractor => "let rho = 28.0; let sigma = 10.0; let beta = 8.0 / 3.0; @@ -33,8 +43,8 @@ return vec3( sigma * (p.y - p.x), p.x * (rho - p.z) - p.y, p.x * p.y - beta * p.z, -);" - .to_string(), +) / 1000.0;" + .to_string(), Self::RoesslerAttractor => "let a = 0.1; let b = 0.1; let c = 14.0; @@ -42,8 +52,8 @@ return vec3( -p.y - p.z, p.x + a * p.y, b + p.z * (p.x - c), -);" - .to_string(), +) / 100.0;" + .to_string(), } } } diff --git a/src/gui.rs b/src/gui.rs index 430b1a9..d91bb4f 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -8,7 +8,7 @@ use winit::{dpi::PhysicalSize, event::Event}; use crate::{arcball::CameraOperation, functions::PredefinedFunction}; -pub const INITIAL_SIDEBAR_WIDTH: f32 = 200.0; +pub const INITIAL_SIDEBAR_WIDTH: f32 = 500.0; pub struct Gui { platform: Platform, @@ -70,9 +70,9 @@ impl Gui { shader_error: None, rotate_scene: false, - field_weight: 0.05, - predefined_function: PredefinedFunction::Rotation, - field_function: PredefinedFunction::Rotation.to_code(), + field_weight: 0.001, + predefined_function: PredefinedFunction::TranslationX, + field_function: PredefinedFunction::TranslationX.to_code(), rotate_scene_changed: false, field_weight_changed: false, @@ -139,6 +139,28 @@ impl Gui { egui::ComboBox::from_label("Predefined function") .selected_text(predefined_function.to_string()) .show_ui(ui, |ui| { + if ui + .selectable_value( + predefined_function, + PredefinedFunction::TranslationX, + PredefinedFunction::TranslationX.to_string(), + ) + .clicked() + { + *field_function = PredefinedFunction::TranslationX.to_code(); + *field_function_changed = true; + } + if ui + .selectable_value( + predefined_function, + PredefinedFunction::TranslationZ, + PredefinedFunction::TranslationZ.to_string(), + ) + .clicked() + { + *field_function = PredefinedFunction::TranslationZ.to_code(); + *field_function_changed = true; + } if ui .selectable_value( predefined_function, @@ -183,7 +205,10 @@ impl Gui { ui.label(format!("Shader error: {}", shader_error)); } }); - ui.image(reference_view_texture_id, (200.0, 200.0)); + ui.image( + reference_view_texture_id, + (INITIAL_SIDEBAR_WIDTH, INITIAL_SIDEBAR_WIDTH), + ); }); egui::CentralPanel::default() .show(ctx, |ui| {