diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 97 |
1 files changed, 76 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs index b8c4f54..41a6d7b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,32 @@ /* @TODO: - auto-select level set by sampling a bunch of points +- bring time back, w pause/rewind/adjust time speed (start out paused?) - Params instead of depth +- seed control (maybe save seeds to a file then let user go back&forth through past sdfs) - fullscreen key - mathematical analysis - options for: - max framerate - mouse sensitivity + - fov, focal length - AA quality - # iterations, distance cutoff - documentation -- GenRandom integers (+ gen_random_scale_bias) +- GenRandom integers (+ gen_random_scale_bias + +----- +cool seeds: +18413841503509874975 +**17878446840930313726 */ -extern crate gen_random; extern crate nalgebra; pub mod sdf; mod sdl; pub mod win; -use gen_random::GenRandom; use nalgebra::{Matrix3, Matrix4, Rotation3, Vector3}; use std::time::Instant; @@ -72,17 +78,13 @@ impl View { } } -fn try_main() -> Result<(), String> { - let my_sdf = if false { - sdf::Sdf::sphere(1.0) - } else { - sdf::Sdf::gen_thread_random_max_depth(6) - }; - println!("{my_sdf:?}"); - - let mut window = win::Window::new("AutoSDF", 1280, 720, true) - .map_err(|e| format!("Error creating window: {e}"))?; - +fn gen_program_with_seed(window: &mut win::Window, program: &mut win::Program, seed: u64) -> Result<(), String> { + use rand::SeedableRng; + + let mut rng = rand::rngs::SmallRng::seed_from_u64(seed); + let my_sdf = sdf::R3ToR::good_random(&mut rng, 6); + let color_function = sdf::R3ToR3::good_random(&mut rng, 7); + let mut fshader_source = String::new(); fshader_source.push_str( " @@ -93,11 +95,44 @@ uniform float u_time; uniform float u_fov; uniform float u_focal_length; uniform float u_level_set; +uniform int u_hsv; + +float smooth_min(float a, float b, float k) { + k = clamp(k, 0.0, 1.0); + float h = max(k-abs(a-b), 0.0)/k; + return min(a, b) - h*h*h*k*(1.0/6.0); +} ", ); - my_sdf.to_glsl(&mut fshader_source); + my_sdf.to_glsl_function("sdf", &mut fshader_source); + color_function.to_glsl_function("get_color_", &mut fshader_source); fshader_source.push_str( " + +// see https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB_alternative +float hsvf(float n, vec3 hsv) { + float k = mod(n + hsv.x * 6.0, 6.0); + return hsv.z - hsv.z * hsv.y * clamp(min(k, 4.0 - k), 0.0, 1.0); +} + +vec3 hsv_to_rgb(vec3 hsv) { + hsv.yz = clamp(hsv.yz, 0.0, 1.0); + return vec3(hsvf(5.0, hsv), hsvf(3.0, hsv), hsvf(1.0, hsv)); +} + +vec3 get_color(vec3 p) { + if (u_hsv != 0) { + vec3 hsv = get_color_(p); + // make sure object isn't too dark so we can actually see it + hsv.z = mix(hsv.z, 1.0, 0.5); + return hsv_to_rgb(hsv); + } else { + // in theory we should clamp this but it actually looks better if we don't + // (it makes the object glow) + return get_color_(p); + } +} + #define ITERATIONS 30 #define AA_X 1 #define AA_Y 1 @@ -134,7 +169,7 @@ void main() { p += u_translation; if (sdf(p) < 0.0) { // looking inside object - o_color = vec4(1.0, 0.0, 1.0, 1.0); + o_color = vec4(get_color(p), 1.0); return; } int i; @@ -159,7 +194,7 @@ void main() { float brightness = (1.0/threshold) * (threshold-min_dist); brightness = pow(brightness, 16.0); float L_ambient = 0.3; - vec3 color = vec3(1.0, 0.0, 0.0); + vec3 color = get_color(p); float specularity = 0.15; // strength of specular lighting final_color += brightness * mix(mix(L_diffuse, 1.0, L_ambient) * color, vec3(L_specular), specularity); break; @@ -173,10 +208,11 @@ void main() { ); //println!("{fshader_source}"); + println!("seed: {seed}"); - let program = window - .create_program( - "attribute vec2 v_pos; + window + .link_program(program, + "IN vec2 v_pos; OUT vec2 pos; uniform float u_aspect_ratio; @@ -187,6 +223,20 @@ void main() { &fshader_source, ) .map_err(|e| format!("Error compiling shader:\n{e}"))?; + Ok(()) +} + +fn gen_program(window: &mut win::Window, program: &mut win::Program) -> Result<(), String> { + let seed = rand::random::<u64>(); + gen_program_with_seed(window, program, seed) +} + +fn try_main() -> Result<(), String> { + + let mut window = win::Window::new("AutoSDF", 1280, 720, true) + .map_err(|e| format!("Error creating window: {e}"))?; + let mut program = window.new_program(); + gen_program(&mut window, &mut program)?; let mut buffer = window.create_buffer(); let data: &[[f32; 2]] = &[ @@ -219,8 +269,13 @@ void main() { match event { Quit | KeyDown(Escape) => break 'mainloop, KeyDown(F1) => show_debug_info = !show_debug_info, + KeyDown(R) => { + gen_program(&mut window, &mut program)?; + view.level_set = 0.0; + }, + KeyDown(N0) => view.level_set = 0.0, MouseMotion { xrel, yrel, .. } => { - let mouse_sensitivity = 0.33; + let mouse_sensitivity = 0.05; view.yaw_by(-xrel as f32 * mouse_sensitivity * frame_dt); view.pitch_by(-yrel as f32 * mouse_sensitivity * frame_dt); } |