polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

perlin.c (2106B)


      1 #include <stdio.h>
      2 
      3 static int hash[] = {
      4   208,34,231,213,32,248,233,56,161,78,24,140,71,48,140,254,245,255,247,247,40,
      5   185,248,251,245,28,124,204,204,76,36,1,107,28,234,163,202,224,245,128,167,204,
      6   9,92,217,54,239,174,173,102,193,189,190,121,100,108,167,44,43,77,180,204,8,81,
      7   70,223,11,38,24,254,210,210,177,32,81,195,243,125,8,169,112,32,97,53,195,13,
      8   203,9,47,104,125,117,114,124,165,203,181,235,193,206,70,180,174,0,167,181,41,
      9   164,30,116,127,198,245,146,87,224,149,206,57,4,192,210,65,210,129,240,178,105,
     10   228,108,245,148,140,40,35,195,38,58,65,207,215,253,65,85,208,76,62,3,237,55,89,
     11   232,50,217,64,244,157,199,121,252,90,17,212,203,149,152,140,187,234,177,73,174,
     12   193,100,192,143,97,53,145,135,19,103,13,90,135,151,199,91,239,247,33,39,145,
     13   101,120,99,3,186,86,99,41,237,203,111,79,220,135,158,42,30,154,120,67,87,167,
     14   135,176,183,191,253,115,184,21,233,58,129,233,142,39,128,211,118,137,139,255,
     15   114,20,218,113,154,27,127,246,250,1,8,198,250,209,92,222,173,21,88,102,219};
     16 
     17 int noise2(int seed, int x, int y) {
     18     int tmp = hash[(y + seed) % 256];
     19     return hash[(tmp + x) % 256];
     20 }
     21 
     22 float lin_inter(float x, float y, float s) {
     23     return x + s * (y-x);
     24 }
     25 
     26 float smooth_inter(float x, float y, float s) {
     27     return lin_inter(x, y, s * s * (3-2*s));
     28 }
     29 
     30 float noise2d(int seed, float x, float y) {
     31     int x_int = x;
     32     int y_int = y;
     33     float x_frac = x - x_int;
     34     float y_frac = y - y_int;
     35     int s = noise2(seed, x_int, y_int);
     36     int t = noise2(seed, x_int+1, y_int);
     37     int u = noise2(seed, x_int, y_int+1);
     38     int v = noise2(seed, x_int+1, y_int+1);
     39     float low = smooth_inter(s, t, x_frac);
     40     float high = smooth_inter(u, v, x_frac);
     41     return smooth_inter(low, high, y_frac);
     42 }
     43 
     44 float perlin2d(int seed, float x, float y, float freq, int depth) {
     45     float xa = x*freq;
     46     float ya = y*freq;
     47     float amp = 1.0;
     48     float fin = 0;
     49     float div = 0.0;
     50 
     51     int i;
     52     for(i=0; i<depth; i++)
     53     {
     54         div += 256 * amp;
     55         fin += noise2d(seed, xa, ya) * amp;
     56         amp /= 2;
     57         xa *= 2;
     58         ya *= 2;
     59     }
     60 
     61     return fin/div;
     62 }
     63