├── FastNoise.java ├── LICENSE └── README.md /FastNoise.java: -------------------------------------------------------------------------------- 1 | // FastNoise.java 2 | // 3 | // MIT License 4 | // 5 | // Copyright(c) 2017 Jordan Peck 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files(the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions : 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | // The developer's email is jorzixdan.me2@gzixmail.com (for great email, take 26 | // off every 'zix'.) 27 | // 28 | 29 | package fastnoise; 30 | 31 | import javax.vecmath.Vector2f; 32 | import javax.vecmath.Vector3f; 33 | 34 | public class FastNoise { 35 | public enum NoiseType {Value, ValueFractal, Perlin, PerlinFractal, Simplex, SimplexFractal, Cellular, WhiteNoise, Cubic, CubicFractal} 36 | public enum Interp {Linear, Hermite, Quintic} 37 | public enum FractalType {FBM, Billow, RigidMulti} 38 | public enum CellularDistanceFunction {Euclidean, Manhattan, Natural} 39 | public enum CellularReturnType {CellValue, NoiseLookup, Distance, Distance2, Distance2Add, Distance2Sub, Distance2Mul, Distance2Div} 40 | 41 | private int m_seed = 1337; 42 | private float m_frequency = (float) 0.01; 43 | private Interp m_interp = Interp.Quintic; 44 | private NoiseType m_noiseType = NoiseType.Simplex; 45 | 46 | private int m_octaves = 3; 47 | private float m_lacunarity = (float) 2.0; 48 | private float m_gain = (float) 0.5; 49 | private FractalType m_fractalType = FractalType.FBM; 50 | 51 | private float m_fractalBounding; 52 | 53 | private CellularDistanceFunction m_cellularDistanceFunction = CellularDistanceFunction.Euclidean; 54 | private CellularReturnType m_cellularReturnType = CellularReturnType.CellValue; 55 | private FastNoise m_cellularNoiseLookup = null; 56 | 57 | private float m_gradientPerturbAmp = (float) (1.0 / 0.45); 58 | 59 | public FastNoise() { 60 | this(1337); 61 | } 62 | 63 | public FastNoise(int seed) { 64 | m_seed = seed; 65 | CalculateFractalBounding(); 66 | } 67 | 68 | // Returns a 0 float/double 69 | public static float GetDecimalType() { 70 | return 0; 71 | } 72 | 73 | // Returns the seed used by this object 74 | public int GetSeed() { 75 | return m_seed; 76 | } 77 | 78 | // Sets seed used for all noise types 79 | // Default: 1337 80 | public void SetSeed(int seed) { 81 | m_seed = seed; 82 | } 83 | 84 | // Sets frequency for all noise types 85 | // Default: 0.01 86 | public void SetFrequency(float frequency) { 87 | m_frequency = frequency; 88 | } 89 | 90 | // Changes the interpolation method used to smooth between noise values 91 | // Possible interpolation methods (lowest to highest quality) : 92 | // - Linear 93 | // - Hermite 94 | // - Quintic 95 | // Used in Value, Gradient Noise and Position Perturbing 96 | // Default: Quintic 97 | public void SetInterp(Interp interp) { 98 | m_interp = interp; 99 | } 100 | 101 | // Sets noise return type of GetNoise(...) 102 | // Default: Simplex 103 | public void SetNoiseType(NoiseType noiseType) { 104 | m_noiseType = noiseType; 105 | } 106 | 107 | // Sets octave count for all fractal noise types 108 | // Default: 3 109 | public void SetFractalOctaves(int octaves) { 110 | m_octaves = octaves; 111 | CalculateFractalBounding(); 112 | } 113 | 114 | // Sets octave lacunarity for all fractal noise types 115 | // Default: 2.0 116 | public void SetFractalLacunarity(float lacunarity) { 117 | m_lacunarity = lacunarity; 118 | } 119 | 120 | // Sets octave gain for all fractal noise types 121 | // Default: 0.5 122 | public void SetFractalGain(float gain) { 123 | m_gain = gain; 124 | CalculateFractalBounding(); 125 | } 126 | 127 | // Sets method for combining octaves in all fractal noise types 128 | // Default: FBM 129 | public void SetFractalType(FractalType fractalType) { 130 | m_fractalType = fractalType; 131 | } 132 | 133 | // Sets return type from cellular noise calculations 134 | // Note: NoiseLookup requires another FastNoise object be set with SetCellularNoiseLookup() to function 135 | // Default: CellValue 136 | public void SetCellularDistanceFunction(CellularDistanceFunction cellularDistanceFunction) { 137 | m_cellularDistanceFunction = cellularDistanceFunction; 138 | } 139 | 140 | // Sets distance function used in cellular noise calculations 141 | // Default: Euclidean 142 | public void SetCellularReturnType(CellularReturnType cellularReturnType) { 143 | m_cellularReturnType = cellularReturnType; 144 | } 145 | 146 | // Noise used to calculate a cell value if cellular return type is NoiseLookup 147 | // The lookup value is acquired through GetNoise() so ensure you SetNoiseType() on the noise lookup, value, gradient or simplex is recommended 148 | public void SetCellularNoiseLookup(FastNoise noise) { 149 | m_cellularNoiseLookup = noise; 150 | } 151 | 152 | // Sets the maximum perturb distance from original location when using GradientPerturb{Fractal}(...) 153 | // Default: 1.0 154 | public void SetGradientPerturbAmp(float gradientPerturbAmp) { 155 | m_gradientPerturbAmp = gradientPerturbAmp / (float) 0.45; 156 | } 157 | 158 | private static class Float2 { 159 | public final float x, y; 160 | 161 | public Float2(float x, float y) { 162 | this.x = x; 163 | this.y = y; 164 | } 165 | } 166 | 167 | private static class Float3 { 168 | public final float x, y, z; 169 | 170 | public Float3(float x, float y, float z) { 171 | this.x = x; 172 | this.y = y; 173 | this.z = z; 174 | } 175 | } 176 | 177 | private static final Float2[] GRAD_2D = { 178 | new Float2(-1, -1), new Float2(1, -1), new Float2(-1, 1), new Float2(1, 1), 179 | new Float2(0, -1), new Float2(-1, 0), new Float2(0, 1), new Float2(1, 0), 180 | }; 181 | 182 | private static final Float3[] GRAD_3D = { 183 | new Float3(1, 1, 0), new Float3(-1, 1, 0), new Float3(1, -1, 0), new Float3(-1, -1, 0), 184 | new Float3(1, 0, 1), new Float3(-1, 0, 1), new Float3(1, 0, -1), new Float3(-1, 0, -1), 185 | new Float3(0, 1, 1), new Float3(0, -1, 1), new Float3(0, 1, -1), new Float3(0, -1, -1), 186 | new Float3(1, 1, 0), new Float3(0, -1, 1), new Float3(-1, 1, 0), new Float3(0, -1, -1), 187 | }; 188 | 189 | private static final Float2[] CELL_2D = 190 | { 191 | new Float2(-0.4313539279f, 0.1281943404f), new Float2(-0.1733316799f, 0.415278375f), new Float2(-0.2821957395f, -0.3505218461f), new Float2(-0.2806473808f, 0.3517627718f), new Float2(0.3125508975f, -0.3237467165f), new Float2(0.3383018443f, -0.2967353402f), new Float2(-0.4393982022f, -0.09710417025f), new Float2(-0.4460443703f, -0.05953502905f), 192 | new Float2(-0.302223039f, 0.3334085102f), new Float2(-0.212681052f, -0.3965687458f), new Float2(-0.2991156529f, 0.3361990872f), new Float2(0.2293323691f, 0.3871778202f), new Float2(0.4475439151f, -0.04695150755f), new Float2(0.1777518f, 0.41340573f), new Float2(0.1688522499f, -0.4171197882f), new Float2(-0.0976597166f, 0.4392750616f), 193 | new Float2(0.08450188373f, 0.4419948321f), new Float2(-0.4098760448f, -0.1857461384f), new Float2(0.3476585782f, -0.2857157906f), new Float2(-0.3350670039f, -0.30038326f), new Float2(0.2298190031f, -0.3868891648f), new Float2(-0.01069924099f, 0.449872789f), new Float2(-0.4460141246f, -0.05976119672f), new Float2(0.3650293864f, 0.2631606867f), 194 | new Float2(-0.349479423f, 0.2834856838f), new Float2(-0.4122720642f, 0.1803655873f), new Float2(-0.267327811f, 0.3619887311f), new Float2(0.322124041f, -0.3142230135f), new Float2(0.2880445931f, -0.3457315612f), new Float2(0.3892170926f, -0.2258540565f), new Float2(0.4492085018f, -0.02667811596f), new Float2(-0.4497724772f, 0.01430799601f), 195 | new Float2(0.1278175387f, -0.4314657307f), new Float2(-0.03572100503f, 0.4485799926f), new Float2(-0.4297407068f, -0.1335025276f), new Float2(-0.3217817723f, 0.3145735065f), new Float2(-0.3057158873f, 0.3302087162f), new Float2(-0.414503978f, 0.1751754899f), new Float2(-0.3738139881f, 0.2505256519f), new Float2(0.2236891408f, -0.3904653228f), 196 | new Float2(0.002967775577f, -0.4499902136f), new Float2(0.1747128327f, -0.4146991995f), new Float2(-0.4423772489f, -0.08247647938f), new Float2(-0.2763960987f, -0.355112935f), new Float2(-0.4019385906f, -0.2023496216f), new Float2(0.3871414161f, -0.2293938184f), new Float2(-0.430008727f, 0.1326367019f), new Float2(-0.03037574274f, -0.4489736231f), 197 | new Float2(-0.3486181573f, 0.2845441624f), new Float2(0.04553517144f, -0.4476902368f), new Float2(-0.0375802926f, 0.4484280562f), new Float2(0.3266408905f, 0.3095250049f), new Float2(0.06540017593f, -0.4452222108f), new Float2(0.03409025829f, 0.448706869f), new Float2(-0.4449193635f, 0.06742966669f), new Float2(-0.4255936157f, -0.1461850686f), 198 | new Float2(0.449917292f, 0.008627302568f), new Float2(0.05242606404f, 0.4469356864f), new Float2(-0.4495305179f, -0.02055026661f), new Float2(-0.1204775703f, 0.4335725488f), new Float2(-0.341986385f, -0.2924813028f), new Float2(0.3865320182f, 0.2304191809f), new Float2(0.04506097811f, -0.447738214f), new Float2(-0.06283465979f, 0.4455915232f), 199 | new Float2(0.3932600341f, -0.2187385324f), new Float2(0.4472261803f, -0.04988730975f), new Float2(0.3753571011f, -0.2482076684f), new Float2(-0.273662295f, 0.357223947f), new Float2(0.1700461538f, 0.4166344988f), new Float2(0.4102692229f, 0.1848760794f), new Float2(0.323227187f, -0.3130881435f), new Float2(-0.2882310238f, -0.3455761521f), 200 | new Float2(0.2050972664f, 0.4005435199f), new Float2(0.4414085979f, -0.08751256895f), new Float2(-0.1684700334f, 0.4172743077f), new Float2(-0.003978032396f, 0.4499824166f), new Float2(-0.2055133639f, 0.4003301853f), new Float2(-0.006095674897f, -0.4499587123f), new Float2(-0.1196228124f, -0.4338091548f), new Float2(0.3901528491f, -0.2242337048f), 201 | new Float2(0.01723531752f, 0.4496698165f), new Float2(-0.3015070339f, 0.3340561458f), new Float2(-0.01514262423f, -0.4497451511f), new Float2(-0.4142574071f, -0.1757577897f), new Float2(-0.1916377265f, -0.4071547394f), new Float2(0.3749248747f, 0.2488600778f), new Float2(-0.2237774255f, 0.3904147331f), new Float2(-0.4166343106f, -0.1700466149f), 202 | new Float2(0.3619171625f, 0.267424695f), new Float2(0.1891126846f, -0.4083336779f), new Float2(-0.3127425077f, 0.323561623f), new Float2(-0.3281807787f, 0.307891826f), new Float2(-0.2294806661f, 0.3870899429f), new Float2(-0.3445266136f, 0.2894847362f), new Float2(-0.4167095422f, -0.1698621719f), new Float2(-0.257890321f, -0.3687717212f), 203 | new Float2(-0.3612037825f, 0.2683874578f), new Float2(0.2267996491f, 0.3886668486f), new Float2(0.207157062f, 0.3994821043f), new Float2(0.08355176718f, -0.4421754202f), new Float2(-0.4312233307f, 0.1286329626f), new Float2(0.3257055497f, 0.3105090899f), new Float2(0.177701095f, -0.4134275279f), new Float2(-0.445182522f, 0.06566979625f), 204 | new Float2(0.3955143435f, 0.2146355146f), new Float2(-0.4264613988f, 0.1436338239f), new Float2(-0.3793799665f, -0.2420141339f), new Float2(0.04617599081f, -0.4476245948f), new Float2(-0.371405428f, -0.2540826796f), new Float2(0.2563570295f, -0.3698392535f), new Float2(0.03476646309f, 0.4486549822f), new Float2(-0.3065454405f, 0.3294387544f), 205 | new Float2(-0.2256979823f, 0.3893076172f), new Float2(0.4116448463f, -0.1817925206f), new Float2(-0.2907745828f, -0.3434387019f), new Float2(0.2842278468f, -0.348876097f), new Float2(0.3114589359f, -0.3247973695f), new Float2(0.4464155859f, -0.0566844308f), new Float2(-0.3037334033f, -0.3320331606f), new Float2(0.4079607166f, 0.1899159123f), 206 | new Float2(-0.3486948919f, -0.2844501228f), new Float2(0.3264821436f, 0.3096924441f), new Float2(0.3211142406f, 0.3152548881f), new Float2(0.01183382662f, 0.4498443737f), new Float2(0.4333844092f, 0.1211526057f), new Float2(0.3118668416f, 0.324405723f), new Float2(-0.272753471f, 0.3579183483f), new Float2(-0.422228622f, -0.1556373694f), 207 | new Float2(-0.1009700099f, -0.4385260051f), new Float2(-0.2741171231f, -0.3568750521f), new Float2(-0.1465125133f, 0.4254810025f), new Float2(0.2302279044f, -0.3866459777f), new Float2(-0.3699435608f, 0.2562064828f), new Float2(0.105700352f, -0.4374099171f), new Float2(-0.2646713633f, 0.3639355292f), new Float2(0.3521828122f, 0.2801200935f), 208 | new Float2(-0.1864187807f, -0.4095705534f), new Float2(0.1994492955f, -0.4033856449f), new Float2(0.3937065066f, 0.2179339044f), new Float2(-0.3226158377f, 0.3137180602f), new Float2(0.3796235338f, 0.2416318948f), new Float2(0.1482921929f, 0.4248640083f), new Float2(-0.407400394f, 0.1911149365f), new Float2(0.4212853031f, 0.1581729856f), 209 | new Float2(-0.2621297173f, 0.3657704353f), new Float2(-0.2536986953f, -0.3716678248f), new Float2(-0.2100236383f, 0.3979825013f), new Float2(0.3624152444f, 0.2667493029f), new Float2(-0.3645038479f, -0.2638881295f), new Float2(0.2318486784f, 0.3856762766f), new Float2(-0.3260457004f, 0.3101519002f), new Float2(-0.2130045332f, -0.3963950918f), 210 | new Float2(0.3814998766f, -0.2386584257f), new Float2(-0.342977305f, 0.2913186713f), new Float2(-0.4355865605f, 0.1129794154f), new Float2(-0.2104679605f, 0.3977477059f), new Float2(0.3348364681f, -0.3006402163f), new Float2(0.3430468811f, 0.2912367377f), new Float2(-0.2291836801f, -0.3872658529f), new Float2(0.2547707298f, -0.3709337882f), 211 | new Float2(0.4236174945f, -0.151816397f), new Float2(-0.15387742f, 0.4228731957f), new Float2(-0.4407449312f, 0.09079595574f), new Float2(-0.06805276192f, -0.444824484f), new Float2(0.4453517192f, -0.06451237284f), new Float2(0.2562464609f, -0.3699158705f), new Float2(0.3278198355f, -0.3082761026f), new Float2(-0.4122774207f, -0.1803533432f), 212 | new Float2(0.3354090914f, -0.3000012356f), new Float2(0.446632869f, -0.05494615882f), new Float2(-0.1608953296f, 0.4202531296f), new Float2(-0.09463954939f, 0.4399356268f), new Float2(-0.02637688324f, -0.4492262904f), new Float2(0.447102804f, -0.05098119915f), new Float2(-0.4365670908f, 0.1091291678f), new Float2(-0.3959858651f, 0.2137643437f), 213 | new Float2(-0.4240048207f, -0.1507312575f), new Float2(-0.3882794568f, 0.2274622243f), new Float2(-0.4283652566f, -0.1378521198f), new Float2(0.3303888091f, 0.305521251f), new Float2(0.3321434919f, -0.3036127481f), new Float2(-0.413021046f, -0.1786438231f), new Float2(0.08403060337f, -0.4420846725f), new Float2(-0.3822882919f, 0.2373934748f), 214 | new Float2(-0.3712395594f, -0.2543249683f), new Float2(0.4472363971f, -0.04979563372f), new Float2(-0.4466591209f, 0.05473234629f), new Float2(0.0486272539f, -0.4473649407f), new Float2(-0.4203101295f, -0.1607463688f), new Float2(0.2205360833f, 0.39225481f), new Float2(-0.3624900666f, 0.2666476169f), new Float2(-0.4036086833f, -0.1989975647f), 215 | new Float2(0.2152727807f, 0.3951678503f), new Float2(-0.4359392962f, -0.1116106179f), new Float2(0.4178354266f, 0.1670735057f), new Float2(0.2007630161f, 0.4027334247f), new Float2(-0.07278067175f, -0.4440754146f), new Float2(0.3644748615f, -0.2639281632f), new Float2(-0.4317451775f, 0.126870413f), new Float2(-0.297436456f, 0.3376855855f), 216 | new Float2(-0.2998672222f, 0.3355289094f), new Float2(-0.2673674124f, 0.3619594822f), new Float2(0.2808423357f, 0.3516071423f), new Float2(0.3498946567f, 0.2829730186f), new Float2(-0.2229685561f, 0.390877248f), new Float2(0.3305823267f, 0.3053118493f), new Float2(-0.2436681211f, -0.3783197679f), new Float2(-0.03402776529f, 0.4487116125f), 217 | new Float2(-0.319358823f, 0.3170330301f), new Float2(0.4454633477f, -0.06373700535f), new Float2(0.4483504221f, 0.03849544189f), new Float2(-0.4427358436f, -0.08052932871f), new Float2(0.05452298565f, 0.4466847255f), new Float2(-0.2812560807f, 0.3512762688f), new Float2(0.1266696921f, 0.4318041097f), new Float2(-0.3735981243f, 0.2508474468f), 218 | new Float2(0.2959708351f, -0.3389708908f), new Float2(-0.3714377181f, 0.254035473f), new Float2(-0.404467102f, -0.1972469604f), new Float2(0.1636165687f, -0.419201167f), new Float2(0.3289185495f, -0.3071035458f), new Float2(-0.2494824991f, -0.3745109914f), new Float2(0.03283133272f, 0.4488007393f), new Float2(-0.166306057f, -0.4181414777f), 219 | new Float2(-0.106833179f, 0.4371346153f), new Float2(0.06440260376f, -0.4453676062f), new Float2(-0.4483230967f, 0.03881238203f), new Float2(-0.421377757f, -0.1579265206f), new Float2(0.05097920662f, -0.4471030312f), new Float2(0.2050584153f, -0.4005634111f), new Float2(0.4178098529f, -0.167137449f), new Float2(-0.3565189504f, -0.2745801121f), 220 | new Float2(0.4478398129f, 0.04403977727f), new Float2(-0.3399999602f, -0.2947881053f), new Float2(0.3767121994f, 0.2461461331f), new Float2(-0.3138934434f, 0.3224451987f), new Float2(-0.1462001792f, -0.4255884251f), new Float2(0.3970290489f, -0.2118205239f), new Float2(0.4459149305f, -0.06049689889f), new Float2(-0.4104889426f, -0.1843877112f), 221 | new Float2(0.1475103971f, -0.4251360756f), new Float2(0.09258030352f, 0.4403735771f), new Float2(-0.1589664637f, -0.4209865359f), new Float2(0.2482445008f, 0.3753327428f), new Float2(0.4383624232f, -0.1016778537f), new Float2(0.06242802956f, 0.4456486745f), new Float2(0.2846591015f, -0.3485243118f), new Float2(-0.344202744f, -0.2898697484f), 222 | new Float2(0.1198188883f, -0.4337550392f), new Float2(-0.243590703f, 0.3783696201f), new Float2(0.2958191174f, -0.3391033025f), new Float2(-0.1164007991f, 0.4346847754f), new Float2(0.1274037151f, -0.4315881062f), new Float2(0.368047306f, 0.2589231171f), new Float2(0.2451436949f, 0.3773652989f), new Float2(-0.4314509715f, 0.12786735f), 223 | }; 224 | 225 | private static final Float3[] CELL_3D = 226 | { 227 | new Float3(0.1453787434f, -0.4149781685f, -0.0956981749f), new Float3(-0.01242829687f, -0.1457918398f, -0.4255470325f), new Float3(0.2877979582f, -0.02606483451f, -0.3449535616f), new Float3(-0.07732986802f, 0.2377094325f, 0.3741848704f), new Float3(0.1107205875f, -0.3552302079f, -0.2530858567f), new Float3(0.2755209141f, 0.2640521179f, -0.238463215f), new Float3(0.294168941f, 0.1526064594f, 0.3044271714f), new Float3(0.4000921098f, -0.2034056362f, 0.03244149937f), 228 | new Float3(-0.1697304074f, 0.3970864695f, -0.1265461359f), new Float3(-0.1483224484f, -0.3859694688f, 0.1775613147f), new Float3(0.2623596946f, -0.2354852944f, 0.2796677792f), new Float3(-0.2709003183f, 0.3505271138f, -0.07901746678f), new Float3(-0.03516550699f, 0.3885234328f, 0.2243054374f), new Float3(-0.1267712655f, 0.1920044036f, 0.3867342179f), new Float3(0.02952021915f, 0.4409685861f, 0.08470692262f), new Float3(-0.2806854217f, -0.266996757f, 0.2289725438f), 229 | new Float3(-0.171159547f, 0.2141185563f, 0.3568720405f), new Float3(0.2113227183f, 0.3902405947f, -0.07453178509f), new Float3(-0.1024352839f, 0.2128044156f, -0.3830421561f), new Float3(-0.3304249877f, -0.1566986703f, 0.2622305365f), new Float3(0.2091111325f, 0.3133278055f, -0.2461670583f), new Float3(0.344678154f, -0.1944240454f, -0.2142341261f), new Float3(0.1984478035f, -0.3214342325f, -0.2445373252f), new Float3(-0.2929008603f, 0.2262915116f, 0.2559320961f), 230 | new Float3(-0.1617332831f, 0.006314769776f, -0.4198838754f), new Float3(-0.3582060271f, -0.148303178f, -0.2284613961f), new Float3(-0.1852067326f, -0.3454119342f, -0.2211087107f), new Float3(0.3046301062f, 0.1026310383f, 0.314908508f), new Float3(-0.03816768434f, -0.2551766358f, -0.3686842991f), new Float3(-0.4084952196f, 0.1805950793f, 0.05492788837f), new Float3(-0.02687443361f, -0.2749741471f, 0.3551999201f), new Float3(-0.03801098351f, 0.3277859044f, 0.3059600725f), 231 | new Float3(0.2371120802f, 0.2900386767f, -0.2493099024f), new Float3(0.4447660503f, 0.03946930643f, 0.05590469027f), new Float3(0.01985147278f, -0.01503183293f, -0.4493105419f), new Float3(0.4274339143f, 0.03345994256f, -0.1366772882f), new Float3(-0.2072988631f, 0.2871414597f, -0.2776273824f), new Float3(-0.3791240978f, 0.1281177671f, 0.2057929936f), new Float3(-0.2098721267f, -0.1007087278f, -0.3851122467f), new Float3(0.01582798878f, 0.4263894424f, 0.1429738373f), 232 | new Float3(-0.1888129464f, -0.3160996813f, -0.2587096108f), new Float3(0.1612988974f, -0.1974805082f, -0.3707885038f), new Float3(-0.08974491322f, 0.229148752f, -0.3767448739f), new Float3(0.07041229526f, 0.4150230285f, -0.1590534329f), new Float3(-0.1082925611f, -0.1586061639f, 0.4069604477f), new Float3(0.2474100658f, -0.3309414609f, 0.1782302128f), new Float3(-0.1068836661f, -0.2701644537f, -0.3436379634f), new Float3(0.2396452163f, 0.06803600538f, -0.3747549496f), 233 | new Float3(-0.3063886072f, 0.2597428179f, 0.2028785103f), new Float3(0.1593342891f, -0.3114350249f, -0.2830561951f), new Float3(0.2709690528f, 0.1412648683f, -0.3303331794f), new Float3(-0.1519780427f, 0.3623355133f, 0.2193527988f), new Float3(0.1699773681f, 0.3456012883f, 0.2327390037f), new Float3(-0.1986155616f, 0.3836276443f, -0.1260225743f), new Float3(-0.1887482106f, -0.2050154888f, -0.353330953f), new Float3(0.2659103394f, 0.3015631259f, -0.2021172246f), 234 | new Float3(-0.08838976154f, -0.4288819642f, -0.1036702021f), new Float3(-0.04201869311f, 0.3099592485f, 0.3235115047f), new Float3(-0.3230334656f, 0.201549922f, -0.2398478873f), new Float3(0.2612720941f, 0.2759854499f, -0.2409749453f), new Float3(0.385713046f, 0.2193460345f, 0.07491837764f), new Float3(0.07654967953f, 0.3721732183f, 0.241095919f), new Float3(0.4317038818f, -0.02577753072f, 0.1243675091f), new Float3(-0.2890436293f, -0.3418179959f, -0.04598084447f), 235 | new Float3(-0.2201947582f, 0.383023377f, -0.08548310451f), new Float3(0.4161322773f, -0.1669634289f, -0.03817251927f), new Float3(0.2204718095f, 0.02654238946f, -0.391391981f), new Float3(-0.1040307469f, 0.3890079625f, -0.2008741118f), new Float3(-0.1432122615f, 0.371614387f, -0.2095065525f), new Float3(0.3978380468f, -0.06206669342f, 0.2009293758f), new Float3(-0.2599274663f, 0.2616724959f, -0.2578084893f), new Float3(0.4032618332f, -0.1124593585f, 0.1650235939f), 236 | new Float3(-0.08953470255f, -0.3048244735f, 0.3186935478f), new Float3(0.118937202f, -0.2875221847f, 0.325092195f), new Float3(0.02167047076f, -0.03284630549f, -0.4482761547f), new Float3(-0.3411343612f, 0.2500031105f, 0.1537068389f), new Float3(0.3162964612f, 0.3082064153f, -0.08640228117f), new Float3(0.2355138889f, -0.3439334267f, -0.1695376245f), new Float3(-0.02874541518f, -0.3955933019f, 0.2125550295f), new Float3(-0.2461455173f, 0.02020282325f, -0.3761704803f), 237 | new Float3(0.04208029445f, -0.4470439576f, 0.02968078139f), new Float3(0.2727458746f, 0.2288471896f, -0.2752065618f), new Float3(-0.1347522818f, -0.02720848277f, -0.4284874806f), new Float3(0.3829624424f, 0.1231931484f, -0.2016512234f), new Float3(-0.3547613644f, 0.1271702173f, 0.2459107769f), new Float3(0.2305790207f, 0.3063895591f, 0.2354968222f), new Float3(-0.08323845599f, -0.1922245118f, 0.3982726409f), new Float3(0.2993663085f, -0.2619918095f, -0.2103333191f), 238 | new Float3(-0.2154865723f, 0.2706747713f, 0.287751117f), new Float3(0.01683355354f, -0.2680655787f, -0.3610505186f), new Float3(0.05240429123f, 0.4335128183f, -0.1087217856f), new Float3(0.00940104872f, -0.4472890582f, 0.04841609928f), new Float3(0.3465688735f, 0.01141914583f, -0.2868093776f), new Float3(-0.3706867948f, -0.2551104378f, 0.003156692623f), new Float3(0.2741169781f, 0.2139972417f, -0.2855959784f), new Float3(0.06413433865f, 0.1708718512f, 0.4113266307f), 239 | new Float3(-0.388187972f, -0.03973280434f, -0.2241236325f), new Float3(0.06419469312f, -0.2803682491f, 0.3460819069f), new Float3(-0.1986120739f, -0.3391173584f, 0.2192091725f), new Float3(-0.203203009f, -0.3871641506f, 0.1063600375f), new Float3(-0.1389736354f, -0.2775901578f, -0.3257760473f), new Float3(-0.06555641638f, 0.342253257f, -0.2847192729f), new Float3(-0.2529246486f, -0.2904227915f, 0.2327739768f), new Float3(0.1444476522f, 0.1069184044f, 0.4125570634f), 240 | new Float3(-0.3643780054f, -0.2447099973f, -0.09922543227f), new Float3(0.4286142488f, -0.1358496089f, -0.01829506817f), new Float3(0.165872923f, -0.3136808464f, -0.2767498872f), new Float3(0.2219610524f, -0.3658139958f, 0.1393320198f), new Float3(0.04322940318f, -0.3832730794f, 0.2318037215f), new Float3(-0.08481269795f, -0.4404869674f, -0.03574965489f), new Float3(0.1822082075f, -0.3953259299f, 0.1140946023f), new Float3(-0.3269323334f, 0.3036542563f, 0.05838957105f), 241 | new Float3(-0.4080485344f, 0.04227858267f, -0.184956522f), new Float3(0.2676025294f, -0.01299671652f, 0.36155217f), new Float3(0.3024892441f, -0.1009990293f, -0.3174892964f), new Float3(0.1448494052f, 0.425921681f, -0.0104580805f), new Float3(0.4198402157f, 0.08062320474f, 0.1404780841f), new Float3(-0.3008872161f, -0.333040905f, -0.03241355801f), new Float3(0.3639310428f, -0.1291284382f, -0.2310412139f), new Float3(0.3295806598f, 0.0184175994f, -0.3058388149f), 242 | new Float3(0.2776259487f, -0.2974929052f, -0.1921504723f), new Float3(0.4149000507f, -0.144793182f, -0.09691688386f), new Float3(0.145016715f, -0.0398992945f, 0.4241205002f), new Float3(0.09299023471f, -0.299732164f, -0.3225111565f), new Float3(0.1028907093f, -0.361266869f, 0.247789732f), new Float3(0.2683057049f, -0.07076041213f, -0.3542668666f), new Float3(-0.4227307273f, -0.07933161816f, -0.1323073187f), new Float3(-0.1781224702f, 0.1806857196f, -0.3716517945f), 243 | new Float3(0.4390788626f, -0.02841848598f, -0.09435116353f), new Float3(0.2972583585f, 0.2382799621f, -0.2394997452f), new Float3(-0.1707002821f, 0.2215845691f, 0.3525077196f), new Float3(0.3806686614f, 0.1471852559f, -0.1895464869f), new Float3(-0.1751445661f, -0.274887877f, 0.3102596268f), new Float3(-0.2227237566f, -0.2316778837f, 0.3149912482f), new Float3(0.1369633021f, 0.1341343041f, -0.4071228836f), new Float3(-0.3529503428f, -0.2472893463f, -0.129514612f), 244 | new Float3(-0.2590744185f, -0.2985577559f, -0.2150435121f), new Float3(-0.3784019401f, 0.2199816631f, -0.1044989934f), new Float3(-0.05635805671f, 0.1485737441f, 0.4210102279f), new Float3(0.3251428613f, 0.09666046873f, -0.2957006485f), new Float3(-0.4190995804f, 0.1406751354f, -0.08405978803f), new Float3(-0.3253150961f, -0.3080335042f, -0.04225456877f), new Float3(0.2857945863f, -0.05796152095f, 0.3427271751f), new Float3(-0.2733604046f, 0.1973770973f, -0.2980207554f), 245 | new Float3(0.219003657f, 0.2410037886f, -0.3105713639f), new Float3(0.3182767252f, -0.271342949f, 0.1660509868f), new Float3(-0.03222023115f, -0.3331161506f, -0.300824678f), new Float3(-0.3087780231f, 0.1992794134f, -0.2596995338f), new Float3(-0.06487611647f, -0.4311322747f, 0.1114273361f), new Float3(0.3921171432f, -0.06294284106f, -0.2116183942f), new Float3(-0.1606404506f, -0.358928121f, -0.2187812825f), new Float3(-0.03767771199f, -0.2290351443f, 0.3855169162f), 246 | new Float3(0.1394866832f, -0.3602213994f, 0.2308332918f), new Float3(-0.4345093872f, 0.005751117145f, 0.1169124335f), new Float3(-0.1044637494f, 0.4168128432f, -0.1336202785f), new Float3(0.2658727501f, 0.2551943237f, 0.2582393035f), new Float3(0.2051461999f, 0.1975390727f, 0.3484154868f), new Float3(-0.266085566f, 0.23483312f, 0.2766800993f), new Float3(0.07849405464f, -0.3300346342f, -0.2956616708f), new Float3(-0.2160686338f, 0.05376451292f, -0.3910546287f), 247 | new Float3(-0.185779186f, 0.2148499206f, 0.3490352499f), new Float3(0.02492421743f, -0.3229954284f, -0.3123343347f), new Float3(-0.120167831f, 0.4017266681f, 0.1633259825f), new Float3(-0.02160084693f, -0.06885389554f, 0.4441762538f), new Float3(0.2597670064f, 0.3096300784f, 0.1978643903f), new Float3(-0.1611553854f, -0.09823036005f, 0.4085091653f), new Float3(-0.3278896792f, 0.1461670309f, 0.2713366126f), new Float3(0.2822734956f, 0.03754421121f, -0.3484423997f), 248 | new Float3(0.03169341113f, 0.347405252f, -0.2842624114f), new Float3(0.2202613604f, -0.3460788041f, -0.1849713341f), new Float3(0.2933396046f, 0.3031973659f, 0.1565989581f), new Float3(-0.3194922995f, 0.2453752201f, -0.200538455f), new Float3(-0.3441586045f, -0.1698856132f, -0.2349334659f), new Float3(0.2703645948f, -0.3574277231f, 0.04060059933f), new Float3(0.2298568861f, 0.3744156221f, 0.0973588921f), new Float3(0.09326603877f, -0.3170108894f, 0.3054595587f), 249 | new Float3(-0.1116165319f, -0.2985018719f, 0.3177080142f), new Float3(0.2172907365f, -0.3460005203f, -0.1885958001f), new Float3(0.1991339479f, 0.3820341668f, -0.1299829458f), new Float3(-0.0541918155f, -0.2103145071f, 0.39412061f), new Float3(0.08871336998f, 0.2012117383f, 0.3926114802f), new Float3(0.2787673278f, 0.3505404674f, 0.04370535101f), new Float3(-0.322166438f, 0.3067213525f, 0.06804996813f), new Float3(-0.4277366384f, 0.132066775f, 0.04582286686f), 250 | new Float3(0.240131882f, -0.1612516055f, 0.344723946f), new Float3(0.1448607981f, -0.2387819045f, 0.3528435224f), new Float3(-0.3837065682f, -0.2206398454f, 0.08116235683f), new Float3(-0.4382627882f, -0.09082753406f, -0.04664855374f), new Float3(-0.37728353f, 0.05445141085f, 0.2391488697f), new Float3(0.1259579313f, 0.348394558f, 0.2554522098f), new Float3(-0.1406285511f, -0.270877371f, -0.3306796947f), new Float3(-0.1580694418f, 0.4162931958f, -0.06491553533f), 251 | new Float3(0.2477612106f, -0.2927867412f, -0.2353514536f), new Float3(0.2916132853f, 0.3312535401f, 0.08793624968f), new Float3(0.07365265219f, -0.1666159848f, 0.411478311f), new Float3(-0.26126526f, -0.2422237692f, 0.2748965434f), new Float3(-0.3721862032f, 0.252790166f, 0.008634938242f), new Float3(-0.3691191571f, -0.255281188f, 0.03290232422f), new Float3(0.2278441737f, -0.3358364886f, 0.1944244981f), new Float3(0.363398169f, -0.2310190248f, 0.1306597909f), 252 | new Float3(-0.304231482f, -0.2698452035f, 0.1926830856f), new Float3(-0.3199312232f, 0.316332536f, -0.008816977938f), new Float3(0.2874852279f, 0.1642275508f, -0.304764754f), new Float3(-0.1451096801f, 0.3277541114f, -0.2720669462f), new Float3(0.3220090754f, 0.0511344108f, 0.3101538769f), new Float3(-0.1247400865f, -0.04333605335f, -0.4301882115f), new Float3(-0.2829555867f, -0.3056190617f, -0.1703910946f), new Float3(0.1069384374f, 0.3491024667f, -0.2630430352f), 253 | new Float3(-0.1420661144f, -0.3055376754f, -0.2982682484f), new Float3(-0.250548338f, 0.3156466809f, -0.2002316239f), new Float3(0.3265787872f, 0.1871229129f, 0.2466400438f), new Float3(0.07646097258f, -0.3026690852f, 0.324106687f), new Float3(0.3451771584f, 0.2757120714f, -0.0856480183f), new Float3(0.298137964f, 0.2852657134f, 0.179547284f), new Float3(0.2812250376f, 0.3466716415f, 0.05684409612f), new Float3(0.4390345476f, -0.09790429955f, -0.01278335452f), 254 | new Float3(0.2148373234f, 0.1850172527f, 0.3494474791f), new Float3(0.2595421179f, -0.07946825393f, 0.3589187731f), new Float3(0.3182823114f, -0.307355516f, -0.08203022006f), new Float3(-0.4089859285f, -0.04647718411f, 0.1818526372f), new Float3(-0.2826749061f, 0.07417482322f, 0.3421885344f), new Float3(0.3483864637f, 0.225442246f, -0.1740766085f), new Float3(-0.3226415069f, -0.1420585388f, -0.2796816575f), new Float3(0.4330734858f, -0.118868561f, -0.02859407492f), 255 | new Float3(-0.08717822568f, -0.3909896417f, -0.2050050172f), new Float3(-0.2149678299f, 0.3939973956f, -0.03247898316f), new Float3(-0.2687330705f, 0.322686276f, -0.1617284888f), new Float3(0.2105665099f, -0.1961317136f, -0.3459683451f), new Float3(0.4361845915f, -0.1105517485f, 0.004616608544f), new Float3(0.05333333359f, -0.313639498f, -0.3182543336f), new Float3(-0.05986216652f, 0.1361029153f, -0.4247264031f), new Float3(0.3664988455f, 0.2550543014f, -0.05590974511f), 256 | new Float3(-0.2341015558f, -0.182405731f, 0.3382670703f), new Float3(-0.04730947785f, -0.4222150243f, -0.1483114513f), new Float3(-0.2391566239f, -0.2577696514f, -0.2808182972f), new Float3(-0.1242081035f, 0.4256953395f, -0.07652336246f), new Float3(0.2614832715f, -0.3650179274f, 0.02980623099f), new Float3(-0.2728794681f, -0.3499628774f, 0.07458404908f), new Float3(0.007892900508f, -0.1672771315f, 0.4176793787f), new Float3(-0.01730330376f, 0.2978486637f, -0.3368779738f), 257 | new Float3(0.2054835762f, -0.3252600376f, -0.2334146693f), new Float3(-0.3231994983f, 0.1564282844f, -0.2712420987f), new Float3(-0.2669545963f, 0.2599343665f, -0.2523278991f), new Float3(-0.05554372779f, 0.3170813944f, -0.3144428146f), new Float3(-0.2083935713f, -0.310922837f, -0.2497981362f), new Float3(0.06989323478f, -0.3156141536f, 0.3130537363f), new Float3(0.3847566193f, -0.1605309138f, -0.1693876312f), new Float3(-0.3026215288f, -0.3001537679f, -0.1443188342f), 258 | new Float3(0.3450735512f, 0.08611519592f, 0.2756962409f), new Float3(0.1814473292f, -0.2788782453f, -0.3029914042f), new Float3(-0.03855010448f, 0.09795110726f, 0.4375151083f), new Float3(0.3533670318f, 0.2665752752f, 0.08105160988f), new Float3(-0.007945601311f, 0.140359426f, -0.4274764309f), new Float3(0.4063099273f, -0.1491768253f, -0.1231199324f), new Float3(-0.2016773589f, 0.008816271194f, -0.4021797064f), new Float3(-0.07527055435f, -0.425643481f, -0.1251477955f), 259 | }; 260 | 261 | 262 | private static int FastFloor(float f) { 263 | return (f >= 0 ? (int) f : (int) f - 1); 264 | } 265 | 266 | 267 | private static int FastRound(float f) { 268 | return (f >= 0) ? (int) (f + (float) 0.5) : (int) (f - (float) 0.5); 269 | } 270 | 271 | 272 | private static float Lerp(float a, float b, float t) { 273 | return a + t * (b - a); 274 | } 275 | 276 | 277 | private static float InterpHermiteFunc(float t) { 278 | return t * t * (3 - 2 * t); 279 | } 280 | 281 | 282 | private static float InterpQuinticFunc(float t) { 283 | return t * t * t * (t * (t * 6 - 15) + 10); 284 | } 285 | 286 | 287 | private static float CubicLerp(float a, float b, float c, float d, float t) { 288 | float p = (d - c) - (a - b); 289 | return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b; 290 | } 291 | 292 | private void CalculateFractalBounding() { 293 | float amp = m_gain; 294 | float ampFractal = 1; 295 | for (int i = 1; i < m_octaves; i++) { 296 | ampFractal += amp; 297 | amp *= m_gain; 298 | } 299 | m_fractalBounding = 1 / ampFractal; 300 | } 301 | 302 | // Hashing 303 | private final static int X_PRIME = 1619; 304 | private final static int Y_PRIME = 31337; 305 | private final static int Z_PRIME = 6971; 306 | private final static int W_PRIME = 1013; 307 | 308 | private static int Hash2D(int seed, int x, int y) { 309 | int hash = seed; 310 | hash ^= X_PRIME * x; 311 | hash ^= Y_PRIME * y; 312 | 313 | hash = hash * hash * hash * 60493; 314 | hash = (hash >> 13) ^ hash; 315 | 316 | return hash; 317 | } 318 | 319 | private static int Hash3D(int seed, int x, int y, int z) { 320 | int hash = seed; 321 | hash ^= X_PRIME * x; 322 | hash ^= Y_PRIME * y; 323 | hash ^= Z_PRIME * z; 324 | 325 | hash = hash * hash * hash * 60493; 326 | hash = (hash >> 13) ^ hash; 327 | 328 | return hash; 329 | } 330 | 331 | private static int Hash4D(int seed, int x, int y, int z, int w) { 332 | int hash = seed; 333 | hash ^= X_PRIME * x; 334 | hash ^= Y_PRIME * y; 335 | hash ^= Z_PRIME * z; 336 | hash ^= W_PRIME * w; 337 | 338 | hash = hash * hash * hash * 60493; 339 | hash = (hash >> 13) ^ hash; 340 | 341 | return hash; 342 | } 343 | 344 | private static float ValCoord2D(int seed, int x, int y) { 345 | int n = seed; 346 | n ^= X_PRIME * x; 347 | n ^= Y_PRIME * y; 348 | 349 | return (n * n * n * 60493) / (float) 2147483648.0; 350 | } 351 | 352 | private static float ValCoord3D(int seed, int x, int y, int z) { 353 | int n = seed; 354 | n ^= X_PRIME * x; 355 | n ^= Y_PRIME * y; 356 | n ^= Z_PRIME * z; 357 | 358 | return (n * n * n * 60493) / (float) 2147483648.0; 359 | } 360 | 361 | private static float ValCoord4D(int seed, int x, int y, int z, int w) { 362 | int n = seed; 363 | n ^= X_PRIME * x; 364 | n ^= Y_PRIME * y; 365 | n ^= Z_PRIME * z; 366 | n ^= W_PRIME * w; 367 | 368 | return (n * n * n * 60493) / (float) 2147483648.0; 369 | } 370 | 371 | private static float GradCoord2D(int seed, int x, int y, float xd, float yd) { 372 | int hash = seed; 373 | hash ^= X_PRIME * x; 374 | hash ^= Y_PRIME * y; 375 | 376 | hash = hash * hash * hash * 60493; 377 | hash = (hash >> 13) ^ hash; 378 | 379 | Float2 g = GRAD_2D[hash & 7]; 380 | 381 | return xd * g.x + yd * g.y; 382 | } 383 | 384 | private static float GradCoord3D(int seed, int x, int y, int z, float xd, float yd, float zd) { 385 | int hash = seed; 386 | hash ^= X_PRIME * x; 387 | hash ^= Y_PRIME * y; 388 | hash ^= Z_PRIME * z; 389 | 390 | hash = hash * hash * hash * 60493; 391 | hash = (hash >> 13) ^ hash; 392 | 393 | Float3 g = GRAD_3D[hash & 15]; 394 | 395 | return xd * g.x + yd * g.y + zd * g.z; 396 | } 397 | 398 | private static float GradCoord4D(int seed, int x, int y, int z, int w, float xd, float yd, float zd, float wd) { 399 | int hash = seed; 400 | hash ^= X_PRIME * x; 401 | hash ^= Y_PRIME * y; 402 | hash ^= Z_PRIME * z; 403 | hash ^= W_PRIME * w; 404 | 405 | hash = hash * hash * hash * 60493; 406 | hash = (hash >> 13) ^ hash; 407 | 408 | hash &= 31; 409 | float a = yd, b = zd, c = wd; // X,Y,Z 410 | switch (hash >> 3) { // OR, DEPENDING ON HIGH ORDER 2 BITS: 411 | case 1: 412 | a = wd; 413 | b = xd; 414 | c = yd; 415 | break; // W,X,Y 416 | case 2: 417 | a = zd; 418 | b = wd; 419 | c = xd; 420 | break; // Z,W,X 421 | case 3: 422 | a = yd; 423 | b = zd; 424 | c = wd; 425 | break; // Y,Z,W 426 | } 427 | return ((hash & 4) == 0 ? -a : a) + ((hash & 2) == 0 ? -b : b) + ((hash & 1) == 0 ? -c : c); 428 | } 429 | 430 | public float GetNoise(float x, float y, float z) { 431 | x *= m_frequency; 432 | y *= m_frequency; 433 | z *= m_frequency; 434 | 435 | switch (m_noiseType) { 436 | case Value: 437 | return SingleValue(m_seed, x, y, z); 438 | case ValueFractal: 439 | switch (m_fractalType) { 440 | case FBM: 441 | return SingleValueFractalFBM(x, y, z); 442 | case Billow: 443 | return SingleValueFractalBillow(x, y, z); 444 | case RigidMulti: 445 | return SingleValueFractalRigidMulti(x, y, z); 446 | default: 447 | return 0; 448 | } 449 | case Perlin: 450 | return SinglePerlin(m_seed, x, y, z); 451 | case PerlinFractal: 452 | switch (m_fractalType) { 453 | case FBM: 454 | return SinglePerlinFractalFBM(x, y, z); 455 | case Billow: 456 | return SinglePerlinFractalBillow(x, y, z); 457 | case RigidMulti: 458 | return SinglePerlinFractalRigidMulti(x, y, z); 459 | default: 460 | return 0; 461 | } 462 | case Simplex: 463 | return SingleSimplex(m_seed, x, y, z); 464 | case SimplexFractal: 465 | switch (m_fractalType) { 466 | case FBM: 467 | return SingleSimplexFractalFBM(x, y, z); 468 | case Billow: 469 | return SingleSimplexFractalBillow(x, y, z); 470 | case RigidMulti: 471 | return SingleSimplexFractalRigidMulti(x, y, z); 472 | default: 473 | return 0; 474 | } 475 | case Cellular: 476 | switch (m_cellularReturnType) { 477 | case CellValue: 478 | case NoiseLookup: 479 | case Distance: 480 | return SingleCellular(x, y, z); 481 | default: 482 | return SingleCellular2Edge(x, y, z); 483 | } 484 | case WhiteNoise: 485 | return GetWhiteNoise(x, y, z); 486 | case Cubic: 487 | return SingleCubic(m_seed, x, y, z); 488 | case CubicFractal: 489 | switch (m_fractalType) { 490 | case FBM: 491 | return SingleCubicFractalFBM(x, y, z); 492 | case Billow: 493 | return SingleCubicFractalBillow(x, y, z); 494 | case RigidMulti: 495 | return SingleCubicFractalRigidMulti(x, y, z); 496 | default: 497 | return 0; 498 | } 499 | default: 500 | return 0; 501 | } 502 | } 503 | 504 | public float GetNoise(float x, float y) { 505 | x *= m_frequency; 506 | y *= m_frequency; 507 | 508 | switch (m_noiseType) { 509 | case Value: 510 | return SingleValue(m_seed, x, y); 511 | case ValueFractal: 512 | switch (m_fractalType) { 513 | case FBM: 514 | return SingleValueFractalFBM(x, y); 515 | case Billow: 516 | return SingleValueFractalBillow(x, y); 517 | case RigidMulti: 518 | return SingleValueFractalRigidMulti(x, y); 519 | default: 520 | return 0; 521 | } 522 | case Perlin: 523 | return SinglePerlin(m_seed, x, y); 524 | case PerlinFractal: 525 | switch (m_fractalType) { 526 | case FBM: 527 | return SinglePerlinFractalFBM(x, y); 528 | case Billow: 529 | return SinglePerlinFractalBillow(x, y); 530 | case RigidMulti: 531 | return SinglePerlinFractalRigidMulti(x, y); 532 | default: 533 | return 0; 534 | } 535 | case Simplex: 536 | return SingleSimplex(m_seed, x, y); 537 | case SimplexFractal: 538 | switch (m_fractalType) { 539 | case FBM: 540 | return SingleSimplexFractalFBM(x, y); 541 | case Billow: 542 | return SingleSimplexFractalBillow(x, y); 543 | case RigidMulti: 544 | return SingleSimplexFractalRigidMulti(x, y); 545 | default: 546 | return 0; 547 | } 548 | case Cellular: 549 | switch (m_cellularReturnType) { 550 | case CellValue: 551 | case NoiseLookup: 552 | case Distance: 553 | return SingleCellular(x, y); 554 | default: 555 | return SingleCellular2Edge(x, y); 556 | } 557 | case WhiteNoise: 558 | return GetWhiteNoise(x, y); 559 | case Cubic: 560 | return SingleCubic(m_seed, x, y); 561 | case CubicFractal: 562 | switch (m_fractalType) { 563 | case FBM: 564 | return SingleCubicFractalFBM(x, y); 565 | case Billow: 566 | return SingleCubicFractalBillow(x, y); 567 | case RigidMulti: 568 | return SingleCubicFractalRigidMulti(x, y); 569 | default: 570 | return 0; 571 | } 572 | default: 573 | return 0; 574 | } 575 | } 576 | 577 | // White Noise 578 | 579 | private int FloatCast2Int(float f) { 580 | int i = Float.floatToRawIntBits(f); 581 | 582 | return i ^ (i >> 16); 583 | } 584 | 585 | public float GetWhiteNoise(float x, float y, float z, float w) { 586 | int xi = FloatCast2Int(x); 587 | int yi = FloatCast2Int(y); 588 | int zi = FloatCast2Int(z); 589 | int wi = FloatCast2Int(w); 590 | 591 | return ValCoord4D(m_seed, xi, yi, zi, wi); 592 | } 593 | 594 | public float GetWhiteNoise(float x, float y, float z) { 595 | int xi = FloatCast2Int(x); 596 | int yi = FloatCast2Int(y); 597 | int zi = FloatCast2Int(z); 598 | 599 | return ValCoord3D(m_seed, xi, yi, zi); 600 | } 601 | 602 | public float GetWhiteNoise(float x, float y) { 603 | int xi = FloatCast2Int(x); 604 | int yi = FloatCast2Int(y); 605 | 606 | return ValCoord2D(m_seed, xi, yi); 607 | } 608 | 609 | public float GetWhiteNoiseInt(int x, int y, int z, int w) { 610 | return ValCoord4D(m_seed, x, y, z, w); 611 | } 612 | 613 | public float GetWhiteNoiseInt(int x, int y, int z) { 614 | return ValCoord3D(m_seed, x, y, z); 615 | } 616 | 617 | public float GetWhiteNoiseInt(int x, int y) { 618 | return ValCoord2D(m_seed, x, y); 619 | } 620 | 621 | // Value Noise 622 | public float GetValueFractal(float x, float y, float z) { 623 | x *= m_frequency; 624 | y *= m_frequency; 625 | z *= m_frequency; 626 | 627 | switch (m_fractalType) { 628 | case FBM: 629 | return SingleValueFractalFBM(x, y, z); 630 | case Billow: 631 | return SingleValueFractalBillow(x, y, z); 632 | case RigidMulti: 633 | return SingleValueFractalRigidMulti(x, y, z); 634 | default: 635 | return 0; 636 | } 637 | } 638 | 639 | private float SingleValueFractalFBM(float x, float y, float z) { 640 | int seed = m_seed; 641 | float sum = SingleValue(seed, x, y, z); 642 | float amp = 1; 643 | 644 | for (int i = 1; i < m_octaves; i++) { 645 | x *= m_lacunarity; 646 | y *= m_lacunarity; 647 | z *= m_lacunarity; 648 | 649 | amp *= m_gain; 650 | sum += SingleValue(++seed, x, y, z) * amp; 651 | } 652 | 653 | return sum * m_fractalBounding; 654 | } 655 | 656 | private float SingleValueFractalBillow(float x, float y, float z) { 657 | int seed = m_seed; 658 | float sum = Math.abs(SingleValue(seed, x, y, z)) * 2 - 1; 659 | float amp = 1; 660 | 661 | for (int i = 1; i < m_octaves; i++) { 662 | x *= m_lacunarity; 663 | y *= m_lacunarity; 664 | z *= m_lacunarity; 665 | 666 | amp *= m_gain; 667 | sum += (Math.abs(SingleValue(++seed, x, y, z)) * 2 - 1) * amp; 668 | } 669 | 670 | return sum * m_fractalBounding; 671 | } 672 | 673 | private float SingleValueFractalRigidMulti(float x, float y, float z) { 674 | int seed = m_seed; 675 | float sum = 1 - Math.abs(SingleValue(seed, x, y, z)); 676 | float amp = 1; 677 | 678 | for (int i = 1; i < m_octaves; i++) { 679 | x *= m_lacunarity; 680 | y *= m_lacunarity; 681 | z *= m_lacunarity; 682 | 683 | amp *= m_gain; 684 | sum -= (1 - Math.abs(SingleValue(++seed, x, y, z))) * amp; 685 | } 686 | 687 | return sum; 688 | } 689 | 690 | public float GetValue(float x, float y, float z) { 691 | return SingleValue(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); 692 | } 693 | 694 | private float SingleValue(int seed, float x, float y, float z) { 695 | int x0 = FastFloor(x); 696 | int y0 = FastFloor(y); 697 | int z0 = FastFloor(z); 698 | int x1 = x0 + 1; 699 | int y1 = y0 + 1; 700 | int z1 = z0 + 1; 701 | 702 | float xs, ys, zs; 703 | switch (m_interp) { 704 | default: 705 | case Linear: 706 | xs = x - x0; 707 | ys = y - y0; 708 | zs = z - z0; 709 | break; 710 | case Hermite: 711 | xs = InterpHermiteFunc(x - x0); 712 | ys = InterpHermiteFunc(y - y0); 713 | zs = InterpHermiteFunc(z - z0); 714 | break; 715 | case Quintic: 716 | xs = InterpQuinticFunc(x - x0); 717 | ys = InterpQuinticFunc(y - y0); 718 | zs = InterpQuinticFunc(z - z0); 719 | break; 720 | } 721 | 722 | float xf00 = Lerp(ValCoord3D(seed, x0, y0, z0), ValCoord3D(seed, x1, y0, z0), xs); 723 | float xf10 = Lerp(ValCoord3D(seed, x0, y1, z0), ValCoord3D(seed, x1, y1, z0), xs); 724 | float xf01 = Lerp(ValCoord3D(seed, x0, y0, z1), ValCoord3D(seed, x1, y0, z1), xs); 725 | float xf11 = Lerp(ValCoord3D(seed, x0, y1, z1), ValCoord3D(seed, x1, y1, z1), xs); 726 | 727 | float yf0 = Lerp(xf00, xf10, ys); 728 | float yf1 = Lerp(xf01, xf11, ys); 729 | 730 | return Lerp(yf0, yf1, zs); 731 | } 732 | 733 | public float GetValueFractal(float x, float y) { 734 | x *= m_frequency; 735 | y *= m_frequency; 736 | 737 | switch (m_fractalType) { 738 | case FBM: 739 | return SingleValueFractalFBM(x, y); 740 | case Billow: 741 | return SingleValueFractalBillow(x, y); 742 | case RigidMulti: 743 | return SingleValueFractalRigidMulti(x, y); 744 | default: 745 | return 0; 746 | } 747 | } 748 | 749 | private float SingleValueFractalFBM(float x, float y) { 750 | int seed = m_seed; 751 | float sum = SingleValue(seed, x, y); 752 | float amp = 1; 753 | 754 | for (int i = 1; i < m_octaves; i++) { 755 | x *= m_lacunarity; 756 | y *= m_lacunarity; 757 | 758 | amp *= m_gain; 759 | sum += SingleValue(++seed, x, y) * amp; 760 | } 761 | 762 | return sum * m_fractalBounding; 763 | } 764 | 765 | private float SingleValueFractalBillow(float x, float y) { 766 | int seed = m_seed; 767 | float sum = Math.abs(SingleValue(seed, x, y)) * 2 - 1; 768 | float amp = 1; 769 | 770 | for (int i = 1; i < m_octaves; i++) { 771 | x *= m_lacunarity; 772 | y *= m_lacunarity; 773 | amp *= m_gain; 774 | sum += (Math.abs(SingleValue(++seed, x, y)) * 2 - 1) * amp; 775 | } 776 | 777 | return sum * m_fractalBounding; 778 | } 779 | 780 | private float SingleValueFractalRigidMulti(float x, float y) { 781 | int seed = m_seed; 782 | float sum = 1 - Math.abs(SingleValue(seed, x, y)); 783 | float amp = 1; 784 | 785 | for (int i = 1; i < m_octaves; i++) { 786 | x *= m_lacunarity; 787 | y *= m_lacunarity; 788 | 789 | amp *= m_gain; 790 | sum -= (1 - Math.abs(SingleValue(++seed, x, y))) * amp; 791 | } 792 | 793 | return sum; 794 | } 795 | 796 | public float GetValue(float x, float y) { 797 | return SingleValue(m_seed, x * m_frequency, y * m_frequency); 798 | } 799 | 800 | private float SingleValue(int seed, float x, float y) { 801 | int x0 = FastFloor(x); 802 | int y0 = FastFloor(y); 803 | int x1 = x0 + 1; 804 | int y1 = y0 + 1; 805 | 806 | float xs, ys; 807 | switch (m_interp) { 808 | default: 809 | case Linear: 810 | xs = x - x0; 811 | ys = y - y0; 812 | break; 813 | case Hermite: 814 | xs = InterpHermiteFunc(x - x0); 815 | ys = InterpHermiteFunc(y - y0); 816 | break; 817 | case Quintic: 818 | xs = InterpQuinticFunc(x - x0); 819 | ys = InterpQuinticFunc(y - y0); 820 | break; 821 | } 822 | 823 | float xf0 = Lerp(ValCoord2D(seed, x0, y0), ValCoord2D(seed, x1, y0), xs); 824 | float xf1 = Lerp(ValCoord2D(seed, x0, y1), ValCoord2D(seed, x1, y1), xs); 825 | 826 | return Lerp(xf0, xf1, ys); 827 | } 828 | 829 | // Gradient Noise 830 | public float GetPerlinFractal(float x, float y, float z) { 831 | x *= m_frequency; 832 | y *= m_frequency; 833 | z *= m_frequency; 834 | 835 | switch (m_fractalType) { 836 | case FBM: 837 | return SinglePerlinFractalFBM(x, y, z); 838 | case Billow: 839 | return SinglePerlinFractalBillow(x, y, z); 840 | case RigidMulti: 841 | return SinglePerlinFractalRigidMulti(x, y, z); 842 | default: 843 | return 0; 844 | } 845 | } 846 | 847 | private float SinglePerlinFractalFBM(float x, float y, float z) { 848 | int seed = m_seed; 849 | float sum = SinglePerlin(seed, x, y, z); 850 | float amp = 1; 851 | 852 | for (int i = 1; i < m_octaves; i++) { 853 | x *= m_lacunarity; 854 | y *= m_lacunarity; 855 | z *= m_lacunarity; 856 | 857 | amp *= m_gain; 858 | sum += SinglePerlin(++seed, x, y, z) * amp; 859 | } 860 | 861 | return sum * m_fractalBounding; 862 | } 863 | 864 | private float SinglePerlinFractalBillow(float x, float y, float z) { 865 | int seed = m_seed; 866 | float sum = Math.abs(SinglePerlin(seed, x, y, z)) * 2 - 1; 867 | float amp = 1; 868 | 869 | for (int i = 1; i < m_octaves; i++) { 870 | x *= m_lacunarity; 871 | y *= m_lacunarity; 872 | z *= m_lacunarity; 873 | 874 | amp *= m_gain; 875 | sum += (Math.abs(SinglePerlin(++seed, x, y, z)) * 2 - 1) * amp; 876 | } 877 | 878 | return sum * m_fractalBounding; 879 | } 880 | 881 | private float SinglePerlinFractalRigidMulti(float x, float y, float z) { 882 | int seed = m_seed; 883 | float sum = 1 - Math.abs(SinglePerlin(seed, x, y, z)); 884 | float amp = 1; 885 | 886 | for (int i = 1; i < m_octaves; i++) { 887 | x *= m_lacunarity; 888 | y *= m_lacunarity; 889 | z *= m_lacunarity; 890 | 891 | amp *= m_gain; 892 | sum -= (1 - Math.abs(SinglePerlin(++seed, x, y, z))) * amp; 893 | } 894 | 895 | return sum; 896 | } 897 | 898 | public float GetPerlin(float x, float y, float z) { 899 | return SinglePerlin(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); 900 | } 901 | 902 | private float SinglePerlin(int seed, float x, float y, float z) { 903 | int x0 = FastFloor(x); 904 | int y0 = FastFloor(y); 905 | int z0 = FastFloor(z); 906 | int x1 = x0 + 1; 907 | int y1 = y0 + 1; 908 | int z1 = z0 + 1; 909 | 910 | float xs, ys, zs; 911 | switch (m_interp) { 912 | default: 913 | case Linear: 914 | xs = x - x0; 915 | ys = y - y0; 916 | zs = z - z0; 917 | break; 918 | case Hermite: 919 | xs = InterpHermiteFunc(x - x0); 920 | ys = InterpHermiteFunc(y - y0); 921 | zs = InterpHermiteFunc(z - z0); 922 | break; 923 | case Quintic: 924 | xs = InterpQuinticFunc(x - x0); 925 | ys = InterpQuinticFunc(y - y0); 926 | zs = InterpQuinticFunc(z - z0); 927 | break; 928 | } 929 | 930 | float xd0 = x - x0; 931 | float yd0 = y - y0; 932 | float zd0 = z - z0; 933 | float xd1 = xd0 - 1; 934 | float yd1 = yd0 - 1; 935 | float zd1 = zd0 - 1; 936 | 937 | float xf00 = Lerp(GradCoord3D(seed, x0, y0, z0, xd0, yd0, zd0), GradCoord3D(seed, x1, y0, z0, xd1, yd0, zd0), xs); 938 | float xf10 = Lerp(GradCoord3D(seed, x0, y1, z0, xd0, yd1, zd0), GradCoord3D(seed, x1, y1, z0, xd1, yd1, zd0), xs); 939 | float xf01 = Lerp(GradCoord3D(seed, x0, y0, z1, xd0, yd0, zd1), GradCoord3D(seed, x1, y0, z1, xd1, yd0, zd1), xs); 940 | float xf11 = Lerp(GradCoord3D(seed, x0, y1, z1, xd0, yd1, zd1), GradCoord3D(seed, x1, y1, z1, xd1, yd1, zd1), xs); 941 | 942 | float yf0 = Lerp(xf00, xf10, ys); 943 | float yf1 = Lerp(xf01, xf11, ys); 944 | 945 | return Lerp(yf0, yf1, zs); 946 | } 947 | 948 | public float GetPerlinFractal(float x, float y) { 949 | x *= m_frequency; 950 | y *= m_frequency; 951 | 952 | switch (m_fractalType) { 953 | case FBM: 954 | return SinglePerlinFractalFBM(x, y); 955 | case Billow: 956 | return SinglePerlinFractalBillow(x, y); 957 | case RigidMulti: 958 | return SinglePerlinFractalRigidMulti(x, y); 959 | default: 960 | return 0; 961 | } 962 | } 963 | 964 | private float SinglePerlinFractalFBM(float x, float y) { 965 | int seed = m_seed; 966 | float sum = SinglePerlin(seed, x, y); 967 | float amp = 1; 968 | 969 | for (int i = 1; i < m_octaves; i++) { 970 | x *= m_lacunarity; 971 | y *= m_lacunarity; 972 | 973 | amp *= m_gain; 974 | sum += SinglePerlin(++seed, x, y) * amp; 975 | } 976 | 977 | return sum * m_fractalBounding; 978 | } 979 | 980 | private float SinglePerlinFractalBillow(float x, float y) { 981 | int seed = m_seed; 982 | float sum = Math.abs(SinglePerlin(seed, x, y)) * 2 - 1; 983 | float amp = 1; 984 | 985 | for (int i = 1; i < m_octaves; i++) { 986 | x *= m_lacunarity; 987 | y *= m_lacunarity; 988 | 989 | amp *= m_gain; 990 | sum += (Math.abs(SinglePerlin(++seed, x, y)) * 2 - 1) * amp; 991 | } 992 | 993 | return sum * m_fractalBounding; 994 | } 995 | 996 | private float SinglePerlinFractalRigidMulti(float x, float y) { 997 | int seed = m_seed; 998 | float sum = 1 - Math.abs(SinglePerlin(seed, x, y)); 999 | float amp = 1; 1000 | 1001 | for (int i = 1; i < m_octaves; i++) { 1002 | x *= m_lacunarity; 1003 | y *= m_lacunarity; 1004 | 1005 | amp *= m_gain; 1006 | sum -= (1 - Math.abs(SinglePerlin(++seed, x, y))) * amp; 1007 | } 1008 | 1009 | return sum; 1010 | } 1011 | 1012 | public float GetPerlin(float x, float y) { 1013 | return SinglePerlin(m_seed, x * m_frequency, y * m_frequency); 1014 | } 1015 | 1016 | private float SinglePerlin(int seed, float x, float y) { 1017 | int x0 = FastFloor(x); 1018 | int y0 = FastFloor(y); 1019 | int x1 = x0 + 1; 1020 | int y1 = y0 + 1; 1021 | 1022 | float xs, ys; 1023 | switch (m_interp) { 1024 | default: 1025 | case Linear: 1026 | xs = x - x0; 1027 | ys = y - y0; 1028 | break; 1029 | case Hermite: 1030 | xs = InterpHermiteFunc(x - x0); 1031 | ys = InterpHermiteFunc(y - y0); 1032 | break; 1033 | case Quintic: 1034 | xs = InterpQuinticFunc(x - x0); 1035 | ys = InterpQuinticFunc(y - y0); 1036 | break; 1037 | } 1038 | 1039 | float xd0 = x - x0; 1040 | float yd0 = y - y0; 1041 | float xd1 = xd0 - 1; 1042 | float yd1 = yd0 - 1; 1043 | 1044 | float xf0 = Lerp(GradCoord2D(seed, x0, y0, xd0, yd0), GradCoord2D(seed, x1, y0, xd1, yd0), xs); 1045 | float xf1 = Lerp(GradCoord2D(seed, x0, y1, xd0, yd1), GradCoord2D(seed, x1, y1, xd1, yd1), xs); 1046 | 1047 | return Lerp(xf0, xf1, ys); 1048 | } 1049 | 1050 | // Simplex Noise 1051 | public float GetSimplexFractal(float x, float y, float z) { 1052 | x *= m_frequency; 1053 | y *= m_frequency; 1054 | z *= m_frequency; 1055 | 1056 | switch (m_fractalType) { 1057 | case FBM: 1058 | return SingleSimplexFractalFBM(x, y, z); 1059 | case Billow: 1060 | return SingleSimplexFractalBillow(x, y, z); 1061 | case RigidMulti: 1062 | return SingleSimplexFractalRigidMulti(x, y, z); 1063 | default: 1064 | return 0; 1065 | } 1066 | } 1067 | 1068 | private float SingleSimplexFractalFBM(float x, float y, float z) { 1069 | int seed = m_seed; 1070 | float sum = SingleSimplex(seed, x, y, z); 1071 | float amp = 1; 1072 | 1073 | for (int i = 1; i < m_octaves; i++) { 1074 | x *= m_lacunarity; 1075 | y *= m_lacunarity; 1076 | z *= m_lacunarity; 1077 | 1078 | amp *= m_gain; 1079 | sum += SingleSimplex(++seed, x, y, z) * amp; 1080 | } 1081 | 1082 | return sum * m_fractalBounding; 1083 | } 1084 | 1085 | private float SingleSimplexFractalBillow(float x, float y, float z) { 1086 | int seed = m_seed; 1087 | float sum = Math.abs(SingleSimplex(seed, x, y, z)) * 2 - 1; 1088 | float amp = 1; 1089 | 1090 | for (int i = 1; i < m_octaves; i++) { 1091 | x *= m_lacunarity; 1092 | y *= m_lacunarity; 1093 | z *= m_lacunarity; 1094 | 1095 | amp *= m_gain; 1096 | sum += (Math.abs(SingleSimplex(++seed, x, y, z)) * 2 - 1) * amp; 1097 | } 1098 | 1099 | return sum * m_fractalBounding; 1100 | } 1101 | 1102 | private float SingleSimplexFractalRigidMulti(float x, float y, float z) { 1103 | int seed = m_seed; 1104 | float sum = 1 - Math.abs(SingleSimplex(seed, x, y, z)); 1105 | float amp = 1; 1106 | 1107 | for (int i = 1; i < m_octaves; i++) { 1108 | x *= m_lacunarity; 1109 | y *= m_lacunarity; 1110 | z *= m_lacunarity; 1111 | 1112 | amp *= m_gain; 1113 | sum -= (1 - Math.abs(SingleSimplex(++seed, x, y, z))) * amp; 1114 | } 1115 | 1116 | return sum; 1117 | } 1118 | 1119 | public float GetSimplex(float x, float y, float z) { 1120 | return SingleSimplex(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); 1121 | } 1122 | 1123 | private final static float F3 = (float) (1.0 / 3.0); 1124 | private final static float G3 = (float) (1.0 / 6.0); 1125 | private final static float G33 = G3 * 3 - 1; 1126 | 1127 | private float SingleSimplex(int seed, float x, float y, float z) { 1128 | float t = (x + y + z) * F3; 1129 | int i = FastFloor(x + t); 1130 | int j = FastFloor(y + t); 1131 | int k = FastFloor(z + t); 1132 | 1133 | t = (i + j + k) * G3; 1134 | float x0 = x - (i - t); 1135 | float y0 = y - (j - t); 1136 | float z0 = z - (k - t); 1137 | 1138 | int i1, j1, k1; 1139 | int i2, j2, k2; 1140 | 1141 | if (x0 >= y0) { 1142 | if (y0 >= z0) { 1143 | i1 = 1; 1144 | j1 = 0; 1145 | k1 = 0; 1146 | i2 = 1; 1147 | j2 = 1; 1148 | k2 = 0; 1149 | } else if (x0 >= z0) { 1150 | i1 = 1; 1151 | j1 = 0; 1152 | k1 = 0; 1153 | i2 = 1; 1154 | j2 = 0; 1155 | k2 = 1; 1156 | } else // x0 < z0 1157 | { 1158 | i1 = 0; 1159 | j1 = 0; 1160 | k1 = 1; 1161 | i2 = 1; 1162 | j2 = 0; 1163 | k2 = 1; 1164 | } 1165 | } else // x0 < y0 1166 | { 1167 | if (y0 < z0) { 1168 | i1 = 0; 1169 | j1 = 0; 1170 | k1 = 1; 1171 | i2 = 0; 1172 | j2 = 1; 1173 | k2 = 1; 1174 | } else if (x0 < z0) { 1175 | i1 = 0; 1176 | j1 = 1; 1177 | k1 = 0; 1178 | i2 = 0; 1179 | j2 = 1; 1180 | k2 = 1; 1181 | } else // x0 >= z0 1182 | { 1183 | i1 = 0; 1184 | j1 = 1; 1185 | k1 = 0; 1186 | i2 = 1; 1187 | j2 = 1; 1188 | k2 = 0; 1189 | } 1190 | } 1191 | 1192 | float x1 = x0 - i1 + G3; 1193 | float y1 = y0 - j1 + G3; 1194 | float z1 = z0 - k1 + G3; 1195 | float x2 = x0 - i2 + F3; 1196 | float y2 = y0 - j2 + F3; 1197 | float z2 = z0 - k2 + F3; 1198 | float x3 = x0 + G33; 1199 | float y3 = y0 + G33; 1200 | float z3 = z0 + G33; 1201 | 1202 | float n0, n1, n2, n3; 1203 | 1204 | t = (float) 0.6 - x0 * x0 - y0 * y0 - z0 * z0; 1205 | if (t < 0) n0 = 0; 1206 | else { 1207 | t *= t; 1208 | n0 = t * t * GradCoord3D(seed, i, j, k, x0, y0, z0); 1209 | } 1210 | 1211 | t = (float) 0.6 - x1 * x1 - y1 * y1 - z1 * z1; 1212 | if (t < 0) n1 = 0; 1213 | else { 1214 | t *= t; 1215 | n1 = t * t * GradCoord3D(seed, i + i1, j + j1, k + k1, x1, y1, z1); 1216 | } 1217 | 1218 | t = (float) 0.6 - x2 * x2 - y2 * y2 - z2 * z2; 1219 | if (t < 0) n2 = 0; 1220 | else { 1221 | t *= t; 1222 | n2 = t * t * GradCoord3D(seed, i + i2, j + j2, k + k2, x2, y2, z2); 1223 | } 1224 | 1225 | t = (float) 0.6 - x3 * x3 - y3 * y3 - z3 * z3; 1226 | if (t < 0) n3 = 0; 1227 | else { 1228 | t *= t; 1229 | n3 = t * t * GradCoord3D(seed, i + 1, j + 1, k + 1, x3, y3, z3); 1230 | } 1231 | 1232 | return 32 * (n0 + n1 + n2 + n3); 1233 | } 1234 | 1235 | public float GetSimplexFractal(float x, float y) { 1236 | x *= m_frequency; 1237 | y *= m_frequency; 1238 | 1239 | switch (m_fractalType) { 1240 | case FBM: 1241 | return SingleSimplexFractalFBM(x, y); 1242 | case Billow: 1243 | return SingleSimplexFractalBillow(x, y); 1244 | case RigidMulti: 1245 | return SingleSimplexFractalRigidMulti(x, y); 1246 | default: 1247 | return 0; 1248 | } 1249 | } 1250 | 1251 | private float SingleSimplexFractalFBM(float x, float y) { 1252 | int seed = m_seed; 1253 | float sum = SingleSimplex(seed, x, y); 1254 | float amp = 1; 1255 | 1256 | for (int i = 1; i < m_octaves; i++) { 1257 | x *= m_lacunarity; 1258 | y *= m_lacunarity; 1259 | 1260 | amp *= m_gain; 1261 | sum += SingleSimplex(++seed, x, y) * amp; 1262 | } 1263 | 1264 | return sum * m_fractalBounding; 1265 | } 1266 | 1267 | private float SingleSimplexFractalBillow(float x, float y) { 1268 | int seed = m_seed; 1269 | float sum = Math.abs(SingleSimplex(seed, x, y)) * 2 - 1; 1270 | float amp = 1; 1271 | 1272 | for (int i = 1; i < m_octaves; i++) { 1273 | x *= m_lacunarity; 1274 | y *= m_lacunarity; 1275 | 1276 | amp *= m_gain; 1277 | sum += (Math.abs(SingleSimplex(++seed, x, y)) * 2 - 1) * amp; 1278 | } 1279 | 1280 | return sum * m_fractalBounding; 1281 | } 1282 | 1283 | private float SingleSimplexFractalRigidMulti(float x, float y) { 1284 | int seed = m_seed; 1285 | float sum = 1 - Math.abs(SingleSimplex(seed, x, y)); 1286 | float amp = 1; 1287 | 1288 | for (int i = 1; i < m_octaves; i++) { 1289 | x *= m_lacunarity; 1290 | y *= m_lacunarity; 1291 | 1292 | amp *= m_gain; 1293 | sum -= (1 - Math.abs(SingleSimplex(++seed, x, y))) * amp; 1294 | } 1295 | 1296 | return sum; 1297 | } 1298 | 1299 | public float GetSimplex(float x, float y) { 1300 | return SingleSimplex(m_seed, x * m_frequency, y * m_frequency); 1301 | } 1302 | 1303 | //private final static float F2 = (float) (1.0 / 2.0); 1304 | //private final static float G2 = (float) (1.0 / 4.0); 1305 | 1306 | private final static float SQRT3 = (float) 1.7320508075688772935274463415059; 1307 | private final static float F2 = 0.5f * (SQRT3 - 1.0f); 1308 | private final static float G2 = (3.0f - SQRT3) / 6.0f; 1309 | 1310 | private float SingleSimplex(int seed, float x, float y) { 1311 | float t = (x + y) * F2; 1312 | int i = FastFloor(x + t); 1313 | int j = FastFloor(y + t); 1314 | 1315 | t = (i + j) * G2; 1316 | float X0 = i - t; 1317 | float Y0 = j - t; 1318 | 1319 | float x0 = x - X0; 1320 | float y0 = y - Y0; 1321 | 1322 | int i1, j1; 1323 | if (x0 > y0) { 1324 | i1 = 1; 1325 | j1 = 0; 1326 | } else { 1327 | i1 = 0; 1328 | j1 = 1; 1329 | } 1330 | 1331 | float x1 = x0 - i1 + G2; 1332 | float y1 = y0 - j1 + G2; 1333 | float x2 = x0 - 1 + 2*G2; 1334 | float y2 = y0 - 1 + 2*G2; 1335 | 1336 | float n0, n1, n2; 1337 | 1338 | t = (float) 0.5 - x0 * x0 - y0 * y0; 1339 | if (t < 0) n0 = 0; 1340 | else { 1341 | t *= t; 1342 | n0 = t * t * GradCoord2D(seed, i, j, x0, y0); 1343 | } 1344 | 1345 | t = (float) 0.5 - x1 * x1 - y1 * y1; 1346 | if (t < 0) n1 = 0; 1347 | else { 1348 | t *= t; 1349 | n1 = t * t * GradCoord2D(seed, i + i1, j + j1, x1, y1); 1350 | } 1351 | 1352 | t = (float) 0.5 - x2 * x2 - y2 * y2; 1353 | if (t < 0) n2 = 0; 1354 | else { 1355 | t *= t; 1356 | n2 = t * t * GradCoord2D(seed, i + 1, j + 1, x2, y2); 1357 | } 1358 | 1359 | return 50 * (n0 + n1 + n2); 1360 | } 1361 | 1362 | public float GetSimplex(float x, float y, float z, float w) { 1363 | return SingleSimplex(m_seed, x * m_frequency, y * m_frequency, z * m_frequency, w * m_frequency); 1364 | } 1365 | 1366 | private static final byte[] SIMPLEX_4D = 1367 | { 1368 | 0, 1, 2, 3, 0, 1, 3, 2, 0, 0, 0, 0, 0, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 1369 | 0, 2, 1, 3, 0, 0, 0, 0, 0, 3, 1, 2, 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 0, 1370 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1371 | 1, 2, 0, 3, 0, 0, 0, 0, 1, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 1, 2, 3, 1, 0, 1372 | 1, 0, 2, 3, 1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 1, 0, 0, 0, 0, 2, 1, 3, 0, 1373 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1374 | 2, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2, 3, 0, 2, 1, 0, 0, 0, 0, 3, 1, 2, 0, 1375 | 2, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 2, 0, 0, 0, 0, 3, 2, 0, 1, 3, 2, 1, 0 1376 | }; 1377 | 1378 | private final static float F4 = (float) ((2.23606797 - 1.0) / 4.0); 1379 | private final static float G4 = (float) ((5.0 - 2.23606797) / 20.0); 1380 | 1381 | private float SingleSimplex(int seed, float x, float y, float z, float w) { 1382 | float n0, n1, n2, n3, n4; 1383 | float t = (x + y + z + w) * F4; 1384 | int i = FastFloor(x + t); 1385 | int j = FastFloor(y + t); 1386 | int k = FastFloor(z + t); 1387 | int l = FastFloor(w + t); 1388 | t = (i + j + k + l) * G4; 1389 | float X0 = i - t; 1390 | float Y0 = j - t; 1391 | float Z0 = k - t; 1392 | float W0 = l - t; 1393 | float x0 = x - X0; 1394 | float y0 = y - Y0; 1395 | float z0 = z - Z0; 1396 | float w0 = w - W0; 1397 | 1398 | int c = (x0 > y0) ? 32 : 0; 1399 | c += (x0 > z0) ? 16 : 0; 1400 | c += (y0 > z0) ? 8 : 0; 1401 | c += (x0 > w0) ? 4 : 0; 1402 | c += (y0 > w0) ? 2 : 0; 1403 | c += (z0 > w0) ? 1 : 0; 1404 | c <<= 2; 1405 | 1406 | int i1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; 1407 | int i2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; 1408 | int i3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0; 1409 | int j1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; 1410 | int j2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; 1411 | int j3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0; 1412 | int k1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; 1413 | int k2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; 1414 | int k3 = SIMPLEX_4D[c++] >= 1 ? 1 : 0; 1415 | int l1 = SIMPLEX_4D[c] >= 3 ? 1 : 0; 1416 | int l2 = SIMPLEX_4D[c] >= 2 ? 1 : 0; 1417 | int l3 = SIMPLEX_4D[c] >= 1 ? 1 : 0; 1418 | 1419 | float x1 = x0 - i1 + G4; 1420 | float y1 = y0 - j1 + G4; 1421 | float z1 = z0 - k1 + G4; 1422 | float w1 = w0 - l1 + G4; 1423 | float x2 = x0 - i2 + 2 * G4; 1424 | float y2 = y0 - j2 + 2 * G4; 1425 | float z2 = z0 - k2 + 2 * G4; 1426 | float w2 = w0 - l2 + 2 * G4; 1427 | float x3 = x0 - i3 + 3 * G4; 1428 | float y3 = y0 - j3 + 3 * G4; 1429 | float z3 = z0 - k3 + 3 * G4; 1430 | float w3 = w0 - l3 + 3 * G4; 1431 | float x4 = x0 - 1 + 4 * G4; 1432 | float y4 = y0 - 1 + 4 * G4; 1433 | float z4 = z0 - 1 + 4 * G4; 1434 | float w4 = w0 - 1 + 4 * G4; 1435 | 1436 | t = (float) 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; 1437 | if (t < 0) n0 = 0; 1438 | else { 1439 | t *= t; 1440 | n0 = t * t * GradCoord4D(seed, i, j, k, l, x0, y0, z0, w0); 1441 | } 1442 | t = (float) 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; 1443 | if (t < 0) n1 = 0; 1444 | else { 1445 | t *= t; 1446 | n1 = t * t * GradCoord4D(seed, i + i1, j + j1, k + k1, l + l1, x1, y1, z1, w1); 1447 | } 1448 | t = (float) 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; 1449 | if (t < 0) n2 = 0; 1450 | else { 1451 | t *= t; 1452 | n2 = t * t * GradCoord4D(seed, i + i2, j + j2, k + k2, l + l2, x2, y2, z2, w2); 1453 | } 1454 | t = (float) 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; 1455 | if (t < 0) n3 = 0; 1456 | else { 1457 | t *= t; 1458 | n3 = t * t * GradCoord4D(seed, i + i3, j + j3, k + k3, l + l3, x3, y3, z3, w3); 1459 | } 1460 | t = (float) 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; 1461 | if (t < 0) n4 = 0; 1462 | else { 1463 | t *= t; 1464 | n4 = t * t * GradCoord4D(seed, i + 1, j + 1, k + 1, l + 1, x4, y4, z4, w4); 1465 | } 1466 | 1467 | return 27 * (n0 + n1 + n2 + n3 + n4); 1468 | } 1469 | 1470 | // Cubic Noise 1471 | public float GetCubicFractal(float x, float y, float z) { 1472 | x *= m_frequency; 1473 | y *= m_frequency; 1474 | z *= m_frequency; 1475 | 1476 | switch (m_fractalType) { 1477 | case FBM: 1478 | return SingleCubicFractalFBM(x, y, z); 1479 | case Billow: 1480 | return SingleCubicFractalBillow(x, y, z); 1481 | case RigidMulti: 1482 | return SingleCubicFractalRigidMulti(x, y, z); 1483 | default: 1484 | return 0; 1485 | } 1486 | } 1487 | 1488 | private float SingleCubicFractalFBM(float x, float y, float z) { 1489 | int seed = m_seed; 1490 | float sum = SingleCubic(seed, x, y, z); 1491 | float amp = 1; 1492 | int i = 0; 1493 | 1494 | while (++i < m_octaves) { 1495 | x *= m_lacunarity; 1496 | y *= m_lacunarity; 1497 | z *= m_lacunarity; 1498 | 1499 | amp *= m_gain; 1500 | sum += SingleCubic(++seed, x, y, z) * amp; 1501 | } 1502 | 1503 | return sum * m_fractalBounding; 1504 | } 1505 | 1506 | private float SingleCubicFractalBillow(float x, float y, float z) { 1507 | int seed = m_seed; 1508 | float sum = Math.abs(SingleCubic(seed, x, y, z)) * 2 - 1; 1509 | float amp = 1; 1510 | int i = 0; 1511 | 1512 | while (++i < m_octaves) { 1513 | x *= m_lacunarity; 1514 | y *= m_lacunarity; 1515 | z *= m_lacunarity; 1516 | 1517 | amp *= m_gain; 1518 | sum += (Math.abs(SingleCubic(++seed, x, y, z)) * 2 - 1) * amp; 1519 | } 1520 | 1521 | return sum * m_fractalBounding; 1522 | } 1523 | 1524 | private float SingleCubicFractalRigidMulti(float x, float y, float z) { 1525 | int seed = m_seed; 1526 | float sum = 1 - Math.abs(SingleCubic(seed, x, y, z)); 1527 | float amp = 1; 1528 | int i = 0; 1529 | 1530 | while (++i < m_octaves) { 1531 | x *= m_lacunarity; 1532 | y *= m_lacunarity; 1533 | z *= m_lacunarity; 1534 | 1535 | amp *= m_gain; 1536 | sum -= (1 - Math.abs(SingleCubic(++seed, x, y, z))) * amp; 1537 | } 1538 | 1539 | return sum; 1540 | } 1541 | 1542 | public float GetCubic(float x, float y, float z) { 1543 | return SingleCubic(m_seed, x * m_frequency, y * m_frequency, z * m_frequency); 1544 | } 1545 | 1546 | private final static float CUBIC_3D_BOUNDING = 1 / (float) (1.5 * 1.5 * 1.5); 1547 | 1548 | private float SingleCubic(int seed, float x, float y, float z) { 1549 | int x1 = FastFloor(x); 1550 | int y1 = FastFloor(y); 1551 | int z1 = FastFloor(z); 1552 | 1553 | int x0 = x1 - 1; 1554 | int y0 = y1 - 1; 1555 | int z0 = z1 - 1; 1556 | int x2 = x1 + 1; 1557 | int y2 = y1 + 1; 1558 | int z2 = z1 + 1; 1559 | int x3 = x1 + 2; 1560 | int y3 = y1 + 2; 1561 | int z3 = z1 + 2; 1562 | 1563 | float xs = x - (float) x1; 1564 | float ys = y - (float) y1; 1565 | float zs = z - (float) z1; 1566 | 1567 | return CubicLerp( 1568 | CubicLerp( 1569 | CubicLerp(ValCoord3D(seed, x0, y0, z0), ValCoord3D(seed, x1, y0, z0), ValCoord3D(seed, x2, y0, z0), ValCoord3D(seed, x3, y0, z0), xs), 1570 | CubicLerp(ValCoord3D(seed, x0, y1, z0), ValCoord3D(seed, x1, y1, z0), ValCoord3D(seed, x2, y1, z0), ValCoord3D(seed, x3, y1, z0), xs), 1571 | CubicLerp(ValCoord3D(seed, x0, y2, z0), ValCoord3D(seed, x1, y2, z0), ValCoord3D(seed, x2, y2, z0), ValCoord3D(seed, x3, y2, z0), xs), 1572 | CubicLerp(ValCoord3D(seed, x0, y3, z0), ValCoord3D(seed, x1, y3, z0), ValCoord3D(seed, x2, y3, z0), ValCoord3D(seed, x3, y3, z0), xs), 1573 | ys), 1574 | CubicLerp( 1575 | CubicLerp(ValCoord3D(seed, x0, y0, z1), ValCoord3D(seed, x1, y0, z1), ValCoord3D(seed, x2, y0, z1), ValCoord3D(seed, x3, y0, z1), xs), 1576 | CubicLerp(ValCoord3D(seed, x0, y1, z1), ValCoord3D(seed, x1, y1, z1), ValCoord3D(seed, x2, y1, z1), ValCoord3D(seed, x3, y1, z1), xs), 1577 | CubicLerp(ValCoord3D(seed, x0, y2, z1), ValCoord3D(seed, x1, y2, z1), ValCoord3D(seed, x2, y2, z1), ValCoord3D(seed, x3, y2, z1), xs), 1578 | CubicLerp(ValCoord3D(seed, x0, y3, z1), ValCoord3D(seed, x1, y3, z1), ValCoord3D(seed, x2, y3, z1), ValCoord3D(seed, x3, y3, z1), xs), 1579 | ys), 1580 | CubicLerp( 1581 | CubicLerp(ValCoord3D(seed, x0, y0, z2), ValCoord3D(seed, x1, y0, z2), ValCoord3D(seed, x2, y0, z2), ValCoord3D(seed, x3, y0, z2), xs), 1582 | CubicLerp(ValCoord3D(seed, x0, y1, z2), ValCoord3D(seed, x1, y1, z2), ValCoord3D(seed, x2, y1, z2), ValCoord3D(seed, x3, y1, z2), xs), 1583 | CubicLerp(ValCoord3D(seed, x0, y2, z2), ValCoord3D(seed, x1, y2, z2), ValCoord3D(seed, x2, y2, z2), ValCoord3D(seed, x3, y2, z2), xs), 1584 | CubicLerp(ValCoord3D(seed, x0, y3, z2), ValCoord3D(seed, x1, y3, z2), ValCoord3D(seed, x2, y3, z2), ValCoord3D(seed, x3, y3, z2), xs), 1585 | ys), 1586 | CubicLerp( 1587 | CubicLerp(ValCoord3D(seed, x0, y0, z3), ValCoord3D(seed, x1, y0, z3), ValCoord3D(seed, x2, y0, z3), ValCoord3D(seed, x3, y0, z3), xs), 1588 | CubicLerp(ValCoord3D(seed, x0, y1, z3), ValCoord3D(seed, x1, y1, z3), ValCoord3D(seed, x2, y1, z3), ValCoord3D(seed, x3, y1, z3), xs), 1589 | CubicLerp(ValCoord3D(seed, x0, y2, z3), ValCoord3D(seed, x1, y2, z3), ValCoord3D(seed, x2, y2, z3), ValCoord3D(seed, x3, y2, z3), xs), 1590 | CubicLerp(ValCoord3D(seed, x0, y3, z3), ValCoord3D(seed, x1, y3, z3), ValCoord3D(seed, x2, y3, z3), ValCoord3D(seed, x3, y3, z3), xs), 1591 | ys), 1592 | zs) * CUBIC_3D_BOUNDING; 1593 | } 1594 | 1595 | 1596 | public float GetCubicFractal(float x, float y) { 1597 | x *= m_frequency; 1598 | y *= m_frequency; 1599 | 1600 | switch (m_fractalType) { 1601 | case FBM: 1602 | return SingleCubicFractalFBM(x, y); 1603 | case Billow: 1604 | return SingleCubicFractalBillow(x, y); 1605 | case RigidMulti: 1606 | return SingleCubicFractalRigidMulti(x, y); 1607 | default: 1608 | return 0; 1609 | } 1610 | } 1611 | 1612 | private float SingleCubicFractalFBM(float x, float y) { 1613 | int seed = m_seed; 1614 | float sum = SingleCubic(seed, x, y); 1615 | float amp = 1; 1616 | int i = 0; 1617 | 1618 | while (++i < m_octaves) { 1619 | x *= m_lacunarity; 1620 | y *= m_lacunarity; 1621 | 1622 | amp *= m_gain; 1623 | sum += SingleCubic(++seed, x, y) * amp; 1624 | } 1625 | 1626 | return sum * m_fractalBounding; 1627 | } 1628 | 1629 | private float SingleCubicFractalBillow(float x, float y) { 1630 | int seed = m_seed; 1631 | float sum = Math.abs(SingleCubic(seed, x, y)) * 2 - 1; 1632 | float amp = 1; 1633 | int i = 0; 1634 | 1635 | while (++i < m_octaves) { 1636 | x *= m_lacunarity; 1637 | y *= m_lacunarity; 1638 | 1639 | amp *= m_gain; 1640 | sum += (Math.abs(SingleCubic(++seed, x, y)) * 2 - 1) * amp; 1641 | } 1642 | 1643 | return sum * m_fractalBounding; 1644 | } 1645 | 1646 | private float SingleCubicFractalRigidMulti(float x, float y) { 1647 | int seed = m_seed; 1648 | float sum = 1 - Math.abs(SingleCubic(seed, x, y)); 1649 | float amp = 1; 1650 | int i = 0; 1651 | 1652 | while (++i < m_octaves) { 1653 | x *= m_lacunarity; 1654 | y *= m_lacunarity; 1655 | 1656 | amp *= m_gain; 1657 | sum -= (1 - Math.abs(SingleCubic(++seed, x, y))) * amp; 1658 | } 1659 | 1660 | return sum; 1661 | } 1662 | 1663 | public float GetCubic(float x, float y) { 1664 | x *= m_frequency; 1665 | y *= m_frequency; 1666 | 1667 | return SingleCubic(0, x, y); 1668 | } 1669 | 1670 | private final static float CUBIC_2D_BOUNDING = 1 / (float) (1.5 * 1.5); 1671 | 1672 | private float SingleCubic(int seed, float x, float y) { 1673 | int x1 = FastFloor(x); 1674 | int y1 = FastFloor(y); 1675 | 1676 | int x0 = x1 - 1; 1677 | int y0 = y1 - 1; 1678 | int x2 = x1 + 1; 1679 | int y2 = y1 + 1; 1680 | int x3 = x1 + 2; 1681 | int y3 = y1 + 2; 1682 | 1683 | float xs = x - (float) x1; 1684 | float ys = y - (float) y1; 1685 | 1686 | return CubicLerp( 1687 | CubicLerp(ValCoord2D(seed, x0, y0), ValCoord2D(seed, x1, y0), ValCoord2D(seed, x2, y0), ValCoord2D(seed, x3, y0), 1688 | xs), 1689 | CubicLerp(ValCoord2D(seed, x0, y1), ValCoord2D(seed, x1, y1), ValCoord2D(seed, x2, y1), ValCoord2D(seed, x3, y1), 1690 | xs), 1691 | CubicLerp(ValCoord2D(seed, x0, y2), ValCoord2D(seed, x1, y2), ValCoord2D(seed, x2, y2), ValCoord2D(seed, x3, y2), 1692 | xs), 1693 | CubicLerp(ValCoord2D(seed, x0, y3), ValCoord2D(seed, x1, y3), ValCoord2D(seed, x2, y3), ValCoord2D(seed, x3, y3), 1694 | xs), 1695 | ys) * CUBIC_2D_BOUNDING; 1696 | } 1697 | 1698 | // Cellular Noise 1699 | public float GetCellular(float x, float y, float z) { 1700 | x *= m_frequency; 1701 | y *= m_frequency; 1702 | z *= m_frequency; 1703 | 1704 | switch (m_cellularReturnType) { 1705 | case CellValue: 1706 | case NoiseLookup: 1707 | case Distance: 1708 | return SingleCellular(x, y, z); 1709 | default: 1710 | return SingleCellular2Edge(x, y, z); 1711 | } 1712 | } 1713 | 1714 | private float SingleCellular(float x, float y, float z) { 1715 | int xr = FastRound(x); 1716 | int yr = FastRound(y); 1717 | int zr = FastRound(z); 1718 | 1719 | float distance = 999999; 1720 | int xc = 0, yc = 0, zc = 0; 1721 | 1722 | switch (m_cellularDistanceFunction) { 1723 | case Euclidean: 1724 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1725 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1726 | for (int zi = zr - 1; zi <= zr + 1; zi++) { 1727 | Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; 1728 | 1729 | float vecX = xi - x + vec.x; 1730 | float vecY = yi - y + vec.y; 1731 | float vecZ = zi - z + vec.z; 1732 | 1733 | float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ; 1734 | 1735 | if (newDistance < distance) { 1736 | distance = newDistance; 1737 | xc = xi; 1738 | yc = yi; 1739 | zc = zi; 1740 | } 1741 | } 1742 | } 1743 | } 1744 | break; 1745 | case Manhattan: 1746 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1747 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1748 | for (int zi = zr - 1; zi <= zr + 1; zi++) { 1749 | Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; 1750 | 1751 | float vecX = xi - x + vec.x; 1752 | float vecY = yi - y + vec.y; 1753 | float vecZ = zi - z + vec.z; 1754 | 1755 | float newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ); 1756 | 1757 | if (newDistance < distance) { 1758 | distance = newDistance; 1759 | xc = xi; 1760 | yc = yi; 1761 | zc = zi; 1762 | } 1763 | } 1764 | } 1765 | } 1766 | break; 1767 | case Natural: 1768 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1769 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1770 | for (int zi = zr - 1; zi <= zr + 1; zi++) { 1771 | Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; 1772 | 1773 | float vecX = xi - x + vec.x; 1774 | float vecY = yi - y + vec.y; 1775 | float vecZ = zi - z + vec.z; 1776 | 1777 | float newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ); 1778 | 1779 | if (newDistance < distance) { 1780 | distance = newDistance; 1781 | xc = xi; 1782 | yc = yi; 1783 | zc = zi; 1784 | } 1785 | } 1786 | } 1787 | } 1788 | break; 1789 | } 1790 | 1791 | switch (m_cellularReturnType) { 1792 | case CellValue: 1793 | return ValCoord3D(0, xc, yc, zc); 1794 | 1795 | case NoiseLookup: 1796 | Float3 vec = CELL_3D[Hash3D(m_seed, xc, yc, zc) & 255]; 1797 | return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y, zc + vec.z); 1798 | 1799 | case Distance: 1800 | return distance - 1; 1801 | default: 1802 | return 0; 1803 | } 1804 | } 1805 | 1806 | private float SingleCellular2Edge(float x, float y, float z) { 1807 | int xr = FastRound(x); 1808 | int yr = FastRound(y); 1809 | int zr = FastRound(z); 1810 | 1811 | float distance = 999999; 1812 | float distance2 = 999999; 1813 | 1814 | switch (m_cellularDistanceFunction) { 1815 | case Euclidean: 1816 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1817 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1818 | for (int zi = zr - 1; zi <= zr + 1; zi++) { 1819 | Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; 1820 | 1821 | float vecX = xi - x + vec.x; 1822 | float vecY = yi - y + vec.y; 1823 | float vecZ = zi - z + vec.z; 1824 | 1825 | float newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ; 1826 | 1827 | distance2 = Math.max(Math.min(distance2, newDistance), distance); 1828 | distance = Math.min(distance, newDistance); 1829 | } 1830 | } 1831 | } 1832 | break; 1833 | case Manhattan: 1834 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1835 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1836 | for (int zi = zr - 1; zi <= zr + 1; zi++) { 1837 | Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; 1838 | 1839 | float vecX = xi - x + vec.x; 1840 | float vecY = yi - y + vec.y; 1841 | float vecZ = zi - z + vec.z; 1842 | 1843 | float newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ); 1844 | 1845 | distance2 = Math.max(Math.min(distance2, newDistance), distance); 1846 | distance = Math.min(distance, newDistance); 1847 | } 1848 | } 1849 | } 1850 | break; 1851 | case Natural: 1852 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1853 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1854 | for (int zi = zr - 1; zi <= zr + 1; zi++) { 1855 | Float3 vec = CELL_3D[Hash3D(m_seed, xi, yi, zi) & 255]; 1856 | 1857 | float vecX = xi - x + vec.x; 1858 | float vecY = yi - y + vec.y; 1859 | float vecZ = zi - z + vec.z; 1860 | 1861 | float newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ); 1862 | 1863 | distance2 = Math.max(Math.min(distance2, newDistance), distance); 1864 | distance = Math.min(distance, newDistance); 1865 | } 1866 | } 1867 | } 1868 | break; 1869 | default: 1870 | break; 1871 | } 1872 | 1873 | switch (m_cellularReturnType) { 1874 | case Distance2: 1875 | return distance2 - 1; 1876 | case Distance2Add: 1877 | return distance2 + distance - 1; 1878 | case Distance2Sub: 1879 | return distance2 - distance - 1; 1880 | case Distance2Mul: 1881 | return distance2 * distance - 1; 1882 | case Distance2Div: 1883 | return distance / distance2 - 1; 1884 | default: 1885 | return 0; 1886 | } 1887 | } 1888 | 1889 | public float GetCellular(float x, float y) { 1890 | x *= m_frequency; 1891 | y *= m_frequency; 1892 | 1893 | switch (m_cellularReturnType) { 1894 | case CellValue: 1895 | case NoiseLookup: 1896 | case Distance: 1897 | return SingleCellular(x, y); 1898 | default: 1899 | return SingleCellular2Edge(x, y); 1900 | } 1901 | } 1902 | 1903 | private float SingleCellular(float x, float y) { 1904 | int xr = FastRound(x); 1905 | int yr = FastRound(y); 1906 | 1907 | float distance = 999999; 1908 | int xc = 0, yc = 0; 1909 | 1910 | switch (m_cellularDistanceFunction) { 1911 | default: 1912 | case Euclidean: 1913 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1914 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1915 | Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; 1916 | 1917 | float vecX = xi - x + vec.x; 1918 | float vecY = yi - y + vec.y; 1919 | 1920 | float newDistance = vecX * vecX + vecY * vecY; 1921 | 1922 | if (newDistance < distance) { 1923 | distance = newDistance; 1924 | xc = xi; 1925 | yc = yi; 1926 | } 1927 | } 1928 | } 1929 | break; 1930 | case Manhattan: 1931 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1932 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1933 | Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; 1934 | 1935 | float vecX = xi - x + vec.x; 1936 | float vecY = yi - y + vec.y; 1937 | 1938 | float newDistance = (Math.abs(vecX) + Math.abs(vecY)); 1939 | 1940 | if (newDistance < distance) { 1941 | distance = newDistance; 1942 | xc = xi; 1943 | yc = yi; 1944 | } 1945 | } 1946 | } 1947 | break; 1948 | case Natural: 1949 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1950 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1951 | Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; 1952 | 1953 | float vecX = xi - x + vec.x; 1954 | float vecY = yi - y + vec.y; 1955 | 1956 | float newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY); 1957 | 1958 | if (newDistance < distance) { 1959 | distance = newDistance; 1960 | xc = xi; 1961 | yc = yi; 1962 | } 1963 | } 1964 | } 1965 | break; 1966 | } 1967 | 1968 | switch (m_cellularReturnType) { 1969 | case CellValue: 1970 | return ValCoord2D(0, xc, yc); 1971 | 1972 | case NoiseLookup: 1973 | Float2 vec = CELL_2D[Hash2D(m_seed, xc, yc) & 255]; 1974 | return m_cellularNoiseLookup.GetNoise(xc + vec.x, yc + vec.y); 1975 | 1976 | case Distance: 1977 | return distance - 1; 1978 | default: 1979 | return 0; 1980 | } 1981 | } 1982 | 1983 | private float SingleCellular2Edge(float x, float y) { 1984 | int xr = FastRound(x); 1985 | int yr = FastRound(y); 1986 | 1987 | float distance = 999999; 1988 | float distance2 = 999999; 1989 | 1990 | switch (m_cellularDistanceFunction) { 1991 | default: 1992 | case Euclidean: 1993 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 1994 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 1995 | Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; 1996 | 1997 | float vecX = xi - x + vec.x; 1998 | float vecY = yi - y + vec.y; 1999 | 2000 | float newDistance = vecX * vecX + vecY * vecY; 2001 | 2002 | distance2 = Math.max(Math.min(distance2, newDistance), distance); 2003 | distance = Math.min(distance, newDistance); 2004 | } 2005 | } 2006 | break; 2007 | case Manhattan: 2008 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 2009 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 2010 | Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; 2011 | 2012 | float vecX = xi - x + vec.x; 2013 | float vecY = yi - y + vec.y; 2014 | 2015 | float newDistance = Math.abs(vecX) + Math.abs(vecY); 2016 | 2017 | distance2 = Math.max(Math.min(distance2, newDistance), distance); 2018 | distance = Math.min(distance, newDistance); 2019 | } 2020 | } 2021 | break; 2022 | case Natural: 2023 | for (int xi = xr - 1; xi <= xr + 1; xi++) { 2024 | for (int yi = yr - 1; yi <= yr + 1; yi++) { 2025 | Float2 vec = CELL_2D[Hash2D(m_seed, xi, yi) & 255]; 2026 | 2027 | float vecX = xi - x + vec.x; 2028 | float vecY = yi - y + vec.y; 2029 | 2030 | float newDistance = (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY); 2031 | 2032 | distance2 = Math.max(Math.min(distance2, newDistance), distance); 2033 | distance = Math.min(distance, newDistance); 2034 | } 2035 | } 2036 | break; 2037 | } 2038 | 2039 | switch (m_cellularReturnType) { 2040 | case Distance2: 2041 | return distance2 - 1; 2042 | case Distance2Add: 2043 | return distance2 + distance - 1; 2044 | case Distance2Sub: 2045 | return distance2 - distance - 1; 2046 | case Distance2Mul: 2047 | return distance2 * distance - 1; 2048 | case Distance2Div: 2049 | return distance / distance2 - 1; 2050 | default: 2051 | return 0; 2052 | } 2053 | } 2054 | 2055 | public void GradientPerturb(Vector3f v3) { 2056 | SingleGradientPerturb(m_seed, m_gradientPerturbAmp, m_frequency, v3); 2057 | } 2058 | 2059 | public void GradientPerturbFractal(Vector3f v3) { 2060 | int seed = m_seed; 2061 | float amp = m_gradientPerturbAmp * m_fractalBounding; 2062 | float freq = m_frequency; 2063 | 2064 | SingleGradientPerturb(seed, amp, m_frequency, v3); 2065 | 2066 | for (int i = 1; i < m_octaves; i++) { 2067 | freq *= m_lacunarity; 2068 | amp *= m_gain; 2069 | SingleGradientPerturb(++seed, amp, freq, v3); 2070 | } 2071 | } 2072 | 2073 | private void SingleGradientPerturb(int seed, float perturbAmp, float frequency, Vector3f v3) { 2074 | float xf = v3.x * frequency; 2075 | float yf = v3.y * frequency; 2076 | float zf = v3.z * frequency; 2077 | 2078 | int x0 = FastFloor(xf); 2079 | int y0 = FastFloor(yf); 2080 | int z0 = FastFloor(zf); 2081 | int x1 = x0 + 1; 2082 | int y1 = y0 + 1; 2083 | int z1 = z0 + 1; 2084 | 2085 | float xs, ys, zs; 2086 | switch (m_interp) { 2087 | default: 2088 | case Linear: 2089 | xs = xf - x0; 2090 | ys = yf - y0; 2091 | zs = zf - z0; 2092 | break; 2093 | case Hermite: 2094 | xs = InterpHermiteFunc(xf - x0); 2095 | ys = InterpHermiteFunc(yf - y0); 2096 | zs = InterpHermiteFunc(zf - z0); 2097 | break; 2098 | case Quintic: 2099 | xs = InterpQuinticFunc(xf - x0); 2100 | ys = InterpQuinticFunc(yf - y0); 2101 | zs = InterpQuinticFunc(zf - z0); 2102 | break; 2103 | } 2104 | 2105 | Float3 vec0 = CELL_3D[Hash3D(seed, x0, y0, z0) & 255]; 2106 | Float3 vec1 = CELL_3D[Hash3D(seed, x1, y0, z0) & 255]; 2107 | 2108 | float lx0x = Lerp(vec0.x, vec1.x, xs); 2109 | float ly0x = Lerp(vec0.y, vec1.y, xs); 2110 | float lz0x = Lerp(vec0.z, vec1.z, xs); 2111 | 2112 | vec0 = CELL_3D[Hash3D(seed, x0, y1, z0) & 255]; 2113 | vec1 = CELL_3D[Hash3D(seed, x1, y1, z0) & 255]; 2114 | 2115 | float lx1x = Lerp(vec0.x, vec1.x, xs); 2116 | float ly1x = Lerp(vec0.y, vec1.y, xs); 2117 | float lz1x = Lerp(vec0.z, vec1.z, xs); 2118 | 2119 | float lx0y = Lerp(lx0x, lx1x, ys); 2120 | float ly0y = Lerp(ly0x, ly1x, ys); 2121 | float lz0y = Lerp(lz0x, lz1x, ys); 2122 | 2123 | vec0 = CELL_3D[Hash3D(seed, x0, y0, z1) & 255]; 2124 | vec1 = CELL_3D[Hash3D(seed, x1, y0, z1) & 255]; 2125 | 2126 | lx0x = Lerp(vec0.x, vec1.x, xs); 2127 | ly0x = Lerp(vec0.y, vec1.y, xs); 2128 | lz0x = Lerp(vec0.z, vec1.z, xs); 2129 | 2130 | vec0 = CELL_3D[Hash3D(seed, x0, y1, z1) & 255]; 2131 | vec1 = CELL_3D[Hash3D(seed, x1, y1, z1) & 255]; 2132 | 2133 | lx1x = Lerp(vec0.x, vec1.x, xs); 2134 | ly1x = Lerp(vec0.y, vec1.y, xs); 2135 | lz1x = Lerp(vec0.z, vec1.z, xs); 2136 | 2137 | v3.x += Lerp(lx0y, Lerp(lx0x, lx1x, ys), zs) * perturbAmp; 2138 | v3.y += Lerp(ly0y, Lerp(ly0x, ly1x, ys), zs) * perturbAmp; 2139 | v3.z += Lerp(lz0y, Lerp(lz0x, lz1x, ys), zs) * perturbAmp; 2140 | } 2141 | 2142 | public void GradientPerturb(Vector2f v2) { 2143 | SingleGradientPerturb(m_seed, m_gradientPerturbAmp, m_frequency, v2); 2144 | } 2145 | 2146 | public void GradientPerturbFractal(Vector2f v2) { 2147 | int seed = m_seed; 2148 | float amp = m_gradientPerturbAmp * m_fractalBounding; 2149 | float freq = m_frequency; 2150 | 2151 | SingleGradientPerturb(seed, amp, m_frequency, v2); 2152 | 2153 | for (int i = 1; i < m_octaves; i++) { 2154 | freq *= m_lacunarity; 2155 | amp *= m_gain; 2156 | SingleGradientPerturb(++seed, amp, freq, v2); 2157 | } 2158 | } 2159 | 2160 | private void SingleGradientPerturb(int seed, float perturbAmp, float frequency, Vector2f v2) { 2161 | float xf = v2.x * frequency; 2162 | float yf = v2.y * frequency; 2163 | 2164 | int x0 = FastFloor(xf); 2165 | int y0 = FastFloor(yf); 2166 | int x1 = x0 + 1; 2167 | int y1 = y0 + 1; 2168 | 2169 | float xs, ys; 2170 | switch (m_interp) { 2171 | default: 2172 | case Linear: 2173 | xs = xf - x0; 2174 | ys = yf - y0; 2175 | break; 2176 | case Hermite: 2177 | xs = InterpHermiteFunc(xf - x0); 2178 | ys = InterpHermiteFunc(yf - y0); 2179 | break; 2180 | case Quintic: 2181 | xs = InterpQuinticFunc(xf - x0); 2182 | ys = InterpQuinticFunc(yf - y0); 2183 | break; 2184 | } 2185 | 2186 | Float2 vec0 = CELL_2D[Hash2D(seed, x0, y0) & 255]; 2187 | Float2 vec1 = CELL_2D[Hash2D(seed, x1, y0) & 255]; 2188 | 2189 | float lx0x = Lerp(vec0.x, vec1.x, xs); 2190 | float ly0x = Lerp(vec0.y, vec1.y, xs); 2191 | 2192 | vec0 = CELL_2D[Hash2D(seed, x0, y1) & 255]; 2193 | vec1 = CELL_2D[Hash2D(seed, x1, y1) & 255]; 2194 | 2195 | float lx1x = Lerp(vec0.x, vec1.x, xs); 2196 | float ly1x = Lerp(vec0.y, vec1.y, xs); 2197 | 2198 | v2.x += Lerp(lx0x, lx1x, ys) * perturbAmp; 2199 | v2.y += Lerp(ly0x, ly1x, ys) * perturbAmp; 2200 | } 2201 | 2202 | } 2203 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jordan Peck 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![discord](https://img.shields.io/discord/703636892901441577?style=flat-square&logo=discord "Discord")](https://discord.gg/SHVaVfV) 2 | 3 | ### Depreciated 4 | This version of FastNoise is now depreciated, please look into using [FastNoise Lite](https://github.com/Auburn/FastNoise/) which is the successor to this library. 5 | 6 | # FastNoise 7 | 8 | This is the Java version of [FastNoise](https://github.com/Auburns/FastNoise) 9 | 10 | FastNoise is an open source noise generation library with a large collection of different noise algorithms. This library has been designed for realtime usage from the ground up, so has been optimised for speed without sacrificing noise quality. 11 | 12 | This project started when my search to find a good noise library for procedural terrain generation concluded without an obvious choice. I enjoyed the options and customisation of Accidental Noise Library and the speed of LibNoise, so many of the techniques from these libraries and the knowledge I gained from reading through their source has gone into creating FastNoise. 13 | 14 | I have now also created [FastNoise SIMD](https://github.com/Auburns/FastNoiseSIMD), which utilises SIMD CPU instructions to gain huge performance boosts. It is slightly less flexible and cannot be converted to other languages, but if you can I would highly suggest using this for heavy noise generation loads. 15 | 16 | ### Features 17 | - Value Noise 2D, 3D 18 | - Perlin Noise 2D, 3D 19 | - Simplex Noise 2D, 3D, 4D 20 | - Cubic Noise 2D, 3D 21 | - Gradient Perturb 2D, 3D 22 | - Multiple fractal options for all of the above 23 | - Cellular (Voronoi) Noise 2D, 3D 24 | - White Noise 2D, 3D, 4D 25 | 26 | ### Wiki 27 | Usage and documentation available in wiki 28 | 29 | [Wiki Link](https://github.com/Auburns/FastNoise/wiki) 30 | 31 | ### Related repositories 32 | - [FastNoise C#](https://github.com/Auburns/FastNoise_CSharp) 33 | - [FastNoise SIMD](https://github.com/Auburns/FastNoiseSIMD) 34 | - [FastNoise Unity](https://www.assetstore.unity3d.com/en/#!/content/70706) 35 | - [Unreal FastNoise](https://github.com/midgen/UnrealFastNoise) 36 | 37 | Credit to [CubicNoise](https://github.com/jobtalle/CubicNoise) for the cubic noise algorithm 38 | 39 | ## FastNoise Preview 40 | 41 | I have written a compact testing application for all the features included in FastNoise with a visual representation. I use this for development purposes and testing noise settings used in terrain generation. 42 | 43 | Download links can be found in the [Releases Section](https://github.com/Auburns/FastNoise/releases). 44 | 45 | ![FastNoise Preview](http://i.imgur.com/uG7Vepc.png) 46 | 47 | 48 | # Performance Comparisons 49 | Benchmarking done on C++ version. 50 | 51 | Using default noise settings on FastNoise and matching those settings across the other libraries where possible. 52 | 53 | Timings below are x1000 ns to generate 32x32x32 points of noise on a single thread. 54 | 55 | - CPU: Intel Xeon Skylake @ 2.0Ghz 56 | - Compiler: Intel 17.0 x64 57 | 58 | | Noise Type |FastNoise | FastNoiseSIMD AVX2 | LibNoise | FastNoise 2D | 59 | |-------------|----------|--------------------|-----------|--------------| 60 | | White Noise |141 | 13 | | 111 | 61 | | Value |635 | 160 | | 364 | 62 | | Perlin |964 | 342 | 1409 | 476 | 63 | | Simplex |1189 | 340 | | 875 | 64 | | Cellular |2933 | 1472 | 56960 | 1074 | 65 | | Cubic |2933 | 1393 | | 872 | 66 | 67 | Comparision of fractal performance [here](https://github.com/Auburns/FastNoiseSIMD/wiki/In-depth-SIMD-level). 68 | 69 | # Examples 70 | ## Cellular Noise 71 | ![Cellular Noise](http://i.imgur.com/quAic8M.png) 72 | 73 | ![Cellular Noise](http://i.imgur.com/gAd9Y2t.png) 74 | 75 | ![Cellular Noise](http://i.imgur.com/7kJd4fA.png) 76 | 77 | ## Fractal Noise 78 | ![Fractal Noise](http://i.imgur.com/XqSD7eR.png) 79 | 80 | ## Value Noise 81 | ![Value Noise](http://i.imgur.com/X2lbFZR.png) 82 | 83 | ## White Noise 84 | ![White Noise](http://i.imgur.com/QIlYvyQ.png) 85 | 86 | ## Gradient Perturb 87 | ![Gradient Perturb](http://i.imgur.com/gOjc1u1.png) 88 | 89 | ![Gradient Perturb](http://i.imgur.com/ui045Bk.png) 90 | 91 | ![Gradient Perturb](http://i.imgur.com/JICFypT.png) 92 | 93 | # Any suggestions or questions welcome 94 | --------------------------------------------------------------------------------