/// <summary> /// Get the noise function at a given position specified by f /// </summary> /// <param name="f">A position in space (dimension 1-4)</param> /// <returns>Amplitude of noise from this pass at the given location.</returns> public float GetNoise(float[] f) { int[] n = new int[MaxDimensions]; // Indexes to pass to lattice function float[] r = new float[MaxDimensions]; // Remainders to pass to lattice function float[] w = new float[MaxDimensions]; // Cubic values to pass to interpolation function for (int i = 0; i < m_nDimensions; i++) { n[i] = (int)Math.Floor(f[i]); r[i] = f[i] - n[i]; w[i] = NoiseHelper.Cubic(r[i]); } float fValue; switch (m_nDimensions) { case 1: fValue = Lerp(Lattice(n[0], r[0]), Lattice(n[0] + 1, r[0] - 1), w[0]); break; case 2: fValue = Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1]), Lattice(n[0] + 1, r[0] - 1, n[1], r[1]), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1), w[0]), w[1]); break; case 3: fValue = Lerp(Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2], r[2]), Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2], r[2]), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2], r[2]), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2], r[2]), w[0]), w[1]), Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2] + 1, r[2] - 1), Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2] + 1, r[2] - 1), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1), w[0]), w[1]), w[2]); break; case 4: fValue = Lerp(Lerp(Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2], r[2], n[3], r[3]), Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2], r[2], n[3], r[3]), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2], r[2], n[3], r[3]), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2], r[2], n[3], r[3]), w[0]), w[1]), Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2] + 1, r[2] - 1, n[3], r[3]), Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2] + 1, r[2] - 1, n[3], r[3]), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1, n[3], r[3]), w[0]), w[1]), w[2]), Lerp(Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2], r[2], n[3] + 1, r[3] - 1), Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2], r[2], n[3] + 1, r[3] - 1), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2], r[2], n[3] + 1, r[3] - 1), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2], r[2], n[3] + 1, r[3] - 1), w[0]), w[1]), Lerp(Lerp(Lattice(n[0], r[0], n[1], r[1], n[2] + 1, r[2] - 1, n[3] + 1, r[3] - 1), Lattice(n[0] + 1, r[0] - 1, n[1], r[1], n[2] + 1, r[2] - 1, n[3] + 1, r[3] - 1), w[0]), Lerp(Lattice(n[0], r[0], n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1), Lattice(n[0] + 1, r[0] - 1, n[1] + 1, r[1] - 1, n[2] + 1, r[2] - 1, n[3] + 1, r[3] - 1), w[0]), w[1]), w[2]), w[3]); break; default: throw new Exception("Invalid value for dimension"); } return(NoiseHelper.Clamp(-0.99999f, 0.99999f, fValue)); }
private static float Lerp(float a, float b, float x) { return(NoiseHelper.Lerp(a, b, x)); }