Skip to content

Commit

Permalink
OpenSimplex2S Conditional-related optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
KdotJPG committed Sep 11, 2020
1 parent 9e1b3f8 commit 5620641
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 153 deletions.
137 changes: 95 additions & 42 deletions C/FastNoiseLite.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// MIT License
// MIT Licens
//
// Copyright(c) 2020 Jordan Peck ([email protected])
//
Expand Down Expand Up @@ -1102,42 +1102,103 @@ static float _fnlSingleOpenSimplex2S2D(int seed, FNLfloat x, FNLfloat y)
int bMask = (int)((xi - (aMask + 2)) * 0.5f - yi);
int cMask = (int)((yi - (aMask + 2)) * 0.5f - xi);

float value = 0;

float a0 = (2.0f / 3.0f) - x0 * x0 - y0 * y0;
if (a0 > 0)
{
value += (a0 * a0) * (a0 * a0) * _fnlGradCoord2D(seed, i, j, x0, y0);
}
float value = (a0 * a0) * (a0 * a0) * _fnlGradCoord2D(seed, i, j, x0, y0);

float a1 = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
if (a1 > 0)
{
float x1 = x0 - (float)(1 - 2 * G2);
float y1 = y0 - (float)(1 - 2 * G2);
value += (a1 * a1) * (a1 * a1) * _fnlGradCoord2D(seed, i1, j1, x1, y1);
}
float x1 = x0 - (float)(1 - 2 * G2);
float y1 = y0 - (float)(1 - 2 * G2);
value += (a1 * a1) * (a1 * a1) * _fnlGradCoord2D(seed, i1, j1, x1, y1);

int di2 = ~(aMask | cMask) | 1;
int ndj2 = (aMask & bMask) << 1;
float t2 = (di2 - ndj2) * (float)G2;
float x2 = x0 - di2 + t2;
float y2 = y0 + ndj2 + t2;
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
// Nested conditionals were faster than compact bit logic/arithmetic.
float xmyi = xi - yi;
if (t > G2)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i1 + (di2 & (-PRIME_X << 1)), j + (ndj2 & (PRIME_Y << 1)), x2, y2);
}
if (xi + xmyi > 1)
{
float x2 = x0 + (float)(3 * G2 - 2);
float y2 = y0 + (float)(3 * G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i + (PRIME_X << 1), j + PRIME_Y, x2, y2);
}
}
else
{
float x2 = x0 + (float)G2;
float y2 = y0 + (float)(G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i, j + PRIME_Y, x2, y2);
}
}

int ndi3 = (aMask & cMask) << 1;
int dj3 = ~(aMask | bMask) | 1;
float t3 = (dj3 - ndi3) * (float)G2;
float x3 = x0 + ndi3 + t3;
float y3 = y0 - dj3 + t3;
float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
if (a3 > 0)
if (yi - xmyi > 1)
{
float x3 = x0 + (float)(3 * G2 - 1);
float y3 = y0 + (float)(3 * G2 - 2);
float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
if (a3 > 0)
{
value += (a3 * a3) * (a3 * a3) * _fnlGradCoord2D(seed, i + PRIME_X, j + (PRIME_Y << 1), x3, y3);
}
}
else
{
float x3 = x0 + (float)(G2 - 1);
float y3 = y0 + (float)G2;
float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
if (a3 > 0)
{
value += (a3 * a3) * (a3 * a3) * _fnlGradCoord2D(seed, i + PRIME_X, j, x3, y3);
}
}
}
else
{
value += (a3 * a3) * (a3 * a3) * _fnlGradCoord2D(seed, i + (ndi3 & (PRIME_X << 1)), j1 + (dj3 & (-PRIME_Y << 1)), x3, y3);
if (xi + xmyi < 0)
{
float x2 = x0 + (float)(1 - G2);
float y2 = y0 - (float)G2;
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i - PRIME_X, j, x2, y2);
}
}
else
{
float x2 = x0 + (float)(G2 - 1);
float y2 = y0 + (float)G2;
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i + PRIME_X, j, x2, y2);
}
}

if (yi < xmyi)
{
float x2 = x0 - (float)G2;
float y2 = y0 - (float)(G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i, j - PRIME_Y, x2, y2);
}
}
else
{
float x2 = x0 + (float)G2;
float y2 = y0 + (float)(G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * _fnlGradCoord2D(seed, i, j + PRIME_Y, x2, y2);
}
}
}

return value * 18.24196194486065f;
Expand Down Expand Up @@ -1170,27 +1231,19 @@ static float _fnlSingleOpenSimplex2S3D(int seed, FNLfloat x, FNLfloat y, FNLfloa
int yNMask = (int)(-0.5f - yi);
int zNMask = (int)(-0.5f - zi);

float value = 0;

float x0 = xi + xNMask;
float y0 = yi + yNMask;
float z0 = zi + zNMask;
float a0 = 0.75f - x0 * x0 - y0 * y0 - z0 * z0;
if (a0 > 0)
{
value += (a0 * a0) * (a0 * a0) * _fnlGradCoord3D(seed,
i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x0, y0, z0);
}
float value = (a0 * a0) * (a0 * a0) * _fnlGradCoord3D(seed,
i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x0, y0, z0);

float x1 = xi - 0.5f;
float y1 = yi - 0.5f;
float z1 = zi - 0.5f;
float a1 = 0.75f - x1 * x1 - y1 * y1 - z1 * z1;
if (a1 > 0)
{
value += (a1 * a1) * (a1 * a1) * _fnlGradCoord3D(seed2,
i + PRIME_X, j + PRIME_Y, k + PRIME_Z, x1, y1, z1);
}
value += (a1 * a1) * (a1 * a1) * _fnlGradCoord3D(seed2,
i + PRIME_X, j + PRIME_Y, k + PRIME_Z, x1, y1, z1);

float xAFlipMask0 = ((xNMask | 1) << 1) * x1;
float yAFlipMask0 = ((yNMask | 1) << 1) * y1;
Expand Down
141 changes: 95 additions & 46 deletions CSharp/FastNoiseLite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1263,51 +1263,108 @@ private float SingleOpenSimplex2S(int seed, FNLfloat x, FNLfloat y)
float x0 = xi - t;
float y0 = yi - t;

int aMask = (int)((xi + yi + 1) * -0.5f);
int bMask = (int)((xi - (aMask + 2)) * 0.5f - yi);
int cMask = (int)((yi - (aMask + 2)) * 0.5f - xi);

float value = 0;

float a0 = (2.0f / 3.0f) - x0 * x0 - y0 * y0;
if (a0 > 0)
{
value += (a0 * a0) * (a0 * a0) * GradCoord(seed, i, j, x0, y0);
}
float value = (a0 * a0) * (a0 * a0) * GradCoord(seed, i, j, x0, y0);

float a1 = (float)(2 * (1 - 2 * G2) * (1 / G2 - 2)) * t + ((float)(-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
if (a1 > 0)
{
float x1 = x0 - (float)(1 - 2 * G2);
float y1 = y0 - (float)(1 - 2 * G2);
value += (a1 * a1) * (a1 * a1) * GradCoord(seed, i1, j1, x1, y1);
}
float x1 = x0 - (float)(1 - 2 * G2);
float y1 = y0 - (float)(1 - 2 * G2);
value += (a1 * a1) * (a1 * a1) * GradCoord(seed, i1, j1, x1, y1);

int di2 = ~(aMask | cMask) | 1;
int ndj2 = (aMask & bMask) << 1;
float t2 = (di2 - ndj2) * (float)G2;
float x2 = x0 - di2 + t2;
float y2 = y0 + ndj2 + t2;
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
// Nested conditionals were faster than compact bit logic/arithmetic.
float xmyi = xi - yi;
if (t > G2)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i1 + (di2 & (-PrimeX << 1)), j + (ndj2 & (PrimeY << 1)), x2, y2);
}
if (xi + xmyi > 1)
{
float x2 = x0 + (float)(3 * G2 - 2);
float y2 = y0 + (float)(3 * G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + (PrimeX << 1), j + PrimeY, x2, y2);
}
}
else
{
float x2 = x0 + (float)G2;
float y2 = y0 + (float)(G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2);
}
}

int ndi3 = (aMask & cMask) << 1;
int dj3 = ~(aMask | bMask) | 1;
float t3 = (dj3 - ndi3) * (float)G2;
float x3 = x0 + ndi3 + t3;
float y3 = y0 - dj3 + t3;
float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
if (a3 > 0)
if (yi - xmyi > 1)
{
float x3 = x0 + (float)(3 * G2 - 1);
float y3 = y0 + (float)(3 * G2 - 2);
float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
if (a3 > 0)
{
value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j + (PrimeY << 1), x3, y3);
}
}
else
{
float x3 = x0 + (float)(G2 - 1);
float y3 = y0 + (float)G2;
float a3 = (2.0f / 3.0f) - x3 * x3 - y3 * y3;
if (a3 > 0)
{
value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + PrimeX, j, x3, y3);
}
}
}
else
{
value += (a3 * a3) * (a3 * a3) * GradCoord(seed, i + (ndi3 & (PrimeX << 1)), j1 + (dj3 & (-PrimeY << 1)), x3, y3);
if (xi + xmyi < 0)
{
float x2 = x0 + (float)(1 - G2);
float y2 = y0 - (float)G2;
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i - PrimeX, j, x2, y2);
}
}
else
{
float x2 = x0 + (float)(G2 - 1);
float y2 = y0 + (float)G2;
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i + PrimeX, j, x2, y2);
}
}

if (yi < xmyi)
{
float x2 = x0 - (float)G2;
float y2 = y0 - (float)(G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j - PrimeY, x2, y2);
}
}
else
{
float x2 = x0 + (float)G2;
float y2 = y0 + (float)(G2 - 1);
float a2 = (2.0f / 3.0f) - x2 * x2 - y2 * y2;
if (a2 > 0)
{
value += (a2 * a2) * (a2 * a2) * GradCoord(seed, i, j + PrimeY, x2, y2);
}
}
}

return value * 18.24196194486065f;
}

private float SingleOpenSimplex2S(int seed, FNLfloat x, FNLfloat y, FNLfloat z)
{
// 3D OpenSimplex2S case uses two offset rotated cube grids.
Expand Down Expand Up @@ -1335,27 +1392,19 @@ private float SingleOpenSimplex2S(int seed, FNLfloat x, FNLfloat y, FNLfloat z)
int yNMask = (int)(-0.5f - yi);
int zNMask = (int)(-0.5f - zi);

float value = 0;

float x0 = xi + xNMask;
float y0 = yi + yNMask;
float z0 = zi + zNMask;
float a0 = 0.75f - x0 * x0 - y0 * y0 - z0 * z0;
if (a0 > 0)
{
value += (a0 * a0) * (a0 * a0) * GradCoord(seed,
i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x0, y0, z0);
}
float value = (a0 * a0) * (a0 * a0) * GradCoord(seed,
i + (xNMask & PrimeX), j + (yNMask & PrimeY), k + (zNMask & PrimeZ), x0, y0, z0);

float x1 = xi - 0.5f;
float y1 = yi - 0.5f;
float z1 = zi - 0.5f;
float a1 = 0.75f - x1 * x1 - y1 * y1 - z1 * z1;
if (a1 > 0)
{
value += (a1 * a1) * (a1 * a1) * GradCoord(seed2,
i + PrimeX, j + PrimeY, k + PrimeZ, x1, y1, z1);
}
value += (a1 * a1) * (a1 * a1) * GradCoord(seed2,
i + PrimeX, j + PrimeY, k + PrimeZ, x1, y1, z1);

float xAFlipMask0 = ((xNMask | 1) << 1) * x1;
float yAFlipMask0 = ((yNMask | 1) << 1) * y1;
Expand Down
Loading

0 comments on commit 5620641

Please sign in to comment.