-
-
Save nowl/828013 to your computer and use it in GitHub Desktop.
#include <stdio.h> | |
static int SEED = 0; | |
static int hash[] = {208,34,231,213,32,248,233,56,161,78,24,140,71,48,140,254,245,255,247,247,40, | |
185,248,251,245,28,124,204,204,76,36,1,107,28,234,163,202,224,245,128,167,204, | |
9,92,217,54,239,174,173,102,193,189,190,121,100,108,167,44,43,77,180,204,8,81, | |
70,223,11,38,24,254,210,210,177,32,81,195,243,125,8,169,112,32,97,53,195,13, | |
203,9,47,104,125,117,114,124,165,203,181,235,193,206,70,180,174,0,167,181,41, | |
164,30,116,127,198,245,146,87,224,149,206,57,4,192,210,65,210,129,240,178,105, | |
228,108,245,148,140,40,35,195,38,58,65,207,215,253,65,85,208,76,62,3,237,55,89, | |
232,50,217,64,244,157,199,121,252,90,17,212,203,149,152,140,187,234,177,73,174, | |
193,100,192,143,97,53,145,135,19,103,13,90,135,151,199,91,239,247,33,39,145, | |
101,120,99,3,186,86,99,41,237,203,111,79,220,135,158,42,30,154,120,67,87,167, | |
135,176,183,191,253,115,184,21,233,58,129,233,142,39,128,211,118,137,139,255, | |
114,20,218,113,154,27,127,246,250,1,8,198,250,209,92,222,173,21,88,102,219}; | |
int noise2(int x, int y) | |
{ | |
int tmp = hash[(y + SEED) % 256]; | |
return hash[(tmp + x) % 256]; | |
} | |
float lin_inter(float x, float y, float s) | |
{ | |
return x + s * (y-x); | |
} | |
float smooth_inter(float x, float y, float s) | |
{ | |
return lin_inter(x, y, s * s * (3-2*s)); | |
} | |
float noise2d(float x, float y) | |
{ | |
int x_int = x; | |
int y_int = y; | |
float x_frac = x - x_int; | |
float y_frac = y - y_int; | |
int s = noise2(x_int, y_int); | |
int t = noise2(x_int+1, y_int); | |
int u = noise2(x_int, y_int+1); | |
int v = noise2(x_int+1, y_int+1); | |
float low = smooth_inter(s, t, x_frac); | |
float high = smooth_inter(u, v, x_frac); | |
return smooth_inter(low, high, y_frac); | |
} | |
float perlin2d(float x, float y, float freq, int depth) | |
{ | |
float xa = x*freq; | |
float ya = y*freq; | |
float amp = 1.0; | |
float fin = 0; | |
float div = 0.0; | |
int i; | |
for(i=0; i<depth; i++) | |
{ | |
div += 256 * amp; | |
fin += noise2d(xa, ya) * amp; | |
amp /= 2; | |
xa *= 2; | |
ya *= 2; | |
} | |
return fin/div; | |
} | |
int | |
main(int argc, char *argv[]) | |
{ | |
int x, y; | |
for(y=0; y<4000; y++) | |
for(x=0; x<4000; x++) | |
perlin2d(x, y, 0.1, 4); | |
return 0; | |
} |
HASH is very flawed. It only has 163 unique numbers, many repeated more than twice. 245 appears 5 times? This should just be a random permutation of all values from 0 to 255. This drastically reduces the effective randomness of your hashing.
Also, as pointed out above, this isn't Perlin noise, which should be generating a random normal vector at each corner, computing a dot product, and then interpolating that. It does use the smooth-step interpolation and the harmonic/fractal layering that normally comes with Perlin noise, but misses the core property that makes Perlin noise different than other types of noise.
One more thing: consider having SEED affect both X and Y in some way. The current implementation just adds it to Y, which means that all seeds are the same, just vertically displaced from each other. I think more ideally your random seed would be used to re-shuffle HASH instead.
It's not the Perlin noise, it's the value noise. Ken Perlin used random vectors instead of random numbers