diff options
-rw-r--r-- | settings.txt | 2 | ||||
-rw-r--r-- | src/fshader_common.glsl | 16 | ||||
-rw-r--r-- | src/main.rs | 8 | ||||
-rw-r--r-- | src/sdf.rs | 57 |
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 @@ -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); |