summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-21 15:27:39 -0500
committerpommicket <pommicket@gmail.com>2022-12-21 15:27:39 -0500
commit49cfde2fb9fca47c3eab73f029fe0a2b9c913544 (patch)
tree5a1d37075b37ffa95380dbe982b04a323c5e7b1a
parent1bc45db77e3d1aaf6c620248b8e598cdc212112f (diff)
more basic functions
-rw-r--r--settings.txt2
-rw-r--r--src/fshader_common.glsl16
-rw-r--r--src/main.rs8
-rw-r--r--src/sdf.rs57
4 files changed, 65 insertions, 18 deletions
diff --git a/settings.txt b/settings.txt
index 13482df..2384452 100644
--- a/settings.txt
+++ b/settings.txt
@@ -1,7 +1,7 @@
mouse-sensitivity 50
# complexity of SDF
# making this bigger will make more complex scenes, but will require more gpu computation
-sdf-length 500
+sdf-length 600
# complexity of color function
# making this bigger will make more complex colors, but will require more gpu computation
color-length 300
diff --git a/src/fshader_common.glsl b/src/fshader_common.glsl
index 558b20f..5bd4a7a 100644
--- a/src/fshader_common.glsl
+++ b/src/fshader_common.glsl
@@ -6,6 +6,7 @@ float smooth_min(float a, float b, float k) {
}
// thanks to https://iquilezles.org/articles/distfunctions/
+
float sdf_box_frame(vec3 p, vec3 b, float e) {
p = abs(p)-b;
vec3 q = abs(p+e)-e;
@@ -19,3 +20,18 @@ float sdf_torus(vec3 p, vec2 t) {
vec2 q = vec2(length(p.xy)-t.x,p.z);
return length(q)-t.y;
}
+
+float sdf_tri_prism(vec3 p, vec2 h) {
+ vec3 q = abs(p);
+ return max(q.z-h.y,max(q.x*0.866025+p.y*0.5,-p.y)-h.x*0.5);
+}
+
+float sdf_vertical_line_segment(vec3 p, float h) {
+ p.y -= clamp(p.y, 0.0, h);
+ return length(p);
+}
+
+float sdf_cylinder(vec3 p, float h, float r) {
+ vec2 d = abs(vec2(length(p.xz),p.y)) - vec2(r,h);
+ return min(max(d.x,d.y),0.0) + length(max(d,0.0));
+}
diff --git a/src/main.rs b/src/main.rs
index 598a12a..1b0c382 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,13 +1,9 @@
/*
@TODO:
-- come up with twisty lipschitz continuous function, & add it
-- (slightly) more interesting constants
-- Params instead of depth for GenRandom
- - allow multiple endpoints (cube & sphere & ...)
+- configurable resolution
- let user go back&forth through past sdfs using scenes.txt file
-- mathematical analysis
- documentation
-- GenRandom integers (+ gen_random_scale_bias)
+- GenRandom integers (just use 0..u32::MAX and add a modulus)
- record a video
- better SDL api: Context + Window<'a> impl !Send+!Sync
- gallery view
diff --git a/src/sdf.rs b/src/sdf.rs
index 8975d05..edf777c 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -173,7 +173,7 @@ impl Display for Constant3 {
pub enum R3ToR3 {
#[prob(0)]
Identity,
- #[prob(6)]
+ #[prob(8)]
#[only_if(params.max_depth >= 0)]
Compose(Box<R3ToR3>, Box<R3ToR3>),
#[prob(1)]
@@ -195,8 +195,8 @@ pub enum R3ToR3 {
#[prob(2)]
#[bias(0.01)]
Sigmoid, //based on sigmoid(x) = 1 / (1 + e^-x)
- #[prob(2)]
- Twisty,
+ #[prob(0)]
+ Twisty(Constant),
}
// note : i dont think R → R transformations really accomplish that much
@@ -216,24 +216,30 @@ pub enum RToR {
#[derive(GenRandom, Debug, Serialize, Deserialize)]
#[params(SdfParams)]
pub enum R3ToR {
- #[prob(1)]
+ #[prob(0.1)]
Sphere(Constant),
- #[prob(1)]
+ #[prob(0.1)]
Cube(Constant),
- #[prob(1)]
+ #[prob(0.1)]
BoxFrame {
#[scale(3.0)]
size: Constant,
#[scale(0.2)]
thickness: Constant,
},
- #[prob(1)]
+ #[prob(0.1)]
Torus {
#[scale(3.0)]
radius: Constant,
#[scale(0.2)]
thickness: Constant,
},
+ #[prob(0.1)]
+ TriPrism(Constant, Constant),
+ #[prob(0.1)]
+ VLineSegment(Constant),
+ #[prob(0.1)]
+ Cylinder(Constant, Constant),
#[prob(8)]
#[only_if(params.max_depth >= 0)]
Compose(Box<R3ToR3>, Box<R3ToR>, Box<RToR>),
@@ -523,22 +529,27 @@ impl Function for R3ToR3 {
);
output
}
- Twisty => {
+ Twisty(c) => {
+ let s = var.next();
let a = var.next();
let theta = var.next();
let output = var.next();
write_str!(
code,
- "vec2 {a} = vec2(cos({input}.x), sin({input}.y));\n"
+ "vec3 {s} = {input} * {c};\n"
);
write_str!(
code,
- "float {theta} = {input}.z * sqrt(2.0);\n"
+ "vec2 {a} = vec2(cos({s}.x), sin({s}.y));\n"
+ );
+ write_str!(
+ code,
+ "float {theta} = {s}.z * sqrt(2.0);\n"
);
write_str!(
code,
"vec3 {output} = vec3({a}.x*cos({theta})+{a}.y*sin({theta}),
- {a}.y*cos({theta})-{a}.x*sin({theta}),{input}.z) * (1.0/4.0);\n"
+ {a}.y*cos({theta})-{a}.x*sin({theta}),{s}.z) * (1.0/(4.0 * {c}));\n"
);
output
}
@@ -586,6 +597,30 @@ impl Function for R3ToR {
);
output
}
+ TriPrism(x, y) => {
+ let output = var.next();
+ write_str!(
+ code,
+ "float {output} = sdf_tri_prism({input}, vec2({x}, {y}));\n"
+ );
+ output
+ }
+ VLineSegment(h) => {
+ let output = var.next();
+ write_str!(
+ code,
+ "float {output} = sdf_vertical_line_segment({input}, {h});\n"
+ );
+ output
+ }
+ Cylinder(x, y) => {
+ let output = var.next();
+ write_str!(
+ code,
+ "float {output} = sdf_cylinder({input}, {x}, {y});\n"
+ );
+ output
+ }
Mix(a, b, t) => {
let a_output = a.to_glsl(input, code, var);
let b_output = b.to_glsl(input, code, var);