diff options
author | pommicket <pommicket@gmail.com> | 2022-12-11 19:21:19 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-12-11 19:21:19 -0500 |
commit | 35456c299b91a8765422e184895e45377fd439b4 (patch) | |
tree | 734fcf8bd3d150f1d966dc65307cf29d08319426 /src/main.rs | |
parent | 1d06c1f0d3fa058b67e8fe999c654d10d7f46896 (diff) |
rotation , but it looks weird
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 132 |
1 files changed, 128 insertions, 4 deletions
diff --git a/src/main.rs b/src/main.rs index fdd2f54..dc29e2b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,134 @@ +extern crate nalgebra; + mod sdl; pub mod win; +pub mod sdf; + +use nalgebra::{Vector3, Matrix3, Rotation3}; +type Vec3 = Vector3<f32>; +type Mat3 = Matrix3<f32>; +type Rot3 = Rotation3<f32>; + +struct View { + pos: Vec3, + yaw: f32, + pitch: f32 +} + +impl Default for View { + fn default() -> Self { + Self { + pos: Vec3::zeros(), + yaw: 0.0, + pitch: 0.0 + } + } +} + +impl View { + /// `camera_rotation() * vec3(0, 0, -1)` is the direction the camera is pointing + fn camera_rotation(&self) -> Mat3 { + *Rot3::from_euler_angles(self.pitch, self.yaw, 0.0).matrix() + } +} + fn try_main() -> Result<(), String> { + let my_sdf = sdf::Sdf::sphere(); + let mut window = win::Window::new("AutoSDF", 1280, 720, true) .map_err(|e| format!("Error creating window: {e}"))?; + let mut fshader_source = String::new(); + fshader_source.push_str(" +IN vec2 pos; +uniform vec3 u_camera_position; +uniform mat3 u_camera_rotation; +"); + my_sdf.to_glsl(&mut fshader_source); + fshader_source.push_str(" +#define ITERATIONS 30 +#define AA_X 2 +#define AA_Y 2 + + + +float fbm(vec3 p) { + float t = 0.0; + float freq = 24.0; + mat3 m = mat3(cos(1.),sin(1.),0, + -sin(1.),cos(1.),0, + 0, 0, 1) * mat3( + 1, 0, 0, + 0, cos(1.),sin(1.), + 0, -sin(1.),cos(1.) + ); + for(int i = 0; i < 5; i++) + { + p = m * p; + t += pow(0.6, float(i)) * sin(freq*p.x)*sin(freq*p.y)*sin(freq*p.z); + freq *= 2.0; + } + return t; +} + +vec3 normal(vec3 p) +{ +// thanks to https://iquilezles.org/articles/normalsSDF/ + float h = 0.0001; + vec2 k = vec2(1.,-1.); + vec3 sdf_normal = k.xyy*sdf(p + k.xyy*h) + + k.yyx*sdf(p + k.yyx*h) + + k.yxy*sdf(p + k.yxy*h) + + k.xxx*sdf(p + k.xxx*h); + vec3 noise_normal = k.xyy*fbm(p + k.xyy*h) + + k.yyx*fbm(p + k.yyx*h) + + k.yxy*fbm(p + k.yxy*h) + + k.xxx*fbm(p + k.xxx*h); + return normalize(sdf_normal + 0.003 * noise_normal); +} + +void main() { + float focal_length = 0.3; + float min_dist = 10.; + vec2 inv_screen_size = 1.0 / vec2(1280.0, 720.0); // @TODO + vec2 aa_delta = inv_screen_size / vec2(AA_X, AA_Y); + vec3 final_color = vec3(0); + for (int m = 0; m < AA_X; m++) { + for (int n = 0; n < AA_Y; n++) { + vec3 p = u_camera_position; + vec2 aa_offset = vec2(float(m), float(n)) * aa_delta; + vec3 delta = normalize(u_camera_rotation * vec3(pos + aa_offset, -focal_length)); + int i; + for (i = 0; i < ITERATIONS; i++) { + float dist = sdf(p); + min_dist = min(min_dist, dist); + if (dist <= 0.01) { + float L = 0.3 + max(0., dot(normal(p), normalize(vec3(.8,1,.6)))); + final_color += L * vec3(1.0, 0.0, 0.0); + + break; + } + p += dist * delta; + } + } + } + final_color *= 1.0 / (AA_X * AA_Y); + o_color = vec4(final_color, 1.0); +}"); + + println!("{fshader_source}"); + let program = window.create_program( "attribute vec2 v_pos; + OUT vec2 pos; + uniform float u_aspect_ratio; + void main() { + pos = v_pos * vec2(u_aspect_ratio, 1.0); gl_Position = vec4(v_pos, 0.0, 1.0); }", - "void main() { - o_color = vec4(1.0, 0.0, 0.0, 1.0); - }" + &fshader_source ).map_err(|e| format!("Error compiling shader:\n{e}"))?; let mut buffer = window.create_buffer(); @@ -28,6 +144,8 @@ fn try_main() -> Result<(), String> { let mut array = window.create_vertex_array(buffer, &program); window.array_attrib2f(&mut array, "v_pos", 0); + let mut view = View::default(); + 'mainloop: loop { while let Some(event) = window.next_event() { use win::Event::*; @@ -35,11 +153,17 @@ fn try_main() -> Result<(), String> { Quit => break 'mainloop, _ => {}, } - println!("{event:?}"); } + window.viewport_full_screen(); + + view.yaw += 0.002; + window.clear_screen(win::ColorF32::BLACK); window.use_program(&program); + window.uniform1f("u_aspect_ratio", window.aspect_ratio()); + window.uniform3f("u_camera_position", view.pos.x, view.pos.y, view.pos.z); + window.uniform3x3f("u_camera_rotation", view.camera_rotation().as_slice()); window.draw_array(&array); |