Implemented simple terrain generation

This commit is contained in:
Lorenzo Torres 2025-08-13 21:16:42 +02:00
parent fb9607b2b1
commit c0b8d021d4
16 changed files with 825 additions and 32 deletions

78
src/math/PerlinNoise.zig Normal file
View file

@ -0,0 +1,78 @@
const std = @import("std");
const Self = @This();
seed: u64,
fn hash(self: Self, x: i32, y: i32) u64 {
var hasher = std.hash.Wyhash.init(self.seed);
hasher.update(std.mem.asBytes(&x));
hasher.update(std.mem.asBytes(&y));
return hasher.final();
}
fn random(self: Self, x: i32, y: i32) @Vector(2, f64) {
const h = self.hash(x, y);
var rng = std.Random.DefaultPrng.init(h);
const angle = rng.random().float(f64) * std.math.tau;
return .{ std.math.cos(angle), std.math.sin(angle) };
}
fn dot(a: @Vector(2, f64), b: @Vector(2, f64)) f64 {
return @reduce(.Add, a*b);
}
fn fade(t: f64) f64 {
return t * t * t * (t * (t * 6 - 15) + 10);
}
fn lerp(a: f64, b: f64, t: f64) f64 {
return a + t * (b - a);
}
fn noise(self: Self, x: f64, y: f64) f64 {
const x0 = @as(i32, @intFromFloat(std.math.floor(x)));
const y0 = @as(i32, @intFromFloat(std.math.floor(y)));
const x1 = x0 + 1;
const y1 = y0 + 1;
const sx = fade(x - @as(f64, @floatFromInt(x0)));
const sy = fade(y - @as(f64, @floatFromInt(y0)));
const grad00 = self.random(x0, y0);
const grad10 = self.random(x1, y0);
const grad01 = self.random(x0, y1);
const grad11 = self.random(x1, y1);
const dx = x - @as(f64, @floatFromInt(x0));
const dy = y - @as(f64, @floatFromInt(y0));
const dot00 = dot(grad00, .{ dx, dy });
const dot10 = dot(grad10, .{ dx - 1, dy });
const dot01 = dot(grad01, .{ dx, dy - 1 });
const dot11 = dot(grad11, .{ dx - 1, dy - 1 });
const ix0 = lerp(dot00, dot10, sx);
const ix1 = lerp(dot01, dot11, sx);
const value = lerp(ix0, ix1, sy);
return value;
}
pub fn fbm(self: Self, x: f64, y: f64, octaves: u32, lacunarity: f64, gain: f64) f64 {
var total: f64 = 0.0;
var amplitude: f64 = 1.0;
var frequency: f64 = 1.0;
var maxAmplitude: f64 = 1.0;
for(0..octaves) |_| {
total += self.noise(x * frequency, y * frequency) * amplitude;
maxAmplitude += amplitude;
amplitude *= gain;
frequency *= lacunarity;
}
return total / maxAmplitude;
}