xxxxxxxxxx
188
const gridSize = 512;
const tileSize = 1;
const w = gridSize * tileSize;
const h = gridSize * tileSize;
let offsetXSlider;
let offsetYSlider;
let octavesSlider;
let frequencySlider;
let lacunaritySlider;
let persistenceSlider;
let pr = new PseudoRandom();
function setup() {
createCanvas(w, h).parent("Canvas");
setupSliders();
loadPixels();
// console.log(smootherStep(0.15));
}
function draw() {
background(220);
noStroke();
const fractalParams = new FractalNoiseParams(
423525,
octavesSlider.value(),
new NoiseParams(
1 / frequencySlider.value(),
lacunaritySlider.value(),
persistenceSlider.value()
)
);
const tilesX = w / tileSize;
const tilesY = h / tileSize;
const noise = generateNoiseMap(fractalParams, tilesX, tilesY);
const curveWidth = 10;
let start, end, ctrl;
if (pr.nextBool()) {
start = new Vec2(pr.nextIntRange(0, tilesX), 0);
end = new Vec2(pr.nextIntRange(0, tilesX), tilesY);
ctrl = new Vec2(pr.nextIntRange(0, tilesX), tilesY / 2);
} else {
start = new Vec2(0, pr.nextIntRange(0, tilesY));
end = new Vec2(tilesX, pr.nextIntRange(0, tilesY));
ctrl = new Vec2(tilesX / 2, pr.nextIntRange(0, tilesY));
}
if (start.y > end.y) {
const t = start;
start = end;
end = t;
}
let pacb = start;
let u = 0;
for (let ct = -0.015; ct <= 1.015; ct += 0.00055) {
const acb = bez(start, end, ctrl, ct);
const diff = Vec2.sub(acb, pacb);
const norm = Vec2.norm(diff);
const perp = new Vec2(-norm.y, norm.x);
pacb = acb;
for (let nt = -curveWidth; nt <= curveWidth; nt += 1) {
const np = Vec2.mulByNum(perp, nt);
const p = Vec2.floor(Vec2.add(acb, np));
const pi = new Vec2(
math.clamp(p.x, 0, tilesX-1),
math.clamp(p.y, 0, tilesY-1)
);
noise[pi.y * tilesX + pi.x] = 0;
}
}
drawNoise(noise, tilesX, tilesY);
noLoop();
}
function bez(start, end, ctrl, t) {
const ac = Vec2.mix(start, ctrl, t);
const cb = Vec2.mix(ctrl, end, t);
return Vec2.mix(ac, cb, t);
}
function generateCurvePoints(start, end, ctrl) {
const points = [];
for (let ct = -0.02; ct <= 1.02; ct += 0.01) { // 00055
const acb = bez(start, end, ctrl, ct);
points.push(acb);
}
return points;
}
function drawNoise(noise, tilesX, tilesY) {
for (let y = 0; y < tilesY; y++) {
for (let x = 0; x < tilesX; x++) {
let n = noise[y * tilesX + x];
set(x * tileSize, y * tileSize, 255 * n);
}
}
updatePixels();
}
function generateNoiseMap(fractalParams, sizeX, sizeY) {
const noise = new Float32Array(sizeX * sizeY);
for (let y = 0; y < sizeY; y++) {
for (let x = 0; x < sizeX; x++) {
const pos = Vec2.add(
new Vec2(x, y),
new Vec2(offsetXSlider.value(), offsetYSlider.value())
);
n = Noise.fractalNoise(pos, fractalParams, Noise.smoothValueNoise2d);
noise[y * sizeX + x] = n;
}
}
return noise;
}
function smoothValueNoise2d(p) {
const cellId = Vec2.floor(p);
const cellFract = Vec2.smoothStep(Vec2.fract(p));
// lerp from bottom-left to bottom-right
const bottomLeft = Noise.valueNoise2d(cellId);
const bottomRight = Noise.valueNoise2d(Vec2.add(cellId, Vec2.Right));
const bottom = math.mix(bottomLeft, bottomRight, cellFract.x);
// lerp from top-left to top-right
const topLeft = Noise.valueNoise2d(Vec2.add(cellId, Vec2.Up));
const topRight = Noise.valueNoise2d(Vec2.add(cellId, Vec2.One));
const top = math.mix(topLeft, topRight, cellFract.x);
// lerp from bottom to top
const n = math.mix(bottom * 2 - 1, top * 2 - 1, cellFract.y);
return n;
}
function smootherStep(x) {
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}
function smootherStep2(v) {
return new Vec2(smootherStep(v.x), smootherStep(v.y));
}
function setupSliders() {
offsetXSlider = createSlider(-w * 10, w * 10, 0, tileSize)
.input(() => draw())
.parent("NoiseOffsetX");
offsetYSlider = createSlider(-h * 10, h * 10, 0, tileSize)
.input(() => draw())
.parent("NoiseOffsetY");
octavesSlider = createSlider(1, 5, 5, 1)
.input(() => draw())
.parent("NoiseOctaves");
frequencySlider = createSlider(1, 500, 250, 0.1)
.input(() => draw())
.parent("NoiseFrequency");
lacunaritySlider = createSlider(0.03, 4, 2, 0.1)
.input(() => draw())
.parent("NoiseLacunarity");
persistenceSlider = createSlider(0.1, 2, 0.5, 0.1)
.input(() => draw())
.parent("NoisePersistence");
}