#define SimplexNoise SimplexNoise2 //#define valarray vector #include "SimplexNoise.h" // #include "Array2D.h" #include #include #include // #ifdef _DEBUG // #include // #include "FRC.h" // #endif using namespace std; inline float radial_attenuation(float[8][3], float*, int); inline constexpr int myfloor(float); SimplexNoise::SimplexNoise(unsigned Octaves, float Gain, float Lacunarity, float Frequency, float Amplitude) { max_octaves = Octaves; gain = Gain; lacunarity = Lacunarity; start_amplitude = Amplitude; start_frequency = Frequency; // set up the permutation table unsigned i, j, k; for (i = 0; i < 256; ++i) permutation_table[i] = i; // #ifdef _DEBUG // padList(cout, permutation_table, permutation_table+256)<& height_map, int z){ unsigned x,y,octave; float amplitude, frequency, final_val; //for each pixel... for (x=0;x> SimplexNoise::genNoise(const vector& xgrid, const vector& ygrid, float z) { unsigned x, y, octave; float amplitude, frequency, final_val; // Normalization bias (Range: ~0-~255 for image use) const float mBias = 1.280, aBias = 137.f; vector> height_map(xgrid.size(), vector(ygrid.size(), 0.f)); // for each pixel... for (x = 0; x < xgrid.size(); ++x) { for (y = 0; y < ygrid.size(); ++y) { frequency = start_frequency; amplitude = start_amplitude; final_val = 0.0f; // for each octave... for (octave = 0; octave < max_octaves; ++octave) { final_val += amplitude * make_point(frequency * xgrid[x], frequency * ygrid[y], frequency * z); frequency *= lacunarity; amplitude *= gain; } height_map[x][y] = final_val * mBias + aBias; } } return height_map; } float SimplexNoise::make_point(float x, float y, float z) { int corners[4][3]; // 4 corners, each with an x,y, and z coordinate. Note: // only corners[0] contains original values; the other // three are offset values from corners[0]. float distances[4][3]; // the distances to each of the four corners int i, j; // first, get the bottom corner in skewed space constexpr float general_skew = 1.0f / 3.0f; // very nice general skew/unskew values in 3D float specific_skew = (x * general_skew + y * general_skew + z * general_skew); corners[0][0] = myfloor(x + specific_skew); corners[0][1] = myfloor(y + specific_skew); corners[0][2] = myfloor(z + specific_skew); // next, get the distance vectors to the bottom corner constexpr float general_unskew = 1.0f / 6.0f; float specific_unskew = corners[0][0] * general_unskew + corners[0][1] * general_unskew + corners[0][2] * general_unskew; distances[0][0] = x - corners[0][0] + specific_unskew; distances[0][1] = y - corners[0][1] + specific_unskew; distances[0][2] = z - corners[0][2] + specific_unskew; // find the coordinates for the two middle corners if (distances[0][0] < distances[0][1]) { // y > x if (distances[0][1] < distances[0][2]) { // if z > y > x corners[1][0] = 0; corners[1][1] = 0; corners[1][2] = 1; corners[2][0] = 0; corners[2][1] = 1; corners[2][2] = 1; } else if (distances[0][0] < distances[0][2]) { // if y > z > x corners[1][0] = 0; corners[1][1] = 1; corners[1][2] = 0; corners[2][0] = 0; corners[2][1] = 1; corners[2][2] = 1; } else { // y > x > z corners[1][0] = 0; corners[1][1] = 1; corners[1][2] = 0; corners[2][0] = 1; corners[2][1] = 1; corners[2][2] = 0; } } else { // x > y if (distances[0][0] < distances[0][2]) { // z > x > y corners[1][0] = 0; corners[1][1] = 0; corners[1][2] = 1; corners[2][0] = 1; corners[2][1] = 0; corners[2][2] = 1; } else if (distances[0][1] < distances[0][2]) { // x > z > y corners[1][0] = 1; corners[1][1] = 0; corners[1][2] = 0; corners[2][0] = 1; corners[2][1] = 0; corners[2][2] = 1; } else { // x > y > z corners[1][0] = 1; corners[1][1] = 0; corners[1][2] = 0; corners[2][0] = 1; corners[2][1] = 1; corners[2][2] = 0; } } // get the top corner corners[3][0] = 1; corners[3][1] = 1; corners[3][2] = 1; // get the distances for (i = 1; i <= 3; ++i) { for (j = 0; j < 3; ++j) { distances[i][j] = distances[0][j] - corners[i][j] + general_unskew * i; } } // get the gradients indices int gradient_index[4]; gradient_index[0] = permutation_table [(corners[0][0] + permutation_table[(corners[0][1] + permutation_table[corners[0][2] & 255]) & 255]) & 255] & 7; for (i = 1; i < 4; ++i) gradient_index[i] = 7 & permutation_table [0xFF & (corners[0][0] + corners[i][0] + permutation_table [0xFF & (corners[0][1] + corners[i][1] + permutation_table[0xFF & (corners[0][2] + corners[i][2])])])]; // sum the contributions from each corner, found using radial attenuation float final_sum = 0.0f; for (i = 0; i < 4; ++i) { final_sum += radial_attenuation(gradient_table, distances[i], gradient_index[i]); } return (32.0f * final_sum); }*/ float radial_attenuation(float gradient_table[8][3], float* distances, int gradient_index) { float test_product = 0.6f - distances[0] * distances[0] - distances[1] * distances[1] - distances[2] * distances[2]; if (test_product < 0.0f) return (0.0f); float dot_product = distances[0] * gradient_table[gradient_index][0] + distances[1] * gradient_table[gradient_index][1] + distances[2] * gradient_table[gradient_index][2]; test_product *= test_product; // square it return (test_product * test_product * dot_product); } inline constexpr int myfloor(float value) { return (value >= 0 ? (int)value : (int)value - 1); }