Skip to content
This repository has been archived by the owner on Apr 2, 2021. It is now read-only.

Add OpenSimplex2, alternative to Simplex. #43

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions FastNoiseSIMD/FastNoiseSIMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,12 @@ void FastNoiseSIMD::FillNoiseSet(float* noiseSet, int xStart, int yStart, int zS
case SimplexFractal:
FillSimplexFractalSet(noiseSet, xStart, yStart, zStart, xSize, ySize, zSize, scaleModifier);
break;
case OpenSimplex2:
FillOpenSimplex2Set(noiseSet, xStart, yStart, zStart, xSize, ySize, zSize, scaleModifier);
break;
case OpenSimplex2Fractal:
FillOpenSimplex2FractalSet(noiseSet, xStart, yStart, zStart, xSize, ySize, zSize, scaleModifier);
break;
case WhiteNoise:
FillWhiteNoiseSet(noiseSet, xStart, yStart, zStart, xSize, ySize, zSize, scaleModifier);
break;
Expand Down Expand Up @@ -461,6 +467,12 @@ void FastNoiseSIMD::FillNoiseSet(float* noiseSet, FastNoiseVectorSet* vectorSet,
case SimplexFractal:
FillSimplexFractalSet(noiseSet, vectorSet, xOffset, yOffset, zOffset);
break;
case OpenSimplex2:
FillOpenSimplex2Set(noiseSet, vectorSet, xOffset, yOffset, zOffset);
break;
case OpenSimplex2Fractal:
FillOpenSimplex2FractalSet(noiseSet, vectorSet, xOffset, yOffset, zOffset);
break;
case WhiteNoise:
FillWhiteNoiseSet(noiseSet, vectorSet, xOffset, yOffset, zOffset);
break;
Expand Down Expand Up @@ -508,6 +520,9 @@ GET_SET(PerlinFractal)
GET_SET(Simplex)
GET_SET(SimplexFractal)

GET_SET(OpenSimplex2)
GET_SET(OpenSimplex2Fractal)

GET_SET(Cellular)

GET_SET(Cubic)
Expand Down
9 changes: 8 additions & 1 deletion FastNoiseSIMD/FastNoiseSIMD.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class FastNoiseSIMD
{
public:

enum NoiseType { Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, WhiteNoise, Cellular, Cubic, CubicFractal };
enum NoiseType { Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, OpenSimplex2, OpenSimplex2Fractal, WhiteNoise, Cellular, Cubic, CubicFractal };
enum FractalType { FBM, Billow, RigidMulti };
enum PerturbType { None, Gradient, GradientFractal, Normalise, Gradient_Normalise, GradientFractal_Normalise };

Expand Down Expand Up @@ -279,6 +279,13 @@ class FastNoiseSIMD
virtual void FillSimplexSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;
virtual void FillSimplexFractalSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;

float* GetOpenSimplex2Set(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f);
float* GetOpenSimplex2FractalSet(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f);
virtual void FillOpenSimplex2Set(float* noiseSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) = 0;
virtual void FillOpenSimplex2FractalSet(float* noiseSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) = 0;
virtual void FillOpenSimplex2Set(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;
virtual void FillOpenSimplex2FractalSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;

float* GetCellularSet(int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f);
virtual void FillCellularSet(float* noiseSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) = 0;
virtual void FillCellularSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) = 0;
Expand Down
78 changes: 78 additions & 0 deletions FastNoiseSIMD/FastNoiseSIMD_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ static float FUNC(INV_SQRT)(float x)
#define SIMDf_XOR(a,b) SIMDf_CAST_TO_FLOAT(SIMDi_CAST_TO_INT(a) ^ SIMDi_CAST_TO_INT(b))

#define SIMDf_FLOOR(a) floorf(a)
#define SIMDf_ROUND(a) roundf(a)
#define SIMDf_ABS(a) fabsf(a)
#define SIMDf_BLENDV(a,b,mask) (mask ? (b) : (a))
#define SIMDf_GATHER(p,a) (*(reinterpret_cast<const float*>(p)+(a)))
Expand Down Expand Up @@ -566,15 +567,18 @@ static SIMDf SIMDf_NUM(10);
static SIMDf SIMDf_NUM(15);
static SIMDf SIMDf_NUM(32);
static SIMDf SIMDf_NUM(999999);
static SIMDf SIMDf_NUM(_1);

static SIMDf SIMDf_NUM(0_5);
static SIMDf SIMDf_NUM(0_6);
static SIMDf SIMDf_NUM(15_5);
static SIMDf SIMDf_NUM(511_5);
static SIMDf SIMDf_NUM(32768_5);

//static SIMDf SIMDf_NUM(cellJitter);
static SIMDf SIMDf_NUM(F3);
static SIMDf SIMDf_NUM(G3);
static SIMDf SIMDf_NUM(R3);
static SIMDf SIMDf_NUM(G33);
static SIMDf SIMDf_NUM(hash2Float);
static SIMDf SIMDf_NUM(vectorSize);
Expand Down Expand Up @@ -632,15 +636,18 @@ void FUNC(InitSIMDValues)()
SIMDf_NUM(15) = SIMDf_SET(15.0f);
SIMDf_NUM(32) = SIMDf_SET(32.0f);
SIMDf_NUM(999999) = SIMDf_SET(999999.0f);
SIMDf_NUM(_1) = SIMDf_SET(-1.0f);

SIMDf_NUM(0_5) = SIMDf_SET(0.5f);
SIMDf_NUM(0_6) = SIMDf_SET(0.6f);
SIMDf_NUM(15_5) = SIMDf_SET(15.5f);
SIMDf_NUM(511_5) = SIMDf_SET(511.5f);
SIMDf_NUM(32768_5) = SIMDf_SET(32768.5f);

//SIMDf_NUM(cellJitter) = SIMDf_SET(0.39614f);
SIMDf_NUM(F3) = SIMDf_SET(1.f / 3.f);
SIMDf_NUM(G3) = SIMDf_SET(1.f / 6.f);
SIMDf_NUM(R3) = SIMDf_SET(2.f / 3.f);
SIMDf_NUM(G33) = SIMDf_SET((3.f / 6.f) - 1.f);
SIMDf_NUM(hash2Float) = SIMDf_SET(1.f / 2147483648.f);
SIMDf_NUM(vectorSize) = SIMDf_SET(VECTOR_SIZE);
Expand Down Expand Up @@ -922,6 +929,65 @@ static SIMDf VECTORCALL FUNC(SimplexSingle)(SIMDi seed, SIMDf x, SIMDf y, SIMDf
return SIMDf_MUL(SIMDf_NUM(32), SIMDf_MASK_ADD(n0, SIMDf_MASK_ADD(n1, SIMDf_MASK_ADD(n2, v3, v2), v1), v0));
}

static SIMDf VECTORCALL FUNC(OpenSimplex2Single)(SIMDi seed, SIMDf x, SIMDf y, SIMDf z)
{
SIMDf f = SIMDf_MUL(SIMDf_NUM(R3), SIMDf_ADD(SIMDf_ADD(x, y), z));
SIMDf xr = SIMDf_SUB(f, x);
SIMDf yr = SIMDf_SUB(f, y);
SIMDf zr = SIMDf_SUB(f, z);

SIMDf val = SIMDf_NUM(0);
for (int i = 0; i < 2; i++)
{
SIMDf v0xr = SIMDf_FLOOR(SIMDf_ADD(xr, SIMDf_NUM(0_5)));
SIMDf v0yr = SIMDf_FLOOR(SIMDf_ADD(yr, SIMDf_NUM(0_5)));
SIMDf v0zr = SIMDf_FLOOR(SIMDf_ADD(zr, SIMDf_NUM(0_5)));
SIMDf d0xr = SIMDf_SUB(xr, v0xr);
SIMDf d0yr = SIMDf_SUB(yr, v0yr);
SIMDf d0zr = SIMDf_SUB(zr, v0zr);

SIMDf score0xr = SIMDf_ABS(d0xr);
SIMDf score0yr = SIMDf_ABS(d0yr);
SIMDf score0zr = SIMDf_ABS(d0zr);
MASK dir0xr = SIMDf_LESS_EQUAL(SIMDf_MAX(score0yr, score0zr), score0xr);
MASK dir0yr = SIMDi_AND_NOT(dir0xr, SIMDf_LESS_EQUAL(SIMDf_MAX(score0zr, score0xr), score0yr));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MASK dir0yr = SIMDi_AND_NOT(dir0xr, SIMDf_LESS_EQUAL(SIMDf_MAX(score0zr, score0xr), score0yr));
MASK dir0yr = MASK_AND_NOT(dir0xr, SIMDf_LESS_EQUAL(SIMDf_MAX(score0zr, score0xr), score0yr));

MASK dir0zr = SIMDi_NOT(SIMDi_OR(dir0xr, dir0yr));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MASK dir0zr = SIMDi_NOT(SIMDi_OR(dir0xr, dir0yr));
MASK dir0zr = MASK_NOT(MASK_OR(dir0xr, dir0yr));

SIMDf v1xr = SIMDf_ADD(v0xr, SIMDf_BLENDV(SIMDf_NUM(0), SIMDf_BLENDV(SIMDf_NUM(1), SIMDf_NUM(_1), SIMDf_LESS_THAN(d0xr, SIMDf_NUM(0))), dir0xr));
SIMDf v1yr = SIMDf_ADD(v0yr, SIMDf_BLENDV(SIMDf_NUM(0), SIMDf_BLENDV(SIMDf_NUM(1), SIMDf_NUM(_1), SIMDf_LESS_THAN(d0yr, SIMDf_NUM(0))), dir0yr));
SIMDf v1zr = SIMDf_ADD(v0zr, SIMDf_BLENDV(SIMDf_NUM(0), SIMDf_BLENDV(SIMDf_NUM(1), SIMDf_NUM(_1), SIMDf_LESS_THAN(d0zr, SIMDf_NUM(0))), dir0zr));
SIMDf d1xr = SIMDf_SUB(xr, v1xr);
SIMDf d1yr = SIMDf_SUB(yr, v1yr);
SIMDf d1zr = SIMDf_SUB(zr, v1zr);

SIMDi hv0xr = SIMDi_MUL(SIMDi_CONVERT_TO_INT(v0xr), SIMDi_NUM(xPrime));
SIMDi hv0yr = SIMDi_MUL(SIMDi_CONVERT_TO_INT(v0yr), SIMDi_NUM(yPrime));
SIMDi hv0zr = SIMDi_MUL(SIMDi_CONVERT_TO_INT(v0zr), SIMDi_NUM(zPrime));
SIMDi hv1xr = SIMDi_MUL(SIMDi_CONVERT_TO_INT(v1xr), SIMDi_NUM(xPrime));
SIMDi hv1yr = SIMDi_MUL(SIMDi_CONVERT_TO_INT(v1yr), SIMDi_NUM(yPrime));
SIMDi hv1zr = SIMDi_MUL(SIMDi_CONVERT_TO_INT(v1zr), SIMDi_NUM(zPrime));

SIMDf t0 = SIMDf_NMUL_ADD(d0zr, d0zr, SIMDf_NMUL_ADD(d0yr, d0yr, SIMDf_NMUL_ADD(d0xr, d0xr, SIMDf_NUM(0_6))));
SIMDf t1 = SIMDf_NMUL_ADD(d1zr, d1zr, SIMDf_NMUL_ADD(d1yr, d1yr, SIMDf_NMUL_ADD(d1xr, d1xr, SIMDf_NUM(0_6))));
MASK n0 = SIMDf_GREATER_THAN(t0, SIMDf_NUM(0));
MASK n1 = SIMDf_GREATER_THAN(t1, SIMDf_NUM(0));
t0 = SIMDf_MUL(t0, t0);
t1 = SIMDf_MUL(t1, t1);

SIMDf v0 = SIMDf_MUL(SIMDf_MUL(t0, t0), FUNC(GradCoord)(seed, hv0xr, hv0yr, hv0zr, d0xr, d0yr, d0zr));
SIMDf v1 = SIMDf_MUL(SIMDf_MUL(t1, t1), FUNC(GradCoord)(seed, hv1xr, hv1yr, hv1zr, d1xr, d1yr, d1zr));

val = SIMDf_MASK_ADD(n0, SIMDf_MASK_ADD(n1, val, v1), v0);

if (i == 0) {
xr = SIMDf_ADD(xr, SIMDf_NUM(32768_5));
yr = SIMDf_ADD(yr, SIMDf_NUM(32768_5));
zr = SIMDf_ADD(zr, SIMDf_NUM(32768_5));
}
}

return SIMDf_MUL(SIMDf_NUM(32), val);
}

static SIMDf VECTORCALL FUNC(CubicSingle)(SIMDi seed, SIMDf x, SIMDf y, SIMDf z)
{
SIMDf xf1 = SIMDf_FLOOR(x);
Expand Down Expand Up @@ -1376,6 +1442,9 @@ FILL_FRACTAL_SET(Perlin)
FILL_SET(Simplex)
FILL_FRACTAL_SET(Simplex)

FILL_SET(OpenSimplex2)
FILL_FRACTAL_SET(OpenSimplex2)

//FILL_SET(WhiteNoise)

FILL_SET(Cubic)
Expand Down Expand Up @@ -1491,6 +1560,9 @@ void SIMD_LEVEL_CLASS::Fill##func##FractalSet(float* noiseSet, FastNoiseVectorSe
FILL_VECTOR_SET(Simplex)
FILL_FRACTAL_VECTOR_SET(Simplex)

FILL_VECTOR_SET(OpenSimplex2)
FILL_FRACTAL_VECTOR_SET(OpenSimplex2)

FILL_VECTOR_SET(WhiteNoise)

FILL_VECTOR_SET(Cubic)
Expand Down Expand Up @@ -1765,6 +1837,12 @@ static SIMDf VECTORCALL FUNC(CellularLookup##distanceFunc##Single)(SIMDi seedV,
case FastNoiseSIMD::SimplexFractal:\
CELLULAR_LOOKUP_FRACTAL_VALUE(Simplex);\
break; \
case FastNoiseSIMD::OpenSimplex2:\
result = FUNC(OpenSimplex2Single)(seedV, xF, yF, zF); \
break;\
case FastNoiseSIMD::OpenSimplex2Fractal:\
CELLULAR_LOOKUP_FRACTAL_VALUE(OpenSimplex2);\
break; \
case FastNoiseSIMD::Cubic:\
result = FUNC(CubicSingle)(seedV, xF, yF, zF); \
break;\
Expand Down
5 changes: 5 additions & 0 deletions FastNoiseSIMD/FastNoiseSIMD_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ namespace FastNoiseSIMD_internal
void FillSimplexSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) override;
void FillSimplexFractalSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) override;

void FillOpenSimplex2Set(float* floatSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) override;
void FillOpenSimplex2FractalSet(float* floatSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) override;
void FillOpenSimplex2Set(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) override;
void FillOpenSimplex2FractalSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) override;

void FillCellularSet(float* floatSet, int xStart, int yStart, int zStart, int xSize, int ySize, int zSize, float scaleModifier = 1.0f) override;
void FillCellularSet(float* noiseSet, FastNoiseVectorSet* vectorSet, float xOffset = 0.0f, float yOffset = 0.0f, float zOffset = 0.0f) override;

Expand Down