Merge branch 'perlin' of https://github.com/Auburns/stb into working

This commit is contained in:
Sean Barrett 2019-02-07 04:54:14 -08:00
commit ca980dd2dc

View File

@ -40,16 +40,13 @@
// 'octaves' times, so this parameter will affect runtime. // 'octaves' times, so this parameter will affect runtime.
// //
// float stb_perlin_ridge_noise3(float x, float y, float z, // float stb_perlin_ridge_noise3(float x, float y, float z,
// float lacunarity, float gain, float offset, int octaves, // float lacunarity, float gain, float offset, int octaves)
// int x_wrap, int y_wrap, int z_wrap);
// //
// float stb_perlin_fbm_noise3(float x, float y, float z, // float stb_perlin_fbm_noise3(float x, float y, float z,
// float lacunarity, float gain, int octaves, // float lacunarity, float gain, int octaves)
// int x_wrap, int y_wrap, int z_wrap);
// //
// float stb_perlin_turbulence_noise3(float x, float y, float z, // float stb_perlin_turbulence_noise3(float x, float y, float z,
// float lacunarity, float gain,int octaves, // float lacunarity, float gain, int octaves)
// int x_wrap, int y_wrap, int z_wrap);
// //
// Typical values to start playing with: // Typical values to start playing with:
// octaves = 6 -- number of "octaves" of noise3() to sum // octaves = 6 -- number of "octaves" of noise3() to sum
@ -60,6 +57,7 @@
// //
// Contributors: // Contributors:
// Jack Mott - additional noise functions // Jack Mott - additional noise functions
// Jordan Peck - seeded noise
// //
@ -67,18 +65,19 @@
extern "C" { extern "C" {
#endif #endif
extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap); extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
extern float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float gain, float offset, int octaves,int x_wrap, int y_wrap, int z_wrap); extern float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves);
extern float stb_perlin_fbm_noise3(float x, float y, float z,float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap); extern float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap); extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#ifdef STB_PERLIN_IMPLEMENTATION #ifdef STB_PERLIN_IMPLEMENTATION
#include <math.h> // fabs()
// not same permutation table as Perlin's reference to avoid copyright issues; // not same permutation table as Perlin's reference to avoid copyright issues;
// Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/ // Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/
// @OPTIMIZE: should this be unsigned char instead of int for cache?
static unsigned char stb__perlin_randtab[512] = static unsigned char stb__perlin_randtab[512] =
{ {
23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123, 23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
@ -117,6 +116,51 @@ static unsigned char stb__perlin_randtab[512] =
61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5, 61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
}; };
// perlin's gradient has 12 cases so some get used 1/16th of the time
// and some 2/16ths. We reduce bias by changing those fractions
// to 5/64ths and 6/64ths
// this array is designed to match the previous implementation
// of gradient hash: indices[stb__perlin_randtab[i]&63]
static unsigned char stb__perlin_randtab_grad_idx[512] =
{
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
// and a second copy so we don't need an extra mask or static initializer
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
};
static float stb__perlin_lerp(float a, float b, float t) static float stb__perlin_lerp(float a, float b, float t)
{ {
return a + (b-a) * t; return a + (b-a) * t;
@ -129,7 +173,7 @@ static int stb__perlin_fastfloor(float a)
} }
// different grad function from Perlin's, but easy to modify to match reference // different grad function from Perlin's, but easy to modify to match reference
static float stb__perlin_grad(int hash, float x, float y, float z) static float stb__perlin_grad(int grad_idx, float x, float y, float z)
{ {
static float basis[12][4] = static float basis[12][4] =
{ {
@ -147,26 +191,11 @@ static float stb__perlin_grad(int hash, float x, float y, float z)
{ 0,-1,-1 }, { 0,-1,-1 },
}; };
// perlin's gradient has 12 cases so some get used 1/16th of the time float *grad = basis[grad_idx];
// and some 2/16ths. We reduce bias by changing those fractions
// to 5/64ths and 6/64ths, and the same 4 cases get the extra weight.
static unsigned char indices[64] =
{
0,1,2,3,4,5,6,7,8,9,10,11,
0,9,1,11,
0,1,2,3,4,5,6,7,8,9,10,11,
0,1,2,3,4,5,6,7,8,9,10,11,
0,1,2,3,4,5,6,7,8,9,10,11,
0,1,2,3,4,5,6,7,8,9,10,11,
};
// if you use reference permutation table, change 63 below to 15 to match reference
// (this is why the ordering of the table above is funky)
float *grad = basis[indices[hash & 63]];
return grad[0]*x + grad[1]*y + grad[2]*z; return grad[0]*x + grad[1]*y + grad[2]*z;
} }
float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap) float stb_perlin_noise3_internal(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
{ {
float u,v,w; float u,v,w;
float n000,n001,n010,n011,n100,n101,n110,n111; float n000,n001,n010,n011,n100,n101,n110,n111;
@ -190,22 +219,22 @@ float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z
y -= py; v = stb__perlin_ease(y); y -= py; v = stb__perlin_ease(y);
z -= pz; w = stb__perlin_ease(z); z -= pz; w = stb__perlin_ease(z);
r0 = stb__perlin_randtab[x0]; r0 = stb__perlin_randtab[x0+seed];
r1 = stb__perlin_randtab[x1]; r1 = stb__perlin_randtab[x1+seed];
r00 = stb__perlin_randtab[r0+y0]; r00 = stb__perlin_randtab[r0+y0];
r01 = stb__perlin_randtab[r0+y1]; r01 = stb__perlin_randtab[r0+y1];
r10 = stb__perlin_randtab[r1+y0]; r10 = stb__perlin_randtab[r1+y0];
r11 = stb__perlin_randtab[r1+y1]; r11 = stb__perlin_randtab[r1+y1];
n000 = stb__perlin_grad(stb__perlin_randtab[r00+z0], x , y , z ); n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
n001 = stb__perlin_grad(stb__perlin_randtab[r00+z1], x , y , z-1 ); n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
n010 = stb__perlin_grad(stb__perlin_randtab[r01+z0], x , y-1, z ); n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
n011 = stb__perlin_grad(stb__perlin_randtab[r01+z1], x , y-1, z-1 ); n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
n100 = stb__perlin_grad(stb__perlin_randtab[r10+z0], x-1, y , z ); n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
n101 = stb__perlin_grad(stb__perlin_randtab[r10+z1], x-1, y , z-1 ); n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
n110 = stb__perlin_grad(stb__perlin_randtab[r11+z0], x-1, y-1, z ); n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
n111 = stb__perlin_grad(stb__perlin_randtab[r11+z1], x-1, y-1, z-1 ); n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
n00 = stb__perlin_lerp(n000,n001,w); n00 = stb__perlin_lerp(n000,n001,w);
n01 = stb__perlin_lerp(n010,n011,w); n01 = stb__perlin_lerp(n010,n011,w);
@ -218,7 +247,12 @@ float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z
return stb__perlin_lerp(n0,n1,u); return stb__perlin_lerp(n0,n1,u);
} }
float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float gain, float offset, int octaves,int x_wrap, int y_wrap, int z_wrap) float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
{
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap,0);
}
float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves)
{ {
int i; int i;
float frequency = 1.0f; float frequency = 1.0f;
@ -227,9 +261,8 @@ float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float
float sum = 0.0f; float sum = 0.0f;
for (i = 0; i < octaves; i++) { for (i = 0; i < octaves; i++) {
float r = (float)(stb_perlin_noise3(x*frequency,y*frequency,z*frequency,x_wrap,y_wrap,z_wrap)); float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i);
r = r<0 ? -r : r; // fabs() r = offset - fabs(r);
r = offset - r;
r = r*r; r = r*r;
sum += r*amplitude*prev; sum += r*amplitude*prev;
prev = r; prev = r;
@ -239,7 +272,7 @@ float stb_perlin_ridge_noise3(float x, float y, float z,float lacunarity, float
return sum; return sum;
} }
float stb_perlin_fbm_noise3(float x, float y, float z,float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap) float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
{ {
int i; int i;
float frequency = 1.0f; float frequency = 1.0f;
@ -247,14 +280,14 @@ float stb_perlin_fbm_noise3(float x, float y, float z,float lacunarity, float ga
float sum = 0.0f; float sum = 0.0f;
for (i = 0; i < octaves; i++) { for (i = 0; i < octaves; i++) {
sum += stb_perlin_noise3(x*frequency,y*frequency,z*frequency,x_wrap,y_wrap,z_wrap)*amplitude; sum += stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
frequency *= lacunarity; frequency *= lacunarity;
amplitude *= gain; amplitude *= gain;
} }
return sum; return sum;
} }
float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves,int x_wrap, int y_wrap, int z_wrap) float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
{ {
int i; int i;
float frequency = 1.0f; float frequency = 1.0f;
@ -262,9 +295,8 @@ float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity,
float sum = 0.0f; float sum = 0.0f;
for (i = 0; i < octaves; i++) { for (i = 0; i < octaves; i++) {
float r = stb_perlin_noise3(x*frequency,y*frequency,z*frequency,x_wrap,y_wrap,z_wrap)*amplitude; float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
r = r<0 ? -r : r; // fabs() sum += fabs(r);
sum += r;
frequency *= lacunarity; frequency *= lacunarity;
amplitude *= gain; amplitude *= gain;
} }