Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added seeding, increased period, fixed bug in 2D gradient #6

Open
wants to merge 4 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
36 changes: 19 additions & 17 deletions src/SimplexNoise.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

#include "SimplexNoise.h"

#include <cstdint> // int32_t/uint8_t

/**
* Computes the largest integer value not greater than the float one
*
Expand Down Expand Up @@ -97,7 +95,11 @@ static const uint8_t perm[256] = {
* @return 8-bits hashed value
*/
static inline uint8_t hash(int32_t i) {
return perm[static_cast<uint8_t>(i)];
return perm[static_cast<uint8_t>(i)] ^ perm[static_cast<uint8_t>(i >> 8)];
}

static inline uint8_t hash(int32_t i, uint32_t seed) {
return perm[static_cast<uint8_t>(i)] ^ perm[static_cast<uint8_t>(i >> 8)] ^ static_cast<uint8_t>(seed);
}

/* NOTE Gradient table to test if lookup-table are more efficient than calculs
Expand Down Expand Up @@ -141,8 +143,8 @@ static float grad(int32_t hash, float x) {
*/
static float grad(int32_t hash, float x, float y) {
const int32_t h = hash & 0x3F; // Convert low 3 bits of hash code
const float u = h < 4 ? x : y; // into 8 simple gradient directions,
const float v = h < 4 ? y : x;
const float u = h & 4 ? x : y; // into 8 simple gradient directions,
const float v = h & 4 ? y : x;
return ((h & 1) ? -u : u) + ((h & 2) ? -2.0f * v : 2.0f * v); // and compute the dot product with (x,y).
}

Expand Down Expand Up @@ -172,7 +174,7 @@ static float grad(int32_t hash, float x, float y, float z) {
*
* @return Noise value in the range[-1; 1], value of 0 on all integer coordinates.
*/
float SimplexNoise::noise(float x) {
float SimplexNoise::noise(float x) const {
float n0, n1; // Noise contributions from the two "corners"

// No need to skew the input space in 1D
Expand All @@ -188,13 +190,13 @@ float SimplexNoise::noise(float x) {
float t0 = 1.0f - x0*x0;
// if(t0 < 0.0f) t0 = 0.0f; // not possible
t0 *= t0;
n0 = t0 * t0 * grad(hash(i0), x0);
n0 = t0 * t0 * grad(hash(i0, mSeed), x0);

// Calculate the contribution from the second corner
float t1 = 1.0f - x1*x1;
// if(t1 < 0.0f) t1 = 0.0f; // not possible
t1 *= t1;
n1 = t1 * t1 * grad(hash(i1), x1);
n1 = t1 * t1 * grad(hash(i1, mSeed), x1);

// The maximum value of this noise is 8*(3/4)^4 = 2.53125
// A factor of 0.395 scales to fit exactly within [-1,1]
Expand All @@ -211,7 +213,7 @@ float SimplexNoise::noise(float x) {
*
* @return Noise value in the range[-1; 1], value of 0 on all integer coordinates.
*/
float SimplexNoise::noise(float x, float y) {
float SimplexNoise::noise(float x, float y) const {
float n0, n1, n2; // Noise contributions from the three corners

// Skewing/Unskewing factors for 2D
Expand Down Expand Up @@ -253,9 +255,9 @@ float SimplexNoise::noise(float x, float y) {
const float y2 = y0 - 1.0f + 2.0f * G2;

// Work out the hashed gradient indices of the three simplex corners
const int gi0 = hash(i + hash(j));
const int gi1 = hash(i + i1 + hash(j + j1));
const int gi2 = hash(i + 1 + hash(j + 1));
const int gi0 = hash(i + hash(j, mSeed), mSeed >> 8);
const int gi1 = hash(i + i1 + hash(j + j1, mSeed), mSeed >> 8);
const int gi2 = hash(i + 1 + hash(j + 1, mSeed), mSeed >> 8);

// Calculate the contribution from the first corner
float t0 = 0.5f - x0*x0 - y0*y0;
Expand Down Expand Up @@ -299,7 +301,7 @@ float SimplexNoise::noise(float x, float y) {
*
* @return Noise value in the range[-1; 1], value of 0 on all integer coordinates.
*/
float SimplexNoise::noise(float x, float y, float z) {
float SimplexNoise::noise(float x, float y, float z) const {
float n0, n1, n2, n3; // Noise contributions from the four corners

// Skewing/Unskewing factors for 3D
Expand Down Expand Up @@ -356,10 +358,10 @@ float SimplexNoise::noise(float x, float y, float z) {
float z3 = z0 - 1.0f + 3.0f * G3;

// Work out the hashed gradient indices of the four simplex corners
int gi0 = hash(i + hash(j + hash(k)));
int gi1 = hash(i + i1 + hash(j + j1 + hash(k + k1)));
int gi2 = hash(i + i2 + hash(j + j2 + hash(k + k2)));
int gi3 = hash(i + 1 + hash(j + 1 + hash(k + 1)));
int gi0 = hash(i + hash(j + hash(k, mSeed), mSeed >> 8));
int gi1 = hash(i + i1 + hash(j + j1 + hash(k + k1, mSeed), mSeed >> 8));
int gi2 = hash(i + i2 + hash(j + j2 + hash(k + k2, mSeed), mSeed >> 8));
int gi3 = hash(i + 1 + hash(j + 1 + hash(k + 1, mSeed), mSeed >> 8));

// Calculate the contribution from the four corners
float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0;
Expand Down
12 changes: 8 additions & 4 deletions src/SimplexNoise.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
#pragma once

#include <cstdint> // int32_t/uint8_t
#include <cstddef> // size_t

/**
Expand All @@ -17,11 +18,11 @@
class SimplexNoise {
public:
// 1D Perlin simplex noise
static float noise(float x);
float noise(float x) const;
// 2D Perlin simplex noise
static float noise(float x, float y);
float noise(float x, float y) const;
// 3D Perlin simplex noise
static float noise(float x, float y, float z);
float noise(float x, float y, float z) const;

// Fractal/Fractional Brownian Motion (fBm) noise summation
float fractal(size_t octaves, float x) const;
Expand All @@ -36,10 +37,12 @@ class SimplexNoise {
* @param[in] lacunarity Lacunarity specifies the frequency multiplier between successive octaves (default to 2.0).
* @param[in] persistence Persistence is the loss of amplitude between successive octaves (usually 1/lacunarity)
*/
explicit SimplexNoise(float frequency = 1.0f,
explicit SimplexNoise(uint32_t seed = 0,
float frequency = 1.0f,
float amplitude = 1.0f,
float lacunarity = 2.0f,
float persistence = 0.5f) :
mSeed(seed),
mFrequency(frequency),
mAmplitude(amplitude),
mLacunarity(lacunarity),
Expand All @@ -48,6 +51,7 @@ class SimplexNoise {

private:
// Parameters of Fractional Brownian Motion (fBm) : sum of N "octaves" of noise
uint32_t mSeed;
float mFrequency; ///< Frequency ("width") of the first octave of noise (default to 1.0)
float mAmplitude; ///< Amplitude ("height") of the first octave of noise (default to 1.0)
float mLacunarity; ///< Lacunarity specifies the frequency multiplier between successive octaves (default to 2.0).
Expand Down
2 changes: 1 addition & 1 deletion test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

int main() {
float x = 0.123f; // Define a float coordinate
float noise = SimplexNoise::noise(x); // Get the noise value for the coordinate
float noise = SimplexNoise().noise(x); // Get the noise value for the coordinate
(void)noise;

return 0;
Expand Down