From ec7c96aba33eceab5fa9fc2667cd4cf891e1576b Mon Sep 17 00:00:00 2001 From: Markus Moenig Date: Sun, 23 Jun 2024 15:04:51 +0700 Subject: [PATCH] Loads of material node fixes --- shared/src/geofxnode.rs | 52 +++++++++++++++++++++++++++++++--- shared/src/materialfxnode.rs | 19 +++++++------ shared/src/materialfxobject.rs | 24 ++++------------ shared/src/patterns.rs | 4 +-- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/shared/src/geofxnode.rs b/shared/src/geofxnode.rs index 4be04bdd..22340e25 100644 --- a/shared/src/geofxnode.rs +++ b/shared/src/geofxnode.rs @@ -34,6 +34,7 @@ pub enum GeoFXNodeFacing { #[derive(Serialize, Deserialize, PartialEq, Clone, Debug)] pub enum GeoFXNodeRole { Ground, + Floor, Column, LeftWall, TopWall, @@ -70,6 +71,13 @@ impl GeoFXNode { coll.set("Octaves", TheValue::IntRange(5, 0..=5)); function = str!("Ground"); } + Floor => { + coll.set("Pos X", TheValue::Float(0.5)); + coll.set("Pos Y", TheValue::Float(0.5)); + coll.set("Height", TheValue::FloatRange(0.1, 0.001..=1.0)); + coll.set("Hole", TheValue::FloatRange(0.0, 0.0..=1.0)); + function = str!("Ground"); + } Column => { coll.set("Pos X", TheValue::Float(0.5)); coll.set("Pos Y", TheValue::Float(0.5)); @@ -127,6 +135,7 @@ impl GeoFXNode { pub fn nodes() -> Vec { vec![ Self::new(GeoFXNodeRole::Ground), + Self::new(GeoFXNodeRole::Floor), Self::new(GeoFXNodeRole::Column), Self::new(GeoFXNodeRole::LeftWall), Self::new(GeoFXNodeRole::TopWall), @@ -160,6 +169,20 @@ impl GeoFXNode { } return -0.001; } + Floor => { + let mut pos = self.position() * scale; + pos.x = pos.x.floor(); + + let hole = coll.get_f32_default("Hole", 0.0) * scale; + + let mut d = self.box2d(p, pos, 1.0 * scale, 1.0 * scale); + + if hole > 0.0 { + d = d.abs() - hole; + } + + return d; + } Column => { let radius = coll.get_f32_default("Radius", 0.4); @@ -346,6 +369,27 @@ impl GeoFXNode { } return p.y - value * 0.05; } + Floor => { + let height = coll.get_f32_default("Height", 0.01); + let hole = coll.get_f32_default("Hole", 0.0); + + let pos = self.position(); + let mut d = self.box2d(vec2f(p.x, p.z), pos, 1.0, 1.0); + + if hole > 0.0 { + d = d.abs() - hole; + } + + if let Some(hit) = hit { + hit.pattern_pos = vec2f(p.x, p.z); + hit.extrusion = GeoFXNodeExtrusion::Y; + hit.extrusion_length = height; + hit.interior_distance = d; + hit.hit_point = p - vec3f(pos.x.floor() + 0.5, 0.0, 0.0); + } + + return d; + } Column => { let radius = coll.get_f32_default("Radius", 0.4); let height = coll.get_f32_default("Height", 1.0); @@ -373,10 +417,10 @@ impl GeoFXNode { let height = coll.get_f32_default("Height", 1.0); let pos = self.position(); - let d = self.box2d(vec2f(p.y, p.z), vec2f(height / 2.0, pos.y), thick, len); + let d = self.box2d(vec2f(p.z, p.y), vec2f(pos.y, height / 2.0), len, height); if let Some(hit) = hit { - hit.pattern_pos = vec2f(p.y, p.z); + hit.pattern_pos = vec2f(p.z, p.y); hit.extrusion = GeoFXNodeExtrusion::X; hit.extrusion_length = coll.get_f32_default("Thickness", 0.2); hit.interior_distance = d; @@ -409,10 +453,10 @@ impl GeoFXNode { let height = coll.get_f32_default("Height", 1.0); let pos = self.position(); - let d = self.box2d(vec2f(p.y, p.z), vec2f(height / 2.0, pos.y), thick, len); + let d = self.box2d(vec2f(p.z, p.y), vec2f(pos.y, height / 2.0), len, height); if let Some(hit) = hit { - hit.pattern_pos = vec2f(p.y, p.z); + hit.pattern_pos = vec2f(p.z, p.y); hit.extrusion = GeoFXNodeExtrusion::X; hit.extrusion_length = coll.get_f32_default("Thickness", 0.2); hit.interior_distance = d; diff --git a/shared/src/materialfxnode.rs b/shared/src/materialfxnode.rs index 3d967d6b..8e027292 100644 --- a/shared/src/materialfxnode.rs +++ b/shared/src/materialfxnode.rs @@ -88,7 +88,8 @@ impl MaterialFXNode { "Pattern", TheValue::TextList(0, vec![str!("Horizontal"), str!("Vertical")]), ); - coll.set("Scale", TheValue::FloatRange(1.0, 0.0..=5.0)); + coll.set("Scale", TheValue::FloatRange(1.0, 0.0..=2.0)); + coll.set("Gap", TheValue::FloatRange(1.0, 0.0..=2.0)); } } @@ -269,11 +270,12 @@ impl MaterialFXNode { if let Some(TheValue::PaletteIndex(index)) = collection.get("Color") { if let Some(color) = &palette.colors[*index as usize] { - hit.albedo.x = color.r * hit.value; - hit.albedo.y = color.g * hit.value; - hit.albedo.z = color.b * hit.value; - hit.roughness = collection.get_f32_default("Roughness", 0.5) * hit.value; - hit.metallic = collection.get_f32_default("Metallic", 0.0) * hit.value; + hit.albedo.x = color.r; // * hit.value; + hit.albedo.y = color.g; // * hit.value; + hit.albedo.z = color.b; // * hit.value; + hit.roughness = collection.get_f32_default("Roughness", 0.5); // * hit.value; + hit.metallic = collection.get_f32_default("Metallic", 0.0); + // * hit.value; } } @@ -358,10 +360,11 @@ impl MaterialFXNode { ExtrusionPatterns => { let collection = self.collection(); let scale = collection.get_f32_default("Scale", 1.0); + let gap = collection.get_f32_default("Gap", 1.0); let p = hit.pattern_pos / (5.0 * scale); - let rc = box_divide(p); - hit.interior_distance_mortar = Some(hit.interior_distance - 0.1); + let rc = box_divide(p, gap); + hit.interior_distance_mortar = Some(hit.interior_distance); hit.interior_distance = rc.0; hit.hash = rc.1; } diff --git a/shared/src/materialfxobject.rs b/shared/src/materialfxobject.rs index 936cd56e..85f5f296 100644 --- a/shared/src/materialfxobject.rs +++ b/shared/src/materialfxobject.rs @@ -50,12 +50,7 @@ impl MaterialFXObject { /// Computes the material pub fn compute(&self, hit: &mut Hit, palette: &ThePalette) { - for (i, node) in self.nodes.iter().enumerate() { - if node.role == MaterialFXNodeRole::Geometry { - self.follow_trail(i, 0, hit, palette); - break; - } - } + self.follow_trail(0, 0, hit, palette); } pub fn get_distance( @@ -84,7 +79,7 @@ impl MaterialFXObject { op_extrusion_x(hit.hit_point, mortar, hit.extrusion_length); d.0 = min(distance, mortar_distance); - if hit.interior_distance <= 0.0 { + if hit.interior_distance <= 0.01 { hit.value = 0.0; } else { hit.value = 1.0; @@ -107,7 +102,7 @@ impl MaterialFXObject { op_extrusion_y(hit.hit_point, mortar, hit.extrusion_length); d.0 = min(distance, mortar_distance); - if hit.interior_distance < 0.0 { + if hit.interior_distance <= 0.01 { hit.value = 0.0; } else { hit.value = 1.0; @@ -129,22 +124,13 @@ impl MaterialFXObject { let mortar_distance = op_extrusion_z(hit.hit_point, mortar, hit.extrusion_length); d.0 = min(distance, mortar_distance); - //hit.value = normalize_sdf(distance, normalize_distance); - //let v1 = smoothstep(-0.05, 0.05, distance); - // let v2 = smoothstep(-0.05, 0.05, mortar_distance); - - //hit.value = smoothstep(-0.05, 0.05, d.0); - if hit.interior_distance < 0.0 { + if hit.interior_distance <= 0.01 { hit.value = 0.0; } else { hit.value = 1.0; } - - //hit.value = smoothstep(-0.05, 0.05, hit.interior_distance); - - //hit.value = max(v1, v2); - //println!("v {}", hit.value); + //hit.value = smoothstep(-0.01, 0.01, hit.interior_distance).clamp(0.0, 1.0); } else { d.0 = distance; } diff --git a/shared/src/patterns.rs b/shared/src/patterns.rs index b702e5bf..4ed9c80f 100644 --- a/shared/src/patterns.rs +++ b/shared/src/patterns.rs @@ -212,7 +212,7 @@ fn rot(a: f32) -> Mat2f { } // Shane's box divide formula from https://www.shadertoy.com/view/XsGyDh -pub fn box_divide(p: Vec2f) -> (f32, f32) { +pub fn box_divide(p: Vec2f, gap: f32) -> (f32, f32) { fn s_box(p: Vec2f, b: Vec2f, r: f32) -> f32 { let d = abs(p) - b + vec2f(r, r); d.x.max(d.y).min(0.0) + length(max(d, vec2f(0.0, 0.0))) - r @@ -256,7 +256,7 @@ pub fn box_divide(p: Vec2f) -> (f32, f32) { p = rot((id - 0.5) * 0.15) * p; // Gap, or mortar, width. Using "l" to keep it roughly constant. - let th = l * 0.02; + let th = l * 0.02 * gap; // Take the subdivided space and turn them into rounded pavers. //let c = s_box(p, vec2f(0.5, 0.5) - th, noise(p) * 0.5); let c = s_box(p, vec2f(0.5, 0.5) - th, 0.0);