1 // ridgedmulti.h 2 // 3 // Copyright (C) 2003, 2004 Jason Bevins 4 // 5 // This library is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation; either version 2.1 of the License, or (at 8 // your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 13 // License (COPYING.txt) for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with this library; if not, write to the Free Software Foundation, 17 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 // 19 // The developer's email is jlbezigvins@gmzigail.com (for great email, take 20 // off every 'zig'.) 21 // 22 module noise.mod.ridgedmulti; 23 24 private { 25 import noise.mod.modulebase; 26 } 27 28 /// @addtogroup libnoise 29 /// @{ 30 31 /// @addtogroup modules 32 /// @{ 33 34 /// @addtogroup generatormodules 35 /// @{ 36 37 /// Default frequency for the module::RidgedMulti noise module. 38 const double DEFAULT_RIDGED_FREQUENCY = 1.0; 39 40 /// Default lacunarity for the module::RidgedMulti noise module. 41 const double DEFAULT_RIDGED_LACUNARITY = 2.0; 42 43 /// Default number of octaves for the module::RidgedMulti noise 44 /// module. 45 const int DEFAULT_RIDGED_OCTAVE_COUNT = 6; 46 47 /// Default noise quality for the module::RidgedMulti noise 48 /// module. 49 const NoiseQuality DEFAULT_RIDGED_QUALITY = NoiseQuality.QUALITY_STD; 50 51 /// Default noise seed for the module::RidgedMulti noise module. 52 const int DEFAULT_RIDGED_SEED = 0; 53 54 /// Maximum number of octaves for the module::RidgedMulti noise 55 /// module. 56 const int RIDGED_MAX_OCTAVE = 30; 57 58 /// Noise module that outputs 3-dimensional ridged-multifractal noise. 59 /// 60 /// @image html moduleridgedmulti.png 61 /// 62 /// This noise module, heavily based on the Perlin-noise module, generates 63 /// ridged-multifractal noise. Ridged-multifractal noise is generated in 64 /// much of the same way as Perlin noise, except the output of each octave 65 /// is modified by an absolute-value function. Modifying the octave 66 /// values in this way produces ridge-like formations. 67 /// 68 /// Ridged-multifractal noise does not use a persistence value. This is 69 /// because the persistence values of the octaves are based on the values 70 /// generated from from previous octaves, creating a feedback loop (or 71 /// that's what it looks like after reading the code.) 72 /// 73 /// This noise module outputs ridged-multifractal-noise values that 74 /// usually range from -1.0 to +1.0, but there are no guarantees that all 75 /// output values will exist within that range. 76 /// 77 /// @note For ridged-multifractal noise generated with only one octave, 78 /// the output value ranges from -1.0 to 0.0. 79 /// 80 /// Ridged-multifractal noise is often used to generate craggy mountainous 81 /// terrain or marble-like textures. 82 /// 83 /// This noise module does not require any source modules. 84 /// 85 /// <b>Octaves</b> 86 /// 87 /// The number of octaves control the <i>amount of detail</i> of the 88 /// ridged-multifractal noise. Adding more octaves increases the detail 89 /// of the ridged-multifractal noise, but with the drawback of increasing 90 /// the calculation time. 91 /// 92 /// An application may specify the number of octaves that generate 93 /// ridged-multifractal noise by calling the SetOctaveCount() method. 94 /// 95 /// <b>Frequency</b> 96 /// 97 /// An application may specify the frequency of the first octave by 98 /// calling the SetFrequency() method. 99 /// 100 /// <b>Lacunarity</b> 101 /// 102 /// The lacunarity specifies the frequency multipler between successive 103 /// octaves. 104 /// 105 /// The effect of modifying the lacunarity is subtle; you may need to play 106 /// with the lacunarity value to determine the effects. For best results, 107 /// set the lacunarity to a number between 1.5 and 3.5. 108 /// 109 /// <b>References & Acknowledgments</b> 110 /// 111 /// <a href=http://www.texturingandmodeling.com/Musgrave.html>F. 112 /// Kenton "Doc Mojo" Musgrave's texturing page</a> - This page contains 113 /// links to source code that generates ridged-multfractal noise, among 114 /// other types of noise. The source file <a 115 /// href=http://www.texturingandmodeling.com/CODE/MUSGRAVE/CLOUD/fractal.c> 116 /// fractal.c</a> contains the code I used in my ridged-multifractal class 117 /// (see the @a RidgedMultifractal() function.) This code was written by F. 118 /// Kenton Musgrave, the person who created 119 /// <a href=http://www.pandromeda.com/>MojoWorld</a>. He is also one of 120 /// the authors in <i>Texturing and Modeling: A Procedural Approach</i> 121 /// (Morgan Kaufmann, 2002. ISBN 1-55860-848-6.) 122 class RidgedMulti : Mod 123 { 124 125 public: 126 127 /// Constructor. 128 /// 129 /// The default number of octaves is set to 130 /// module::DEFAULT_RIDGED_OCTAVE_COUNT. 131 /// 132 /// The default frequency is set to 133 /// module::DEFAULT_RIDGED_FREQUENCY. 134 /// 135 /// The default lacunarity is set to 136 /// module::DEFAULT_RIDGED_LACUNARITY. 137 /// 138 /// The default seed value is set to 139 /// module::DEFAULT_RIDGED_SEED. 140 this() 141 { 142 super(this.GetSourceModCount ()); 143 m_frequency = DEFAULT_RIDGED_FREQUENCY; 144 m_lacunarity = DEFAULT_RIDGED_LACUNARITY; 145 m_noiseQuality = DEFAULT_RIDGED_QUALITY; 146 m_octaveCount = DEFAULT_RIDGED_OCTAVE_COUNT; 147 m_seed = DEFAULT_RIDGED_SEED; 148 this.CalcSpectralWeights (); 149 } 150 151 /// Returns the frequency of the first octave. 152 /// 153 /// @returns The frequency of the first octave. 154 double GetFrequency () const 155 { 156 return m_frequency; 157 } 158 159 /// Returns the lacunarity of the ridged-multifractal noise. 160 /// 161 /// @returns The lacunarity of the ridged-multifractal noise. 162 /// 163 /// The lacunarity is the frequency multiplier between successive 164 /// octaves. 165 double GetLacunarity () const 166 { 167 return m_lacunarity; 168 } 169 170 /// Returns the quality of the ridged-multifractal noise. 171 /// 172 /// @returns The quality of the ridged-multifractal noise. 173 /// 174 /// See NoiseQuality for definitions of the various 175 /// coherent-noise qualities. 176 NoiseQuality GetNoiseQuality () const 177 { 178 return m_noiseQuality; 179 } 180 181 /// Returns the number of octaves that generate the 182 /// ridged-multifractal noise. 183 /// 184 /// @returns The number of octaves that generate the 185 /// ridged-multifractal noise. 186 /// 187 /// The number of octaves controls the amount of detail in the 188 /// ridged-multifractal noise. 189 int GetOctaveCount () const 190 { 191 return m_octaveCount; 192 } 193 194 /// Returns the seed value used by the ridged-multifractal-noise 195 /// function. 196 /// 197 /// @returns The seed value. 198 int GetSeed () const 199 { 200 return m_seed; 201 } 202 203 override int GetSourceModCount () const 204 { 205 return 0; 206 } 207 208 // Multifractal code originally written by F. Kenton "Doc Mojo" Musgrave, 209 // 1998. Modified by jas for use with libnoise. 210 override double GetValue (double x, double y, double z) const 211 { 212 x *= m_frequency; 213 y *= m_frequency; 214 z *= m_frequency; 215 216 double signal = 0.0; 217 double value = 0.0; 218 double weight = 1.0; 219 220 // These parameters should be user-defined; they may be exposed in a 221 // future version of libnoise. 222 double offset = 1.0; 223 double gain = 2.0; 224 225 for (int curOctave = 0; curOctave < m_octaveCount; curOctave++) { 226 227 // Make sure that these floating-point values have the same range as a 32- 228 // bit integer so that we can pass them to the coherent-noise functions. 229 double nx, ny, nz; 230 nx = MakeInt32Range (x); 231 ny = MakeInt32Range (y); 232 nz = MakeInt32Range (z); 233 234 // Get the coherent-noise value. 235 int seed = (m_seed + curOctave) & 0x7fffffff; 236 signal = GradientCoherentNoise3D (nx, ny, nz, seed, m_noiseQuality); 237 238 // Make the ridges. 239 signal = fabs (signal); 240 signal = offset - signal; 241 242 // Square the signal to increase the sharpness of the ridges. 243 signal *= signal; 244 245 // The weighting from the previous octave is applied to the signal. 246 // Larger values have higher weights, producing sharp points along the 247 // ridges. 248 signal *= weight; 249 250 // Weight successive contributions by the previous signal. 251 weight = signal * gain; 252 if (weight > 1.0) { 253 weight = 1.0; 254 } 255 if (weight < 0.0) { 256 weight = 0.0; 257 } 258 259 // Add the signal to the output value. 260 value += (signal * m_pSpectralWeights[curOctave]); 261 262 // Go to the next octave. 263 x *= m_lacunarity; 264 y *= m_lacunarity; 265 z *= m_lacunarity; 266 } 267 268 return (value * 1.25) - 1.0; 269 } 270 271 /// Sets the frequency of the first octave. 272 /// 273 /// @param frequency The frequency of the first octave. 274 void SetFrequency (double frequency) 275 { 276 m_frequency = frequency; 277 } 278 279 /// Sets the lacunarity of the ridged-multifractal noise. 280 /// 281 /// @param lacunarity The lacunarity of the ridged-multifractal noise. 282 /// 283 /// The lacunarity is the frequency multiplier between successive 284 /// octaves. 285 /// 286 /// For best results, set the lacunarity to a number between 1.5 and 287 /// 3.5. 288 void SetLacunarity (double lacunarity) 289 { 290 m_lacunarity = lacunarity; 291 CalcSpectralWeights (); 292 } 293 294 /// Sets the quality of the ridged-multifractal noise. 295 /// 296 /// @param noiseQuality The quality of the ridged-multifractal noise. 297 /// 298 /// See NoiseQuality for definitions of the various 299 /// coherent-noise qualities. 300 void SetNoiseQuality (NoiseQuality noiseQuality) 301 { 302 m_noiseQuality = noiseQuality; 303 } 304 305 /// Sets the number of octaves that generate the ridged-multifractal 306 /// noise. 307 /// 308 /// @param octaveCount The number of octaves that generate the 309 /// ridged-multifractal noise. 310 /// 311 /// @pre The number of octaves ranges from 1 to 312 /// module::RIDGED_MAX_OCTAVE. 313 /// 314 /// @throw new ExceptionInvalidParam An invalid parameter was 315 /// specified; see the preconditions for more information. 316 /// 317 /// The number of octaves controls the amount of detail in the 318 /// ridged-multifractal noise. 319 /// 320 /// The larger the number of octaves, the more time required to 321 /// calculate the ridged-multifractal-noise value. 322 void SetOctaveCount (int octaveCount) 323 { 324 if (octaveCount > RIDGED_MAX_OCTAVE) { 325 throw new ExceptionInvalidParam (); 326 } 327 m_octaveCount = octaveCount; 328 } 329 330 /// Sets the seed value used by the ridged-multifractal-noise 331 /// function. 332 /// 333 /// @param seed The seed value. 334 void SetSeed (int seed) 335 { 336 m_seed = seed; 337 } 338 339 protected: 340 341 /// Calculates the spectral weights for each octave. 342 /// 343 /// This method is called when the lacunarity changes. 344 void CalcSpectralWeights () 345 { 346 // This exponent parameter should be user-defined; it may be exposed in a 347 // future version of libnoise. 348 double h = 1.0; 349 350 double frequency = 1.0; 351 for (int i = 0; i < RIDGED_MAX_OCTAVE; i++) { 352 // Compute weight for each frequency. 353 m_pSpectralWeights[i] = pow (frequency, -h); 354 frequency *= m_lacunarity; 355 } 356 } 357 358 /// Frequency of the first octave. 359 double m_frequency; 360 361 /// Frequency multiplier between successive octaves. 362 double m_lacunarity; 363 364 /// Quality of the ridged-multifractal noise. 365 NoiseQuality m_noiseQuality; 366 367 /// Total number of octaves that generate the ridged-multifractal 368 /// noise. 369 int m_octaveCount; 370 371 /// Contains the spectral weights for each octave. 372 double[RIDGED_MAX_OCTAVE] m_pSpectralWeights; 373 374 /// Seed value used by the ridged-multfractal-noise function. 375 int m_seed; 376 377 }; 378 379 /// @} 380 381 /// @} 382 383 /// @}