From f039525f98b85d9e35fcbb3180df61101e62469b Mon Sep 17 00:00:00 2001 From: arcadeperfect Date: Sat, 7 Dec 2024 11:02:07 -0500 Subject: [PATCH] pre refactor --- src/gui.rs | 6 +- src/main.rs | 12 ++- src/shaders/ca.wgsl | 105 +++++------------------ src/shaders/extract.wgsl | 10 +++ src/shaders/generate_circle.wgsl | 140 ++++++++++++++++++++++++++++--- 5 files changed, 172 insertions(+), 101 deletions(-) diff --git a/src/gui.rs b/src/gui.rs index b2a9f1b..be6e32d 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -35,7 +35,7 @@ fn ui_system( ui.heading("noiseeee"); ui.group(|ui| { ui.label("radius"); - ui.add(egui::Slider::new(&mut params.radius, 0.0..=1.).text("radius")); + ui.add(egui::Slider::new(&mut params.radius, 0.0..=0.5).text("radius")); ui.add(egui::Slider::new(&mut params.noise_amplitude, 0.0..=5.).text("amplitude")); ui.add(egui::Slider::new(&mut params.noise_freq, 0.0..=1.).text("frequency")); ui.add(egui::Slider::new(&mut params.noise_offset, 0.0..=20.).text("offset")); @@ -60,8 +60,10 @@ fn ui_system( .range(0..=100), ); }); - ui.add(egui::Slider::new(&mut params.ca_thresh, 0.0..=0.25).text("thresh")); + ui.add(egui::Slider::new(&mut params.ca_thresh, 0.0..=1.).text("thresh")); ui.add(egui::Slider::new(&mut params.ca_search_radius, 0.1..=6.).text("search radius")); + ui.add(egui::Slider::new(&mut params.ca_edge_pow, 0.1..=6.).text("edge pow")); + ui.add(egui::Slider::new(&mut params.edge_suppress_mix, 0.0..=1.).text("edge mix")); }); }); diff --git a/src/main.rs b/src/main.rs index 13886e7..22be99a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,7 +45,9 @@ struct ParamsUniform { warp_scale: f32, noise_weight: f32, ca_thresh: f32, - ca_search_radius: f32 + ca_search_radius: f32, + ca_edge_pow: f32, + edge_suppress_mix: f32 } impl Default for ParamsUniform { @@ -53,7 +55,7 @@ impl Default for ParamsUniform { fn default() -> Self { Self { dimensions: BUFFER_LEN as u32, - radius: 0.75, + radius: 0.3, noise_seed: 0, noise_freq: 0.3, noise_amplitude: 1.55, @@ -65,8 +67,10 @@ impl Default for ParamsUniform { warp_amount: 0.0, warp_scale: 0.0, noise_weight: 0.53, - ca_thresh: 0.17, - ca_search_radius: 3.8 + ca_thresh: 0.24, + ca_search_radius: 3.8, + ca_edge_pow: 1.5, + edge_suppress_mix: 1.0 } } } diff --git a/src/shaders/ca.wgsl b/src/shaders/ca.wgsl index 5b659c3..4c3b6c7 100644 --- a/src/shaders/ca.wgsl +++ b/src/shaders/ca.wgsl @@ -17,7 +17,9 @@ struct Params { warp_scale: f32, noise_weight: f32, ca_thresh: f32, - ca_search_radius: f32 + ca_search_radius: f32, + ca_edge_pow: f32, + edge_suppress_mix: f32 } @group(0) @binding(0) var params: Params; @@ -45,7 +47,7 @@ fn get_weighted_neighbor_count(x: i32, y: i32, radius: f32) -> f32 { let new_y = y + j; if(new_x < 0 || new_x >= dim || new_y < 0 || new_y >= dim) { - // found += 1.0; // Treat out-of-bounds as walls + found += 1.0; // Treat out-of-bounds as walls continue; } @@ -64,67 +66,9 @@ fn get_weighted_neighbor_count(x: i32, y: i32, radius: f32) -> f32 { return normed; } -// fn probb(v: f32) -> bool{ - -// if(v <= 0){ -// return false; -// } -// if(v >= 1){ -// return true; -// } - -// var rand = noise::rand11(f32(x * y * y)); -// return rand < v; -// } - -// regarding input: -// r contains generated terrain -// g contains distance field from center -// b contains distance field from edges -// a contains weighted noise - - -// @compute @workgroup_size(16, 16) -// fn main(@builtin(global_invocation_id) global_id: vec3) { -// let x = global_id.x; -// let y = global_id.y; - -// if (x >= params.dimensions || y >= params.dimensions) { -// return; -// } - - - -// let upos = vec2(i32(x), i32(y)); -// let current = textureLoad(input_texture, upos); -// let edge_dist = current.b; -// let nze = current.a; - -// let scaled_radius = params.ca_search_radius * (8.0 / (f32(params.dimensions) / 128.0)); -// let nbs = get_weighted_neighbor_count(i32(x), i32(y), scaled_radius); - -// var thresh = params.ca_thresh; - - -// // true means we are a cave and we will be subtracted from the planet - -// var selector = nbs > thresh; - -// var rand = noise::rand11(f32(x * y * y)); - -// var caves = select( -// 0., -// 1., -// selector -// ); -// // caves = caves + edge_dist; - -// var result = current.r - caves; - -// textureStore(output_texture, upos, vec4f(current.x, current.y, current.z, caves)); -// } @compute @workgroup_size(16, 16) fn main(@builtin(global_invocation_id) global_id: vec3) { + let x = global_id.x; let y = global_id.y; @@ -134,34 +78,22 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { let upos = vec2(i32(x), i32(y)); let current = textureLoad(input_texture, upos); - let edge_dist = current.b; + var edge_dist = current.b; + let center_dist = current.g; let nze = current.a; let scaled_radius = params.ca_search_radius * (8.0 / (f32(params.dimensions) / 128.0)); let nbs = get_weighted_neighbor_count(i32(x), i32(y), scaled_radius); var thresh = params.ca_thresh; + // edge_dist = params.radius / edge_dist; + + var weighted_thresh = thresh * pow((1-edge_dist), params.ca_edge_pow); + thresh = mix(thresh, weighted_thresh, params.edge_suppress_mix); + thresh = utils::remap(thresh, 0., 1., 0.14, 0.31); // Generate base cave selector from cellular automata var selector = nbs > thresh; - - // Get random value - var rand = noise::rand11(f32(x * y * y)); - - let seed = vec2f(f32(x), f32(y)); - var n = noise::fbm(seed * 0.01); - n = n * 0.5 + 0.5; - n = n - 0.3; - n = n * 0.1; - // Create an exponential edge falloff factor - // pow(x, n) where n > 1 creates exponential curve - // Higher power = sharper falloff - let edge_power = n * 51.; // Adjust this to control falloff sharpness - let edge_scale = n; // Adjust this to control where falloff starts - let edge_factor = pow(clamp(edge_dist / edge_scale, 0.0, 1.0), edge_power); - - // Only allow cave formation if random value is less than edge factor - selector = selector && (rand < edge_factor); var caves = select( 0., @@ -170,9 +102,14 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { ); var result = current.r - caves; - - textureStore(output_texture, upos, vec4f(current.x, current.y, current.z, caves)); + + let norm_edge = edge_dist / current.z; + + textureStore(output_texture, upos, vec4f(current.r, current.g, current.b, caves)); + } -// r, g, and b are left as is -// caves are added to a \ No newline at end of file +// r contains generated terrain +// g contains distance field from center +// b contains distance field from edges +// a is the deformed radius \ No newline at end of file diff --git a/src/shaders/extract.wgsl b/src/shaders/extract.wgsl index 0258815..660f34d 100644 --- a/src/shaders/extract.wgsl +++ b/src/shaders/extract.wgsl @@ -26,9 +26,19 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { let current = textureLoad(input_texture, upos); + + let dist = current.g / current.a; + textureStore(output_texture, upos, vec4f(dist)); + var r = current.r - current.a; r = clamp(r, 0., 1.); // textureStore(output_texture, upos, vec4f(r,r,r,1.)); + // textureStore(output_texture, upos, vec4f(r, current.g, current.b, 1.0)); textureStore(output_texture, upos, vec4f(r, current.g, current.b, 1.0)); } + +// r contains generated terrain +// g contains distance field from center +// b contains distance field from edges +// a is the deformed radius \ No newline at end of file diff --git a/src/shaders/generate_circle.wgsl b/src/shaders/generate_circle.wgsl index 8df8f89..47e5ac1 100644 --- a/src/shaders/generate_circle.wgsl +++ b/src/shaders/generate_circle.wgsl @@ -10,10 +10,15 @@ struct Params { noise_offset: f32, power_bias: f32, flatness: f32, - steepness:f32, - mix:f32, + steepness: f32, + mix: f32, warp_amount: f32, warp_scale: f32, + noise_weight: f32, + ca_thresh: f32, + ca_search_radius: f32, + ca_edge_pow: f32, + edge_suppress_mix: f32 } @group(0) @binding(0) var params: Params; @@ -66,6 +71,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { let dim = params.dimensions; + // normalize the coordinates var normd_pos = vec2f( f32(x) / f32(dim), f32(y) / f32(dim) @@ -87,20 +93,132 @@ fn main(@builtin(global_invocation_id) global_id: vec3) { var result = mix(n, m, params.mix); - let r = params.radius * 0.4 + result; + let deformed_radius = params.radius + result; let dist_to_center = distance(normd_pos, center); let upos = vec2(i32(x), i32(y)); - let v = select(0.0, 1.0, dist_to_center <= r); + let v = select(0.0, 1.0, dist_to_center <= deformed_radius); + + normd_pos = normd_pos - center; // transform so that 0,0 is the center + let mag = length(normd_pos); // the distance from this pixel to the center + normd_pos = vec2f(mag, 0.0); // create a new vector of the same length, but on the x axis + let edge = vec2f(deformed_radius, 0.0); // create a new vector on the same axis, at the distance to the edge + // let dist_to_edge = distance(normd_pos, edge); // calculate the distance to the edge + var dist_to_edge = edge.x - normd_pos.x; + // dist_to_edge = dist_to_edge / deformed_radius; + dist_to_edge = dist_to_edge * params.ca_edge_pow; + textureStore(output_texture, upos, vec4(v , dist_to_center, dist_to_edge, deformed_radius)); +} - normd_pos = normd_pos - center; - let mag = length(normd_pos); - normd_pos = vec2f(mag, 0.0); - let edge = vec2f(r, 0.0); - let dist_to_edge = distance(normd_pos, edge); +// r contains generated terrain +// g contains distance field from center +// b contains distance field from edges +// a is the deformed radius + + +// #import compute::noise +// #import compute::utils + +// struct Params { +// dimensions: u32, +// radius: f32, +// noise_seed: u32, +// noise_scale: f32, +// noise_amplitude: f32, +// noise_offset: f32, +// power_bias: f32, +// flatness: f32, +// steepness:f32, +// mix:f32, +// warp_amount: f32, +// warp_scale: f32, +// } + +// @group(0) @binding(0) var params: Params; +// @group(0) @binding(1) var input_texture: texture_storage_2d; +// @group(0) @binding(2) var output_texture: texture_storage_2d; + +// // Power bias to make peaks more pronounced +// fn power_bias(n: f32, power: f32) -> f32{ +// let normalized = (n + 1.) * 0.5; +// return pow(normalized, power) * 2. -1.; +// } + +// // Plateau function for flat areas with steep cliffs +// fn plateau(n: f32, flatness: f32) -> f32{ +// let x = n * flatness; +// let exp2x = exp(2.0 * x); +// return (exp2x -1.0) / (exp2x + 1.0); +// } + +// // Exponential distribution for elevation concentration +// fn exp_distribution(n: f32, sharpness: f32) -> f32 { +// let normalized = (n +1.) * 0.5; +// return (exp(n * sharpness) - 1.0) / (exp(sharpness) - 1.0) * 2.0 - 1.0; +// } + +// // Combined mountain bias function +// fn mountain_bias(n: f32) -> f32 { +// var result = n; +// // make peaks more pronounced +// result = power_bias(n, params.power_bias); + +// // add plateaus +// result = plateau(result, params.flatness); + +// // // adjust distribution +// result = exp_distribution(result, params.steepness); + +// return result; +// } + +// @compute @workgroup_size(16, 16) +// fn main(@builtin(global_invocation_id) global_id: vec3) { +// let x = global_id.x; +// let y = global_id.y; + +// // Early return if we're outside the texture dimensions +// if (x >= params.dimensions || y >= params.dimensions) { +// return; +// } - textureStore(output_texture, upos, vec4(v , dist_to_center, dist_to_edge, 1.)); -} +// let dim = params.dimensions; + +// var normd_pos = vec2f( +// f32(x) / f32(dim), +// f32(y) / f32(dim) +// ); + + +// let seed_mult = 10.0; +// let center = vec2(0.5, 0.5); + +// let angle = atan2(normd_pos.x - center.x, normd_pos.y - center.y); +// let seed = vec2f(cos(angle), sin(angle)); +// var n = noise::fbm((seed * seed_mult * params.noise_scale) + params.noise_offset); + +// var m = mountain_bias(n) * 0.03; +// n = n * 0.03; + +// n = n * params.noise_amplitude; +// m = m * params.noise_amplitude; + +// var result = mix(n, m, params.mix); + +// let r = params.radius * 0.4 + result; +// let dist_to_center = distance(normd_pos, center); +// let upos = vec2(i32(x), i32(y)); + +// let v = select(0.0, 1.0, dist_to_center <= r); + +// normd_pos = normd_pos - center; +// let mag = length(normd_pos); +// normd_pos = vec2f(mag, 0.0); +// let edge = vec2f(r, 0.0); +// let dist_to_edge = distance(normd_pos, edge); + +// textureStore(output_texture, upos, vec4(v , dist_to_center, dist_to_edge, 1.)); +// } // r contains generated terrain // g contains distance field from center