19 #include <smmintrin.h>
28 inline double floorSSE(
double val) {
return _mm_cvtsd_f64(_mm_floor_sd(_mm_set_sd(0.0), _mm_set_sd(val))); }
31 return _mm_cvtsd_f64(_mm_round_sd(_mm_set_sd(0.0), _mm_set_sd(val), _MM_FROUND_TO_NEAREST_INT));
35 double s_curve(
double t) {
return t * t * t * (t * (6 * t - 15) + 10); }
42 for (
int k = 0; k < d; k++) {
43 static const uint32_t M = 1664525, C = 1013904223;
44 seed = seed * M +
index[k] + C;
48 seed ^= (seed << 7) & 0x9d2c5680UL;
49 seed ^= (seed << 15) & 0xefc60000UL;
52 return (((seed & 0xff0000) >> 4) + (seed & 0xff)) & 0xff;
64 for (
int k = 0; k < d; k++) {
65 static const uint32_t M = 1664525, C = 1013904223;
66 u1.i = u1.i * M +
index[k] + C;
70 u1.i ^= (u1.i << 7) & 0x9d2c5680U;
71 u1.i ^= (u1.i << 15) & 0xefc60000U;
75 u2.c[2] =
p[u1.c[1] + u2.c[3]];
76 u2.c[1] =
p[u1.c[2] + u2.c[2]];
77 u2.c[0] =
p[u1.c[3] + u2.c[1]];
83 template <
int d,
class T,
bool periodic>
88 for (
int k = 0; k < d; k++) {
92 index[k] %= period[k];
93 if (index[k] < 0) index[k] += period[k];
95 weights[0][k] = X[k] -
f;
96 weights[1][k] = weights[0][k] - 1;
101 for (
int dummy = 0; dummy < num; dummy++) {
104 for (
int k = 0; k < d; k++) {
105 offset[k] = ((dummy & (1 << k)) != 0);
106 latticeIndex[k] = index[k] + offset[k];
109 int lookup = hashReduceChar<d>(latticeIndex);
111 for (
int k = 0; k < d; k++) {
112 double grad = NOISE_TABLES<d>::g[lookup][k];
113 double weight = weights[offset[k]][k];
114 val += grad * weight;
120 for (
int k = 0; k < d; k++) alphas[k] =
s_curve(weights[0][k]);
122 for (
int newd = d - 1; newd >= 0; newd--) {
123 int newnum = 1 << newd;
124 int k = (d - newd - 1);
126 T beta = T(1) - alphas[k];
127 for (
int dummy = 0; dummy < newnum; dummy++) {
128 int index = dummy * (1 << (d - newd));
129 int otherIndex = index + (1 << k);
131 vals[
index] = beta * vals[
index] + alpha * vals[otherIndex];
142 template <
int d_in,
int d_out,
class T>
144 uint32_t
index[d_in];
146 for (
int k = 0; k < d_in; k++) index[k] = uint32_t(
floorSSE(in[k]));
148 out[dim] = hashReduce<d_in>(
index) * (1.0 / 0xffffffffu);
149 if (++dim >= d_out)
break;
150 for (
int k = 0; k < d_in; k++) index[k] += 1000;
155 template <
int d_in,
int d_out,
class T>
158 for (
int i = 0; i < d_in; i++) P[i] = in[i];
162 out[i] = noiseHelper<d_in, T, false>(P);
163 if (++i >= d_out)
break;
164 for (
int k = 0; k < d_out; k++) P[k] += (T)1000;
169 template <
int d_in,
int d_out,
class T>
170 void PNoise(
const T* in,
const int* period, T* out) {
172 for (
int i = 0; i < d_in; i++) P[i] = in[i];
176 out[i] = noiseHelper<d_in, T, true>(P, period);
177 if (++i >= d_out)
break;
178 for (
int k = 0; k < d_out; k++) P[k] += (T)1000;
184 template <
int d_in,
int d_out,
bool turbulence,
class T>
185 void FBM(
const T* in, T* out,
int octaves, T lacunarity, T gain) {
187 for (
int i = 0; i < d_in; i++) P[i] = in[i];
190 for (
int k = 0; k < d_out; k++) out[k] = 0;
193 T localResult[d_out];
194 Noise<d_in, d_out>(P, localResult);
196 for (
int k = 0; k < d_out; k++) out[k] += fabs(localResult[k]) * scale;
198 for (
int k = 0; k < d_out; k++) out[k] += localResult[k] * scale;
199 if (++octave >= octaves)
break;
201 for (
int k = 0; k < d_in; k++) {
227 int main(
int argc,
char* argv[]) {
230 for (
int i = 0; i < 10000000; i++) {
231 T foo[3] = {.3, .3, .3};
233 sum += SeExpr2::noiseHelper<3, T, false>(foo);
template void FBM< 4, 1, false, double >(const double *, double *, int, double, double)
T noiseHelper(const T *X, const int *period=0)
Noise with d_in dimensional domain, 1 dimensional abcissa.
double s_curve(double t)
This is the Quintic interpolant from Perlin's Improved Noise Paper.
unsigned char hashReduceChar(int index[d])
Does a hash reduce to a character.
double floorSSE(double val)
template void FBM< 3, 1, false, double >(const double *, double *, int, double, double)
with numParticles numAttributes A variable block contains variable names and types but doesn t care what the values are< pre > void f(const std::string &s, MyParticleData *p, int outputDim=3)
template void Noise< 3, 3, double >(const double *, double *)
void CellNoise(const T *in, T *out)
Computes cellular noise (non-interpolated piecewise constant cell random values)
template void PNoise< 3, 1, double >(const double *, const int *, double *)
double roundSSE(double val)
void PNoise(const T *in, const int *period, T *out)
Periodic Noise with d_in dimensional domain, d_out dimensional abcissa.
template void FBM< 3, 1, true, double >(const double *, double *, int, double, double)
template void CellNoise< 3, 1, double >(const double *, double *)
The result is computed int int< br >< divstyle="margin-left:40px;"> Picks values randomly between loRange and hiRange based on supplied index(which is automatically hashed). 
template void FBM< 3, 3, true, double >(const double *, double *, int, double, double)
template void Noise< 4, 1, double >(const double *, double *)
template void FBM< 3, 3, false, double >(const double *, double *, int, double, double)
void FBM(const T *in, T *out, int octaves, T lacunarity, T gain)
Fractional Brownian Motion. If turbulence is true then turbulence computed.
uint32_t hashReduce(uint32_t index[d])
Does a hash reduce to an integer.
void Noise(const T *in, T *out)
Noise with d_in dimensional domain, d_out dimensional abcissa.
double turbulence(int n, const Vec3d *args)
template void Noise< 2, 1, double >(const double *, double *)
template void CellNoise< 3, 3, double >(const double *, double *)
template void Noise< 1, 1, double >(const double *, double *)
int main(int argc, char *argv[])
template void FBM< 4, 3, false, double >(const double *, double *, int, double, double)
template void Noise< 4, 3, double >(const double *, double *)
template void Noise< 3, 1, double >(const double *, double *)