Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Perlin Noise
#include <algorithm>
#include <random>
using namespace std;
void createRandomHash(vector<uint8_t>& hash)
{
random_device r;
default_random_engine re(r());
hash.resize(256);
iota(hash.begin(), hash.end(), 0);
shuffle(hash.begin(), hash.end(), re);
hash.insert(hash.end(), hash.begin(), hash.end());
}
inline
uint8_t hash(const vector<uint8_t>& h, unsigned int a, unsigned int b) { return h[h[a] + b]; }
// Our easing function
inline
double fade(double t) { return t*t*t*(t*(t*6.-15.)+10.); }
inline
double lerp(double t, double a, double b) { return a + t * (b - a); }
inline
double gradient(uint8_t hash, double x, double y)
{
return ((hash & 1) ? x : -x) + ((hash & 2) ? y : -y);
}
double noise(double x, double y)
{
int xi = (int)x & 255;
int yi = (int)y & 255;
x -= (int)x;
y -= (int)y;
double u = fade(x);
double v = fade(y);
uint8_t aa = hash(xi, yi);
uint8_t ab = hash(xi, yi+1);
uint8_t ba = hash(xi+1, yi);
uint8_t bb = hash(xi+1, yi+1);
double val = lerp(v,
lerp(u, gradient(aa, x, y), gradient(ba, x-1, y)),
lerp(u, gradient(ab, x, y-1), gradient(bb, x-1, y-1)));
return (val + 1.)/2.;
}
int main(int argc, char** argv)
{
unsigned int width = 100, height = 100;
for (unsigned int i=0; i<height; ++i)
{
for (unsigned int j=0; j<width; ++j)
{
double x = (double)j/(double)width;
double y = (double)i/(double)height;
double n = noise(10*x, 10*y);
// 'n' is the value to assign to the pixel at (j, i)
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.