summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-13 18:52:43 -0500
committerpommicket <pommicket@gmail.com>2022-12-13 18:52:43 -0500
commit0649f21d9b60ebedffc3731374feb6132e38804a (patch)
tree0ca6fcd99f08a02f4f3baf361374a06ad829d08f /src
parent3f699f3720ef8d912e509bc3785485b527419dc0 (diff)
more functions
Diffstat (limited to 'src')
-rw-r--r--src/main.rs94
-rw-r--r--src/sdf.rs28
-rw-r--r--src/sdl.rs1
-rw-r--r--src/win.rs56
4 files changed, 127 insertions, 52 deletions
diff --git a/src/main.rs b/src/main.rs
index 6fef680..c55d1c0 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -27,14 +27,19 @@ struct View {
pos: Vec3,
yaw: f32,
pitch: f32,
+ level_set: f32,
}
impl Default for View {
fn default() -> Self {
+ // don't start out right next to the origin, since weird stuff might be happening there
+ let pos = Vec3::new(0.0, 0.0, 4.0);
+
Self {
- pos: Vec3::zeros(),
+ pos,
yaw: 0.0,
pitch: 0.0,
+ level_set: 0.0,
}
}
}
@@ -49,16 +54,18 @@ impl View {
Mat4::new_translation(&self.pos)
}
+ #[allow(dead_code)]
fn transform(&self) -> Mat4 {
self.translation() * self.rotation().to_homogeneous()
}
-
}
fn try_main() -> Result<(), String> {
- use sdf::{R3ToR, Constant};
- let funciton = R3ToR::mix(R3ToR::sphere_f32(1.0), R3ToR::cube_f32(1.0),
- Constant::Time(0.1, 0.0));
+ use sdf::{R3ToR};
+ let funciton = R3ToR::min(
+ R3ToR::sphere_f32(1.5),
+ R3ToR::cube_f32(1.0),
+ );
let my_sdf = sdf::Sdf::from_function(funciton);
let mut window = win::Window::new("AutoSDF", 1280, 720, true)
@@ -68,8 +75,12 @@ fn try_main() -> Result<(), String> {
fshader_source.push_str(
"
IN vec2 pos;
-uniform mat4 u_transform;
+uniform mat3 u_rotation;
+uniform vec3 u_translation;
uniform float u_time;
+uniform float u_fov;
+uniform float u_focal_length;
+uniform float u_level_set;
",
);
my_sdf.to_glsl(&mut fshader_source);
@@ -79,27 +90,11 @@ uniform float u_time;
#define AA_X 1
#define AA_Y 1
-
-
-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;
+float sdf_adjusted(vec3 p) {
+ return sdf(p) - u_level_set;
}
-
+#define sdf sdf_adjusted
+
vec3 normal(vec3 p)
{
// thanks to https://iquilezles.org/articles/normalsSDF/
@@ -113,7 +108,6 @@ vec3 normal(vec3 p)
}
void main() {
- float focal_length = 1.0;
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);
@@ -121,8 +115,10 @@ void main() {
for (int m = 0; m < AA_X; m++) {
for (int n = 0; n < AA_Y; n++) {
vec2 aa_offset = vec2(float(m), float(n)) * aa_delta;
- vec3 p = (u_transform * vec4(pos + aa_offset, -focal_length, 1.0)).xyz;
+ vec3 pos3d = vec3((pos + aa_offset) * sin(u_fov * 0.5), -1.0) * u_focal_length;
+ vec3 p = u_rotation * pos3d;
vec3 delta = normalize(p);
+ p += u_translation;
if (sdf(p) < 0.0) {
// looking inside object
o_color = vec4(1.0, 0.0, 1.0, 1.0);
@@ -187,7 +183,7 @@ void main() {
'mainloop: loop {
let frame_dt = frame_time.elapsed().as_secs_f32();
frame_time = Instant::now();
-
+
while let Some(event) = window.next_event() {
use win::Event::*;
use win::Key::*;
@@ -201,22 +197,26 @@ void main() {
_ => {}
}
}
-
- { // movement
+
+ {
+ // movement
let mut dx = 0.0;
let mut dy = 0.0;
let mut dz = 0.0;
- use win::Key::{Left, Right, Up, Down, W, A, S, D, Q, E};
- if window.is_key_down(W) || window.is_key_down(Up) {
+ let mut dl = 0.0;
+ use win::Key::{
+ Down, Left, NumPad3, NumPad9, PageDown, PageUp, Right, Up, A, D, E, M, N, Q, S, W,
+ };
+ if window.any_key_down(&[W, Up]) {
dz -= 1.0;
}
- if window.is_key_down(S) || window.is_key_down(Down) {
+ if window.any_key_down(&[S, Down]) {
dz += 1.0;
}
- if window.is_key_down(A) || window.is_key_down(Left) {
+ if window.any_key_down(&[A, Left]) {
dx -= 1.0;
}
- if window.is_key_down(D) || window.is_key_down(Right) {
+ if window.any_key_down(&[D, Right]) {
dx += 1.0;
}
if window.is_key_down(Q) {
@@ -225,21 +225,35 @@ void main() {
if window.is_key_down(E) {
dy -= 1.0;
}
+ if window.any_key_down(&[PageUp, NumPad9, M]) {
+ dl += 1.0;
+ }
+ if window.any_key_down(&[PageDown, NumPad3, N]) {
+ dl -= 1.0;
+ }
let motion = Vec3::new(dx, dy, dz);
if let Some(motion) = motion.try_normalize(0.001) {
- let motion = motion * frame_dt;
+ let move_speed = 2.0;
+ let motion = motion * frame_dt * move_speed;
let motion = view.rotation() * motion;
view.pos += motion;
}
+
+ let level_set_speed = 1.0;
+ view.level_set += dl * frame_dt * level_set_speed;
}
-
+
window.viewport_full_screen();
window.clear_screen(win::ColorF32::BLACK);
window.use_program(&program);
window.uniform1f("u_aspect_ratio", window.aspect_ratio());
window.uniform1f("u_time", total_time);
- window.uniform4x4f("u_transform", view.transform().as_slice());
+ window.uniform1f("u_fov", std::f32::consts::PI * 0.25);
+ window.uniform1f("u_focal_length", 1.0);
+ window.uniform1f("u_level_set", view.level_set);
+ window.uniform3x3f("u_rotation", view.rotation().as_slice());
+ window.uniform3f_slice("u_translation", view.pos.as_slice());
window.draw_array(&array);
@@ -247,7 +261,7 @@ void main() {
if show_debug_info {
println!("frame time = {:?}ms", frame_dt * 1000.0);
}
-
+
total_time += frame_dt;
}
diff --git a/src/sdf.rs b/src/sdf.rs
index ba483a7..832ac3c 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -65,7 +65,7 @@ impl R3ToR {
pub fn sphere_f32(r: f32) -> Self {
Self::Sphere(r.into())
}
-
+
pub fn cube_f32(r: f32) -> Self {
Self::Cube(r.into())
}
@@ -73,10 +73,14 @@ impl R3ToR {
pub fn mix(a: Self, b: Self, t: Constant) -> Self {
Self::Mix(Box::new(a), Box::new(b), t)
}
-
+
pub fn mix_f32(a: Self, b: Self, t: f32) -> Self {
Self::mix(a, b, t.into())
}
+
+ pub fn min(a: Self, b: Self) -> Self {
+ Self::Min(Box::new(a), Box::new(b))
+ }
}
struct VarCounter {
@@ -178,6 +182,15 @@ impl Function for R3ToR {
var.next()
);
}
+ Min(a, b) => {
+ let a_output = a.to_glsl(input, code, var);
+ let b_output = b.to_glsl(input, code, var);
+ write_str!(
+ code,
+ "float v{} = min(v{a_output}, v{b_output});\n",
+ var.next()
+ );
+ },
_ => todo!(),
}
@@ -197,18 +210,11 @@ impl Sdf {
Self { distance_function }
}
- /// appends some glsl code including a function `float sdf(vec3 p) { ... }`
+ /// appends some glsl code including a function `float sdf(vec3) { ... }`
pub fn to_glsl(&self, code: &mut String) {
code.push_str("float sdf(vec3 p) {\n");
- // don't start out right next to the origin, since weird stuff might be happening there
- let origin_dist: f32 = 3.0;
let mut var = VarCounter::new();
- write_str!(
- code,
- "vec3 v{} = p - vec3(0,0,-{}.);\n",
- var.next(),
- origin_dist
- );
+ write_str!(code, "vec3 v{} = p;\n", var.next());
let output = self.distance_function.to_glsl(var.prev(), code, &mut var);
write_str!(code, "return v{output};\n");
code.push('}');
diff --git a/src/sdl.rs b/src/sdl.rs
index 1124a53..00d90b2 100644
--- a/src/sdl.rs
+++ b/src/sdl.rs
@@ -1001,6 +1001,7 @@ pub unsafe fn get_keyboard_state() -> &'static [u8] {
pub unsafe fn poll_event() -> Option<SDL_Event> {
let mut event = mem::MaybeUninit::zeroed();
+
if SDL_PollEvent(event.as_mut_ptr()) != 0 {
let event = event.assume_init();
Some(event)
diff --git a/src/win.rs b/src/win.rs
index 4badc76..18cbd62 100644
--- a/src/win.rs
+++ b/src/win.rs
@@ -61,10 +61,22 @@ pub enum Key {
N7,
N8,
N9,
+ NumPad0,
+ NumPad1,
+ NumPad2,
+ NumPad3,
+ NumPad4,
+ NumPad5,
+ NumPad6,
+ NumPad7,
+ NumPad8,
+ NumPad9,
Up,
Left,
Right,
Down,
+ PageUp,
+ PageDown,
Space,
Enter,
Escape,
@@ -129,6 +141,8 @@ impl Key {
RIGHT => Key::Right,
DOWN => Key::Down,
ESCAPE => Key::Escape,
+ PAGEUP => Key::PageUp,
+ PAGEDOWN => Key::PageDown,
F1 => Key::F1,
F2 => Key::F2,
F3 => Key::F3,
@@ -141,6 +155,16 @@ impl Key {
F10 => Key::F10,
F11 => Key::F11,
F12 => Key::F12,
+ KP_0 => Key::NumPad0,
+ KP_1 => Key::NumPad1,
+ KP_2 => Key::NumPad2,
+ KP_3 => Key::NumPad3,
+ KP_4 => Key::NumPad4,
+ KP_5 => Key::NumPad5,
+ KP_6 => Key::NumPad6,
+ KP_7 => Key::NumPad7,
+ KP_8 => Key::NumPad8,
+ KP_9 => Key::NumPad9,
_ => return None,
})
}
@@ -191,6 +215,8 @@ impl Key {
Key::Right => RIGHT,
Key::Down => DOWN,
Key::Escape => ESCAPE,
+ Key::PageUp => PAGEUP,
+ Key::PageDown => PAGEDOWN,
Key::F1 => F1,
Key::F2 => F2,
Key::F3 => F3,
@@ -203,6 +229,16 @@ impl Key {
Key::F10 => F10,
Key::F11 => F11,
Key::F12 => F12,
+ Key::NumPad0 => KP_0,
+ Key::NumPad1 => KP_1,
+ Key::NumPad2 => KP_2,
+ Key::NumPad3 => KP_3,
+ Key::NumPad4 => KP_4,
+ Key::NumPad5 => KP_5,
+ Key::NumPad6 => KP_6,
+ Key::NumPad7 => KP_7,
+ Key::NumPad8 => KP_8,
+ Key::NumPad9 => KP_9,
}
}
}
@@ -962,6 +998,11 @@ impl Window {
}
}
+ pub fn uniform2f_slice(&mut self, name: &str, xy: &[f32]) {
+ assert_eq!(xy.len(), 2);
+ self.uniform2f(name, xy[0], xy[1])
+ }
+
pub fn uniform3f(&mut self, name: &str, x: f32, y: f32, z: f32) {
let loc = self.get_uniform_location(name).unwrap_or(-1);
unsafe {
@@ -969,6 +1010,11 @@ impl Window {
}
}
+ pub fn uniform3f_slice(&mut self, name: &str, xyz: &[f32]) {
+ assert_eq!(xyz.len(), 3);
+ self.uniform3f(name, xyz[0], xyz[1], xyz[2])
+ }
+
pub fn uniform4f(&mut self, name: &str, x: f32, y: f32, z: f32, w: f32) {
let loc = self.get_uniform_location(name).unwrap_or(-1);
unsafe {
@@ -976,6 +1022,11 @@ impl Window {
}
}
+ pub fn uniform4f_slice(&mut self, name: &str, xyzw: &[f32]) {
+ assert_eq!(xyzw.len(), 4);
+ self.uniform4f(name, xyzw[0], xyzw[1], xyzw[2], xyzw[3])
+ }
+
pub fn uniform3x3f(&mut self, name: &str, matrix: &[f32]) {
assert_eq!(matrix.len(), 9);
let loc = self.get_uniform_location(name).unwrap_or(-1);
@@ -1000,12 +1051,15 @@ impl Window {
array.draw();
}
- #[allow(dead_code)]
pub fn is_key_down(&mut self, key: Key) -> bool {
let kbd_state = unsafe { sdl::get_keyboard_state() };
kbd_state[key.to_sdl() as usize] != 0
}
+ pub fn any_key_down(&mut self, keys: &[Key]) -> bool {
+ keys.iter().any(|&k| self.is_key_down(k))
+ }
+
pub fn swap(&mut self) {
unsafe { sdl::gl_swap_window(self.sdlwin) };
}