float Noise::Turb(Point3 p, float lev) { float sum = 0.0f; float l,f = 1.0f; float ml = levels; for (l = lev; l >= 1.0f; l-=1.0f, ml-=1.0f) { sum += (float)fabs(noise4(p*f,phase))/f; f *= 2.0f; } if (l>0.0f) sum += l*(float)fabs(noise4(p*f,phase))/f; #ifdef DOAA if (filter&&(ml>l)) { float r = 0; if (ml<1.0f) { r += (ml-l)/f; } else { r += (1.0f-l)/f; ml -= 1.0f; f *= 2.0f; for (l = ml; l >=1.0f; l-=1.0f) { r += 1.0f/f; f *= 2.0f; } if (l>0.0f) r+= l/f; sum += r*avgAbsNs; } } #endif return sum; }
static PyObject * py_noise4(PyObject *self, PyObject *args, PyObject *kwargs) { float x, y, z, w; int octaves = 1; float persistence = 0.5f; float lacunarity = 2.0f; static char *kwlist[] = {"x", "y", "z", "w", "octaves", "persistence", "lacunarity", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ffff|iff:snoise4", kwlist, &x, &y, &z, &w, &octaves, &persistence)) return NULL; if (octaves == 1) { // Single octave, return simple noise return (PyObject *) PyFloat_FromDouble((double) noise4(x, y, z, w)); } else if (octaves > 1) { return (PyObject *) PyFloat_FromDouble( (double) fbm_noise4(x, y, z, w, octaves, persistence, lacunarity)); } else { PyErr_SetString(PyExc_ValueError, "Expected octaves value > 0"); return NULL; } }
inline float fbm_noise4(float x, float y, float z, float w, int octaves, float persistence, float lacunarity) { float freq = 1.0f; float amp = 1.0f; float max = 1.0f; float total = noise4(x, y, z, w); int i; for (i = 1; i < octaves; ++i) { freq *= lacunarity; amp *= persistence; max += amp; total += noise4(x * freq, y * freq, z * freq, w * freq) * amp; } return total / max; }
void Noise::ComputeAvgValue() { #ifdef DOAA srand(1345); Point3 p; int i; float sum = 0.0f; filter = FALSE; for (i=0; i<NAVG; i++) { p.x = float(rand())/100.0f; p.y = float(rand())/100.0f; p.z = float(rand())/100.0f; sum += NoiseFunction(p,levels,0.0f); } avgValue = sum/float(NAVG); sum = 0.0f; if (avgAbsNs<0.0f) { #define NAVGNS 10000 float phase; for (i=0; i<NAVGNS; i++) { p.x = float(rand())/100.0f; p.y = float(rand())/100.0f; p.z = float(rand())/100.0f; phase = float(rand())/100.0f; sum += (float)fabs(noise4(p,phase)); } avgAbsNs = sum/float(NAVGNS); } #endif }
float Noise::NoiseFunction(Point3 p, float limitLev, float smWidth) { float res(0.0f); float lev = limitLev; if (limitLev<(1.0f-BLENDBAND)) return avgValue; if (lev<1.0f) lev = 1.0f; switch (noiseType) { case NOISE_TURB: res = Turb(p,lev); break; case NOISE_REGULAR: res = NOISE01(p); break; case NOISE_FRACTAL: { float sum = 0.0f; float l, f = 1.0f; for (l = lev; l >= 1.0f; l-=1.0f) { sum += noise4(p*f,phase)/f; f *= 2.0f; } if (l>0.0f) sum += l*noise4(p*f,phase)/f; res = 0.5f*(sum+1.0f); } break; } if (low<high) { //res = threshold(res,low,high); res = filter? SmoothThresh(res,low,high, smWidth): threshold(res,low,high); } if (res<0.0f) res = 0.0f; else if (res>1.0f) res = 1.0f; if (filter) { if (limitLev<1.0f) { float u = (limitLev+BLENDBAND-1.0f)/BLENDBAND; res = u*res + (1.0f-u)*avgValue; } } return res; }