summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-13 22:29:37 -0500
committerpommicket <pommicket@gmail.com>2022-12-13 22:29:37 -0500
commitc83b409a0da900a099339a2e4fb023458c227fd3 (patch)
tree9e85a7a577019d9ecbdd81635fd0c95edf927eba
parent9098de12df1ae7fc1d002c5ef95713726f002b93 (diff)
composing, etc.
-rw-r--r--src/main.rs33
-rw-r--r--src/sdf.rs103
-rw-r--r--src/win.rs33
3 files changed, 137 insertions, 32 deletions
diff --git a/src/main.rs b/src/main.rs
index 2bcdd06..e5ad5cb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -61,10 +61,19 @@ impl View {
}
fn try_main() -> Result<(), String> {
- use sdf::{R3ToR};
- let funciton = R3ToR::smooth_min(
- R3ToR::sphere_f32(1.2),
- R3ToR::cube_f32(1.0)
+ use sdf::{R3ToR, RToR, R3ToR3, Constant};
+ let funciton = R3ToR::compose(
+ R3ToR3::Sin(Constant::from(0.5))
+ .compose(R3ToR3::Translate((
+ Constant::Time(0.1, 0.0),
+ Constant::F32(0.5),
+ Constant::F32(0.7)
+ ).into())),
+ R3ToR::smooth_min(
+ R3ToR::sphere_f32(1.2),
+ R3ToR::cube_f32(1.0)
+ ),
+ RToR::Identity
);
let my_sdf = sdf::Sdf::from_function(funciton);
@@ -86,7 +95,7 @@ uniform float u_level_set;
my_sdf.to_glsl(&mut fshader_source);
fshader_source.push_str(
"
-#define ITERATIONS 20
+#define ITERATIONS 30
#define AA_X 1
#define AA_Y 1
@@ -136,7 +145,9 @@ void main() {
float threshold = 0.02;
if (min_dist < threshold) {
float L = 0.3 + max(0., dot(normal(p), normalize(vec3(.8,1,.6))));
- final_color += L * (1.0/threshold) * (threshold-min_dist) * vec3(1.0, 0.0, 0.0);
+ float brightness = (1.0/threshold) * (threshold-min_dist);
+ brightness = pow(brightness, 8.0);
+ final_color += L * brightness * vec3(1.0, 0.0, 0.0);
break;
}
@@ -235,15 +246,21 @@ void main() {
if window.any_key_down(&[PageDown, NumPad3, N]) {
dl -= 1.0;
}
+ let speed_multiplier = if window.is_shift_down() {
+ 10.0
+ } else {
+ 1.0
+ };
+
let motion = Vec3::new(dx, dy, dz);
if let Some(motion) = motion.try_normalize(0.001) {
- let move_speed = 2.0;
+ let move_speed = 4.0 * speed_multiplier;
let motion = motion * frame_dt * move_speed;
let motion = view.rotation() * motion;
view.pos += motion;
}
- let level_set_speed = 1.0;
+ let level_set_speed = 1.0 * speed_multiplier;
view.level_set += dl * frame_dt * level_set_speed;
}
diff --git a/src/sdf.rs b/src/sdf.rs
index fee1a93..e7c78b8 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -12,6 +12,7 @@ macro_rules! write_str {
pub enum Constant {
F32(f32),
Time(f32, f32),
+ // @TODO: sin, sqrt, mod
}
impl From<f32> for Constant {
@@ -32,6 +33,12 @@ impl Constant {
pub struct Constant3(Constant, Constant, Constant);
+impl From<(Constant, Constant, Constant)> for Constant3 {
+ fn from(x: (Constant, Constant, Constant)) -> Self {
+ Self(x.0, x.1, x.2)
+ }
+}
+
impl Constant3 {
fn to_glsl(&self) -> String {
format!(
@@ -45,23 +52,39 @@ impl Constant3 {
pub enum R3ToR3 {
Identity,
+ Compose(Box<R3ToR3>, Box<R3ToR3>),
Translate(Constant3),
+ Sin(Constant),
+ //@TODO InfiniteMirrors(f32)
}
pub enum RToR {
Identity,
+ Compose(Box<RToR>, Box<RToR>),
Add(Constant),
}
pub enum R3ToR {
Sphere(Constant),
Cube(Constant),
- PrePost(Box<R3ToR3>, Box<R3ToR>, Box<RToR>),
+ Compose(Box<R3ToR3>, Box<R3ToR>, Box<RToR>),
Mix(Box<R3ToR>, Box<R3ToR>, Constant),
SmoothMin(Box<R3ToR>, Box<R3ToR>),
Min(Box<R3ToR>, Box<R3ToR>),
}
+impl R3ToR3 {
+ pub fn compose(self, b: Self) -> Self {
+ Self::Compose(Box::new(self), Box::new(b))
+ }
+}
+
+impl RToR {
+ pub fn compose(self, b: Self) -> Self {
+ Self::Compose(Box::new(self), Box::new(b))
+ }
+}
+
impl R3ToR {
pub fn sphere_f32(r: f32) -> Self {
Self::Sphere(r.into())
@@ -86,6 +109,10 @@ impl R3ToR {
pub fn smooth_min(a: Self, b: Self) -> Self {
Self::SmoothMin(Box::new(a), Box::new(b))
}
+
+ pub fn compose(pre: R3ToR3, f: Self, post: RToR) -> Self {
+ Self::Compose(Box::new(pre), Box::new(f), Box::new(post))
+ }
}
#[derive(Clone, Copy)]
@@ -136,17 +163,22 @@ impl Function for RToR {
use RToR::*;
match self {
- Identity => return input,
+ Identity => input,
Add(x) => {
+ let output = var.next();
write_str!(
code,
- "float {} = {input} + {};\n",
- var.next(),
+ "float {output} = {input} + {};\n",
x.to_glsl()
);
+ output
}
+ Compose(a, b) => {
+ let a_output = a.to_glsl(input, code, var);
+ let b_output = b.to_glsl(a_output, code, var);
+ b_output
+ },
}
- var.prev()
}
}
@@ -155,18 +187,34 @@ impl Function for R3ToR3 {
use R3ToR3::*;
match self {
- Identity => return input,
+ Identity => input,
Translate(by) => {
+ let output = var.next();
write_str!(
code,
- "vec3 {} = {input} + {};\n",
- var.next(),
+ "vec3 {output} = {input} + {};\n",
by.to_glsl()
);
+ output
+ }
+ Sin(c) => {
+ // we shouldn't just do sin(c x), since that
+ // would multiply the derivative by c (which breaks the SDF if c > 1)
+ // so we'll do sin(c x) / c instead.
+ let c = c.to_glsl();
+ let output = var.next();
+ write_str!(
+ code,
+ "vec3 {output} = sin({c} * {input}) * (1.0 / {c});\n"
+ );
+ output
+ },
+ Compose(a, b) => {
+ let a_output = a.to_glsl(input, code, var);
+ let b_output = b.to_glsl(a_output, code, var);
+ b_output
}
}
-
- var.prev()
}
}
@@ -178,54 +226,63 @@ impl Function for R3ToR {
// these SDFs.
Sphere(r) => {
let r = r.to_glsl();
- write_str!(code, "float {} = length({input}) - {r};\n", var.next());
+ let output = var.next();
+ write_str!(code, "float {output} = length({input}) - {r};\n");
+ output
}
Cube(r) => {
let r = r.to_glsl();
let q = var.next();
write_str!(code, "vec3 {q} = abs({input}) - {r};\n");
+ let output = var.next();
write_str!(
code,
- "float {} = length(max({q},0.0)) + min(max({q}.x,max({q}.y,{q}.z)),0.0);\n",
- var.next()
- )
+ "float {output} = length(max({q},0.0)) + min(max({q}.x,max({q}.y,{q}.z)),0.0);\n"
+ );
+ output
}
Mix(a, b, t) => {
let t = t.to_glsl();
let a_output = a.to_glsl(input, code, var);
let b_output = b.to_glsl(input, code, var);
+ let output = var.next();
write_str!(
code,
- "float {} = mix({a_output}, {b_output}, clamp({t}, 0.0, 1.0));\n",
- var.next()
+ "float {output} = mix({a_output}, {b_output}, clamp({t}, 0.0, 1.0));\n"
);
+ output
}
Min(a, b) => {
let a_output = a.to_glsl(input, code, var);
let b_output = b.to_glsl(input, code, var);
+ let output = var.next();
write_str!(
code,
- "float {} = min({a_output}, {b_output});\n",
- var.next()
+ "float {output} = min({a_output}, {b_output});\n"
);
+ output
},
SmoothMin(a, b) => {
let a_output = a.to_glsl(input, code, var);
let b_output = b.to_glsl(input, code, var);
+ let output = var.next();
// for now we're using a fixed k value
// i don't want to make this a Constant right now,
// since most values of k (i.e. <0, >1) look bad/just like min.
let k = 0.2;
write_str!(
code,
- "float {} = sdf_smooth_min({a_output}, {b_output}, {k});\n",
- var.next()
+ "float {output} = sdf_smooth_min({a_output}, {b_output}, {k});\n"
);
+ output
+ },
+ Compose(pre, f, post) => {
+ let pre_output = pre.to_glsl(input, code, var);
+ let f_output = f.to_glsl(pre_output, code, var);
+ let post_output = post.to_glsl(f_output, code, var);
+ post_output
},
- _ => todo!(),
}
-
- var.prev()
}
}
diff --git a/src/win.rs b/src/win.rs
index 18cbd62..d392819 100644
--- a/src/win.rs
+++ b/src/win.rs
@@ -8,6 +8,7 @@ use std::ffi::{c_char, c_int, c_uint, c_void, CStr, CString};
use std::sync::Mutex;
use std::{fmt, mem};
+
pub type AudioCallback = fn(sample_rate: u32, samples: &mut [f32]);
struct AudioData {
@@ -23,7 +24,7 @@ pub struct Window {
audio_data: Option<Box<AudioData>>,
}
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Key {
A,
B,
@@ -80,6 +81,12 @@ pub enum Key {
Space,
Enter,
Escape,
+ LShift,
+ RShift,
+ LCtrl,
+ RCtrl,
+ LAlt,
+ RAlt,
F1,
F2,
F3,
@@ -165,6 +172,12 @@ impl Key {
KP_7 => Key::NumPad7,
KP_8 => Key::NumPad8,
KP_9 => Key::NumPad9,
+ LSHIFT => Key::LShift,
+ RSHIFT => Key::RShift,
+ LCTRL => Key::LCtrl,
+ RCTRL => Key::RCtrl,
+ LALT => Key::LAlt,
+ RALT => Key::RAlt,
_ => return None,
})
}
@@ -239,6 +252,12 @@ impl Key {
Key::NumPad7 => KP_7,
Key::NumPad8 => KP_8,
Key::NumPad9 => KP_9,
+ Key::LShift => LSHIFT,
+ Key::RShift => RSHIFT,
+ Key::LCtrl => LCTRL,
+ Key::RCtrl => RCTRL,
+ Key::LAlt => LALT,
+ Key::RAlt => RALT,
}
}
}
@@ -1059,6 +1078,18 @@ impl Window {
pub fn any_key_down(&mut self, keys: &[Key]) -> bool {
keys.iter().any(|&k| self.is_key_down(k))
}
+
+ pub fn is_shift_down(&mut self) -> bool {
+ self.is_key_down(Key::LShift) || self.is_key_down(Key::RShift)
+ }
+
+ pub fn is_ctrl_down(&mut self) -> bool {
+ self.is_key_down(Key::LCtrl) || self.is_key_down(Key::RCtrl)
+ }
+
+ pub fn is_alt_down(&mut self) -> bool {
+ self.is_key_down(Key::LAlt) || self.is_key_down(Key::RAlt)
+ }
pub fn swap(&mut self) {
unsafe { sdl::gl_swap_window(self.sdlwin) };