Skip to content

Commit

Permalink
caves working pretty well
Browse files Browse the repository at this point in the history
  • Loading branch information
arcadeperfect committed Dec 7, 2024
1 parent b04f785 commit d28b447
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 63 deletions.
4 changes: 2 additions & 2 deletions src/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ fn ui_system(
ui.label("ca iterations");
ui.add(
egui::DragValue::new(&mut shader_configurator.shader_configs[3].iterations)
.range(0..=50),
.range(0..=100),
);
});
ui.add(egui::Slider::new(&mut params.ca_thresh, 0.1..=20.).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"));

});
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Default for ParamsUniform {
warp_amount: 0.0,
warp_scale: 0.0,
noise_weight: 0.53,
ca_thresh: 7.5,
ca_thresh: 0.17,
ca_search_radius: 3.8
}
}
Expand Down
128 changes: 83 additions & 45 deletions src/shaders/ca.wgsl
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#import compute::noise
#import compute::utils


struct Params {
dimensions: u32,
radius: f32,
Expand All @@ -16,10 +20,15 @@ struct Params {
ca_search_radius: f32
}

@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var input_texture: texture_storage_2d<rgba32float, read>;
@group(0) @binding(2) var output_texture: texture_storage_2d<rgba32float, write>;

fn get_weighted_neighbor_count(x: i32, y: i32, radius: f32) -> f32 {
var found = 0.0;
let dim = i32(params.dimensions);
let r = i32(ceil(radius));
var count = 0.0;

for(var i = -r; i <= r; i++) {
for(var j = -r; j <= r; j++) {
Expand All @@ -46,16 +55,34 @@ fn get_weighted_neighbor_count(x: i32, y: i32, radius: f32) -> f32 {
// Weight by distance from center
let weight = 1.0 - sqrt(dist_sq) / radius;
found += v * weight;
count += 1.0;
}
}
return found;

let normed: f32 = found / count;

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

@group(0) @binding(0) var<uniform> params: Params;
@group(0) @binding(1) var input_texture: texture_storage_2d<rgba32float, read>;
@group(0) @binding(2) var output_texture: texture_storage_2d<rgba32float, write>;

// @compute @workgroup_size(16, 16)
// fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
Expand All @@ -66,45 +93,36 @@ fn get_weighted_neighbor_count(x: i32, y: i32, radius: f32) -> f32 {
// return;
// }



// let upos = vec2<i32>(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 neighbor_weight = get_weighted_neighbor_count(i32(x), i32(y), scaled_radius);

// let base_threshold = params.ca_thresh * (scaled_radius / 4.0);

// // Increased stability bias for more persistence
// let stability_bias = 0.25;
// let threshold = select(
// base_threshold,
// base_threshold * (1.0 - stability_bias),
// nze > 0.5
// );
// let nbs = get_weighted_neighbor_count(i32(x), i32(y), scaled_radius);

// // Wider transition zone
// let transition_width = 0.2 * base_threshold;
// let diff = neighbor_weight - threshold;

// // Use the transition value directly instead of as a selector
// let transition = 1.0 - smoothstep(-transition_width, transition_width, diff);

// // Strong bias toward maintaining current state unless transition is significant
// let persistence = 0.7;
// let v = select(
// transition,
// nze,
// abs(nze - transition) < persistence
// );
// var thresh = params.ca_thresh;

// var result = current.x - nze;
// result = clamp(result, 0., 1.);

// textureStore(output_texture, upos, vec4f(result, current.y, current.z, nze));
// }
// // 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<u32>) {
let x = global_id.x;
Expand All @@ -116,25 +134,45 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {

let upos = vec2<i32>(i32(x), i32(y));
let current = textureLoad(input_texture, upos);

let edge_dist = current.b;
let nze = current.a;

// let result = nze;
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);

// let caves = 1.0;
var thresh = params.ca_thresh;

let nbs = get_weighted_neighbor_count(i32(x), i32(y), params.ca_search_radius);
// 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 * 5.; // 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.,
1.,
nbs > params.ca_thresh
selector
);

var result = current.r - caves;

// // result = current.z - result;
// result = clamp (result, 0., 1.);


textureStore(output_texture, upos, vec4f(current.x, current.y, current.z, caves));
}
}

// r, g, and b are left as is
// caves are added to a
3 changes: 2 additions & 1 deletion src/shaders/extract.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
var r = current.r - current.a;
r = clamp(r, 0., 1.);

textureStore(output_texture, upos, vec4f(r,current.y,current.z,1.));
// textureStore(output_texture, upos, vec4f(r,r,r,1.));
textureStore(output_texture, upos, vec4f(r, 0., 0., 1.0));
}
23 changes: 15 additions & 8 deletions src/shaders/generate_circle.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {

let dim = params.dimensions;

var pos = vec2f(
var normd_pos = vec2f(
f32(x) / f32(dim),
f32(y) / f32(dim)
);
Expand All @@ -75,7 +75,7 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let seed_mult = 10.0;
let center = vec2<f32>(0.5, 0.5);

let angle = atan2(pos.x - center.x, pos.y - center.y);
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);

Expand All @@ -88,16 +88,23 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
var result = mix(n, m, params.mix);

let r = params.radius * 0.4 + result;
let dist = distance(pos, center);
let dist_to_center = distance(normd_pos, center);
let upos = vec2<i32>(i32(x), i32(y));

let v = select(0.0, 1.0, dist <= r);
let v = select(0.0, 1.0, dist_to_center <= r);

pos = pos - center;
let mag = length(pos);
pos = vec2f(mag, 0.0);
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<f32>(v , dist, distance(pos, edge), 1.));
textureStore(output_texture, upos, vec4<f32>(v , dist_to_center, dist_to_edge, 1.));
}

// r contains generated terrain
// g contains distance field from center
// b contains distance field from edges
// a is unused


13 changes: 7 additions & 6 deletions src/shaders/pre_ca_noise.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
}
let pos = vec2f(f32(x), f32(y));
let upos = vec2<i32>(i32(x), i32(y));
let v = noise::rand11(f32(x * y));
// let v = noise::rand11(f32(x * (y*y)));
let v = noise::rand11(f32(x ^ (y << 16)));
let s = select(0.,1.,v <= params.noise_weight);


var current = textureLoad(input_texture, upos);
// var result = current.x-s;
// result = clamp(result, 0., 1.);

textureStore(output_texture, upos, vec4f(current.x, current.y, current.z, f32(s)));
}
}

// r, g, and b are left as is
// noise is added to a

0 comments on commit d28b447

Please sign in to comment.