worldgen: fractal Perlin noise
This commit is contained in:
parent
252ff19f2a
commit
c3ae9c4942
41
src/main.cpp
41
src/main.cpp
|
@ -67,17 +67,19 @@ static num lerp(num x, num y, num t)
|
|||
|
||||
static num dot(vec2 *grid, int GRID_N, int ix, int iy, num fx, num fy)
|
||||
{
|
||||
vec2 g = grid[iy * GRID_N + ix];
|
||||
/* Wrap the grid around to get a torus effect, so the noise does not appear
|
||||
discontinuous when we repeat it during fractal sampling */
|
||||
vec2 g = grid[(iy % GRID_N) * GRID_N + (ix % GRID_N)];
|
||||
return (fx - num(ix)) * g.x + (fy - num(iy)) * g.y;
|
||||
}
|
||||
|
||||
static uint8_t *perlinNoise(int N, int PERLIN_CELL_SIZE)
|
||||
static int8_t *perlinNoise(int N, int PERLIN_CELL_SIZE)
|
||||
{
|
||||
uint8_t *noise = new uint8_t[N * N];
|
||||
int8_t *noise = new int8_t[N * N];
|
||||
if(!noise)
|
||||
return nullptr;
|
||||
|
||||
int GRID_N = (N / PERLIN_CELL_SIZE) + 1;
|
||||
int GRID_N = N / PERLIN_CELL_SIZE;
|
||||
vec2 *grid = new vec2[GRID_N * GRID_N];
|
||||
if(!grid) {
|
||||
delete[] noise;
|
||||
|
@ -104,24 +106,43 @@ static uint8_t *perlinNoise(int N, int PERLIN_CELL_SIZE)
|
|||
num ry = smooth(fy - num(iy));
|
||||
|
||||
num v = lerp(lerp(d0, d1, rx), lerp(d2, d3, rx), ry);
|
||||
noise[y * N + x] = 128 + (int)(v * num(127));
|
||||
noise[y * N + x] = (int)(v * num(128));
|
||||
}
|
||||
|
||||
delete[] grid;
|
||||
return noise;
|
||||
}
|
||||
|
||||
static int8_t samplePerlin(int8_t *noise, int N, int x, int y, int levels)
|
||||
{
|
||||
int8_t result = 0;
|
||||
|
||||
for(int i = 0; i < levels; i++) {
|
||||
/* Add something depending on i to decorrelate octaves */
|
||||
int wy = ((y << i) + (17 * i + 5)) % N;
|
||||
int wx = ((x << i) + (13 * i + 1)) % N;
|
||||
int tmp = result + (noise[wy * N + wx] >> i);
|
||||
result = max(-128, min(tmp, 127));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#include <gint/display.h>
|
||||
void perlinTest(void)
|
||||
{
|
||||
uint8_t *noise;
|
||||
int time = prof_exec({ noise = perlinNoise(128, 16); });
|
||||
int8_t *noise;
|
||||
int N = 128;
|
||||
int PERLIN_CELL_SIZE = 16;
|
||||
|
||||
int time = prof_exec({ noise = perlinNoise(N, PERLIN_CELL_SIZE); });
|
||||
dclear(C_RED);
|
||||
|
||||
if(noise)
|
||||
for(int y = 0; y < 128; y++)
|
||||
for(int x = 0; x < 128; x++) {
|
||||
int gray = noise[y * 128 + x] >> 3;
|
||||
for(int y = 0; y < N; y++)
|
||||
for(int x = 0; x < N; x++) {
|
||||
int v = samplePerlin(noise, N, x, y, 3);
|
||||
int gray = 16 + (v >> 3);
|
||||
dpixel(x, y, C_RGB(gray, gray, gray));
|
||||
}
|
||||
dprint(2, DHEIGHT-20, C_WHITE, "time = %d ms", time / 1000);
|
||||
|
|
Loading…
Reference in New Issue