1 // turbulence.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.turbulence; 23 24 private { 25 import noise.mod.modulebase; 26 import noise.mod.perlin; 27 } 28 29 /// @addtogroup libnoise 30 /// @{ 31 32 /// @addtogroup modules 33 /// @{ 34 35 /// @addtogroup transformermodules 36 /// @{ 37 38 /// Default frequency for the module::Turbulence noise module. 39 const double DEFAULT_TURBULENCE_FREQUENCY = DEFAULT_PERLIN_FREQUENCY; 40 41 /// Default power for the module::Turbulence noise module. 42 const double DEFAULT_TURBULENCE_POWER = 1.0; 43 44 /// Default roughness for the module::Turbulence noise module. 45 const int DEFAULT_TURBULENCE_ROUGHNESS = 3; 46 47 /// Default noise seed for the module::Turbulence noise module. 48 const int DEFAULT_TURBULENCE_SEED = DEFAULT_PERLIN_SEED; 49 50 /// Noise module that randomly displaces the input value before 51 /// returning the output value from a source module. 52 /// 53 /// @image html moduleturbulence.png 54 /// 55 /// @a Turbulence is the pseudo-random displacement of the input value. 56 /// The GetValue() method randomly displaces the ( @a x, @a y, @a z ) 57 /// coordinates of the input value before retrieving the output value from 58 /// the source module. To control the turbulence, an application can 59 /// modify its frequency, its power, and its roughness. 60 /// 61 /// The frequency of the turbulence determines how rapidly the 62 /// displacement amount changes. To specify the frequency, call the 63 /// SetFrequency() method. 64 /// 65 /// The power of the turbulence determines the scaling factor that is 66 /// applied to the displacement amount. To specify the power, call the 67 /// SetPower() method. 68 /// 69 /// The roughness of the turbulence determines the roughness of the 70 /// changes to the displacement amount. Low values smoothly change the 71 /// displacement amount. High values roughly change the displacement 72 /// amount, which produces more "kinky" changes. To specify the 73 /// roughness, call the SetRoughness() method. 74 /// 75 /// Use of this noise module may require some trial and error. Assuming 76 /// that you are using a generator module as the source module, you 77 /// should first: 78 /// - Set the frequency to the same frequency as the source module. 79 /// - Set the power to the reciprocal of the frequency. 80 /// 81 /// From these initial frequency and power values, modify these values 82 /// until this noise module produce the desired changes in your terrain or 83 /// texture. For example: 84 /// - Low frequency (1/8 initial frequency) and low power (1/8 initial 85 /// power) produces very minor, almost unnoticeable changes. 86 /// - Low frequency (1/8 initial frequency) and high power (8 times 87 /// initial power) produces "ropey" lava-like terrain or marble-like 88 /// textures. 89 /// - High frequency (8 times initial frequency) and low power (1/8 90 /// initial power) produces a noisy version of the initial terrain or 91 /// texture. 92 /// - High frequency (8 times initial frequency) and high power (8 times 93 /// initial power) produces nearly pure noise, which isn't entirely 94 /// useful. 95 /// 96 /// Displacing the input values result in more realistic terrain and 97 /// textures. If you are generating elevations for terrain height maps, 98 /// you can use this noise module to produce more realistic mountain 99 /// ranges or terrain features that look like flowing lava rock. If you 100 /// are generating values for textures, you can use this noise module to 101 /// produce realistic marble-like or "oily" textures. 102 /// 103 /// Internally, there are three module::Perlin noise modules 104 /// that displace the input value; one for the @a x, one for the @a y, 105 /// and one for the @a z coordinate. 106 /// 107 /// This noise module requires one source module. 108 class Turbulence : Mod 109 { 110 111 public: 112 113 /// Constructor. 114 /// 115 /// The default frequency is set to 116 /// module::DEFAULT_TURBULENCE_FREQUENCY. 117 /// 118 /// The default power is set to 119 /// module::DEFAULT_TURBULENCE_POWER. 120 /// 121 /// The default roughness is set to 122 /// module::DEFAULT_TURBULENCE_ROUGHNESS. 123 /// 124 /// The default seed value is set to 125 /// module::DEFAULT_TURBULENCE_SEED. 126 this() 127 { 128 super(this.GetSourceModCount()); 129 m_power = DEFAULT_TURBULENCE_POWER; 130 SetSeed (DEFAULT_TURBULENCE_SEED); 131 SetFrequency (DEFAULT_TURBULENCE_FREQUENCY); 132 SetRoughness (DEFAULT_TURBULENCE_ROUGHNESS); 133 } 134 135 /// Returns the frequency of the turbulence. 136 /// 137 /// @returns The frequency of the turbulence. 138 /// 139 /// The frequency of the turbulence determines how rapidly the 140 /// displacement amount changes. 141 double GetFrequency () const 142 { 143 // Since each module::Perlin noise module has the same frequency, it 144 // does not matter which module we use to retrieve the frequency. 145 return m_xDistortMod.GetFrequency (); 146 } 147 148 /// Returns the power of the turbulence. 149 /// 150 /// @returns The power of the turbulence. 151 /// 152 /// The power of the turbulence determines the scaling factor that is 153 /// applied to the displacement amount. 154 double GetPower () const 155 { 156 return m_power; 157 } 158 159 /// Returns the roughness of the turbulence. 160 /// 161 /// @returns The roughness of the turbulence. 162 /// 163 /// The roughness of the turbulence determines the roughness of the 164 /// changes to the displacement amount. Low values smoothly change 165 /// the displacement amount. High values roughly change the 166 /// displacement amount, which produces more "kinky" changes. 167 int GetRoughnessCount () const 168 { 169 return m_xDistortMod.GetOctaveCount (); 170 } 171 172 /// Returns the seed value of the internal Perlin-noise modules that 173 /// are used to displace the input values. 174 /// 175 /// @returns The seed value. 176 /// 177 /// Internally, there are three module::Perlin noise modules 178 /// that displace the input value; one for the @a x, one for the @a y, 179 /// and one for the @a z coordinate. 180 int GetSeed () const 181 { 182 return m_xDistortMod.GetSeed (); 183 } 184 185 override int GetSourceModCount () const 186 { 187 return 1; 188 } 189 190 override double GetValue (double x, double y, double z) const 191 { 192 assert (m_pSourceMod[0] !is null); 193 194 // Get the values from the three module::Perlin noise modules and 195 // add each value to each coordinate of the input value. There are also 196 // some offsets added to the coordinates of the input values. This prevents 197 // the distortion modules from returning zero if the (x, y, z) coordinates, 198 // when multiplied by the frequency, are near an integer boundary. This is 199 // due to a property of gradient coherent noise, which returns zero at 200 // integer boundaries. 201 double x0, y0, z0; 202 double x1, y1, z1; 203 double x2, y2, z2; 204 x0 = x + (12414.0 / 65536.0); 205 y0 = y + (65124.0 / 65536.0); 206 z0 = z + (31337.0 / 65536.0); 207 x1 = x + (26519.0 / 65536.0); 208 y1 = y + (18128.0 / 65536.0); 209 z1 = z + (60493.0 / 65536.0); 210 x2 = x + (53820.0 / 65536.0); 211 y2 = y + (11213.0 / 65536.0); 212 z2 = z + (44845.0 / 65536.0); 213 double xDistort = x + (m_xDistortMod.GetValue (x0, y0, z0) 214 * m_power); 215 double yDistort = y + (m_yDistortMod.GetValue (x1, y1, z1) 216 * m_power); 217 double zDistort = z + (m_zDistortMod.GetValue (x2, y2, z2) 218 * m_power); 219 220 // Retrieve the output value at the offsetted input value instead of the 221 // original input value. 222 return m_pSourceMod[0].GetValue (xDistort, yDistort, zDistort); 223 } 224 225 /// Sets the frequency of the turbulence. 226 /// 227 /// @param frequency The frequency of the turbulence. 228 /// 229 /// The frequency of the turbulence determines how rapidly the 230 /// displacement amount changes. 231 void SetFrequency (double frequency) 232 { 233 // Set the frequency of each Perlin-noise module. 234 m_xDistortMod.SetFrequency (frequency); 235 m_yDistortMod.SetFrequency (frequency); 236 m_zDistortMod.SetFrequency (frequency); 237 } 238 239 /// Sets the power of the turbulence. 240 /// 241 /// @param power The power of the turbulence. 242 /// 243 /// The power of the turbulence determines the scaling factor that is 244 /// applied to the displacement amount. 245 void SetPower (double power) 246 { 247 m_power = power; 248 } 249 250 /// Sets the roughness of the turbulence. 251 /// 252 /// @param roughness The roughness of the turbulence. 253 /// 254 /// The roughness of the turbulence determines the roughness of the 255 /// changes to the displacement amount. Low values smoothly change 256 /// the displacement amount. High values roughly change the 257 /// displacement amount, which produces more "kinky" changes. 258 /// 259 /// Internally, there are three module::Perlin noise modules 260 /// that displace the input value; one for the @a x, one for the @a y, 261 /// and one for the @a z coordinate. The roughness value is equal to 262 /// the number of octaves used by the module::Perlin noise 263 /// modules. 264 void SetRoughness (int roughness) 265 { 266 // Set the octave count for each Perlin-noise module. 267 m_xDistortMod.SetOctaveCount (roughness); 268 m_yDistortMod.SetOctaveCount (roughness); 269 m_zDistortMod.SetOctaveCount (roughness); 270 } 271 272 /// Sets the seed value of the internal noise modules that are used to 273 /// displace the input values. 274 /// 275 /// @param seed The seed value. 276 /// 277 /// Internally, there are three module::Perlin noise modules 278 /// that displace the input value; one for the @a x, one for the @a y, 279 /// and one for the @a z coordinate. This noise module assigns the 280 /// following seed values to the module::Perlin noise modules: 281 /// - It assigns the seed value (@a seed + 0) to the @a x noise module. 282 /// - It assigns the seed value (@a seed + 1) to the @a y noise module. 283 /// - It assigns the seed value (@a seed + 2) to the @a z noise module. 284 void SetSeed (int seed) 285 { 286 // Set the seed of each module::Perlin noise modules. To prevent any 287 // sort of weird artifacting, use a slightly different seed for each noise 288 // module. 289 m_xDistortMod.SetSeed (seed ); 290 m_yDistortMod.SetSeed (seed + 1); 291 m_zDistortMod.SetSeed (seed + 2); 292 } 293 294 protected: 295 296 /// The power (scale) of the displacement. 297 double m_power; 298 299 /// Noise module that displaces the @a x coordinate. 300 Perlin m_xDistortMod; 301 302 /// Noise module that displaces the @a y coordinate. 303 Perlin m_yDistortMod; 304 305 /// Noise module that displaces the @a z coordinate. 306 Perlin m_zDistortMod; 307 308 }; 309 310 /// @} 311 312 /// @} 313 314 /// @}