Gamedev Framework (gf)  0.6.0
A C++11 framework for 2D games
Noises.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2017 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_NOISES_H
22 #define GF_NOISES_H
23 
24 #include <cstddef>
25 #include <cstdint>
26 #include <array>
27 #include <functional>
28 #include <vector>
29 
30 #include "Math.h"
31 #include "Noise.h"
32 #include "Portability.h"
33 #include "Vector.h"
34 
35 
36 namespace gf {
37 #ifndef DOXYGEN_SHOULD_SKIP_THIS
38 inline namespace v1 {
39 #endif
40 
41  class Random;
42 
43  /**
44  * @ingroup core
45  * @brief Value 2D noise
46  *
47  * [Value noise](https://en.wikipedia.org/wiki/Value_noise) is a
48  * lattice-based noise based on values.
49  */
50  class GF_API ValueNoise2D : public Noise2D {
51  public:
52  /**
53  * @brief Constructor
54  *
55  * @param random A random engine
56  * @param step A step
57  *
58  * @sa gf::Step
59  */
60  ValueNoise2D(Random& random, Step<double> step);
61 
62  virtual double getValue(double x, double y) override;
63 
64  private:
65  Step<double> m_step;
66  std::array<uint8_t, 256> m_perm;
67  std::array<double, 256> m_values;
68 
69  double at(uint8_t i, uint8_t j) const;
70  };
71 
72 
73  /**
74  * @ingroup core
75  * @brief Gradient 2D noise
76  *
77  * [Gradient noise](https://en.wikipedia.org/wiki/Gradient_noise) is a
78  * lattice-based noise based on gradients.
79  */
80  class GF_API GradientNoise2D : public Noise2D {
81  public:
82  /**
83  * @brief Constructor
84  *
85  * @param random A random engine
86  * @param step A step
87  *
88  * @sa gf::Step
89  */
90  GradientNoise2D(Random& random, Step<double> step);
91 
92  virtual double getValue(double x, double y) override;
93 
94  private:
95  Step<double> m_step;
96  std::array<uint8_t, 256> m_perm;
97  std::array<Vector2d, 256> m_gradients2D;
98 
99  const Vector2d& at(uint8_t i, uint8_t j) const;
100  };
101 
102  /**
103  * @ingroup core
104  * @brief Gradient 3D noise
105  *
106  * [Gradient noise](https://en.wikipedia.org/wiki/Gradient_noise) is a
107  * lattice-based noise based on gradients.
108  */
109  class GF_API GradientNoise3D : public Noise3D {
110  public:
111  /**
112  * @brief Constructor
113  *
114  * @param random A random engine
115  * @param step A step
116  *
117  * @sa gf::Step
118  */
119  GradientNoise3D(Random& random, Step<double> step);
120 
121  virtual double getValue(double x, double y, double z) override;
122 
123  private:
124  Step<double> m_step;
125  std::array<uint8_t, 256> m_perm;
126  std::array<Vector3d, 256> m_gradients3D;
127 
128  const Vector3d& at(uint8_t i, uint8_t j, uint8_t k) const;
129  };
130 
131  /**
132  * @ingroup core
133  * @brief Better gradient 2D noise
134  *
135  * An implementation of the better gradient noise of Kensler et al.,
136  * especially the new hash function and filter kernel. This noise is
137  * slower than gradient noise but gives better results.
138  *
139  * @sa [Better Gradient Noise. A. Kensler, A. Knoll, P. Shirley. 2008](https://www.cs.utah.edu/~aek/research/noise.pdf)
140  */
142  public:
143  /**
144  * @brief Constructor
145  *
146  * @param random A random engine
147  */
148  BetterGradientNoise2D(Random& random);
149 
150  virtual double getValue(double x, double y) override;
151 
152  private:
153  std::array<uint8_t, 256> m_permX;
154  std::array<uint8_t, 256> m_permY;
155  std::array<Vector2d, 256> m_gradients2D;
156 
157  const Vector2d& at(uint8_t i, uint8_t j) const;
158  };
159 
160  /**
161  * @ingroup core
162  * @brief Fractal 2D noise
163  *
164  * Fractal noise is based of fractional Brownian motion (fBm). It consists
165  * in adding several octaves of a basic noise at different amplitudes.
166  *
167  */
168  class GF_API FractalNoise2D : public Noise2D {
169  public:
170  /**
171  * @brief Constructor
172  *
173  * @param noise The basic noise function
174  * @param scale The scale factor
175  * @param octaves The number of octaves
176  * @param lacunarity The factor applied to frequency
177  * @param persistence The factor applied to amplitude
178  * @param dimension The contrast between the layers
179  */
180  FractalNoise2D(Noise2D& noise, double scale, std::size_t octaves = 8, double lacunarity = 2.0, double persistence = 0.5, double
181  dimension = 1.0);
182 
183  virtual double getValue(double x, double y) override;
184 
185  private:
186  Noise2D& m_noise;
187  double m_scale;
188  std::size_t m_octaves;
189  double m_lacunarity;
190  double m_persistence;
191  double m_dimension;
192  };
193 
194 
195  /**
196  * @ingroup core
197  * @brief Fractal 3D noise
198  *
199  * Fractal noise is based of fractional Brownian motion (fBm). It consists
200  * in adding several octaves of a basic noise at different amplitudes.
201  *
202  */
203  class GF_API FractalNoise3D : public Noise3D {
204  public:
205  /**
206  * @brief Constructor
207  *
208  * @param noise The basic noise function
209  * @param scale The scale factor
210  * @param octaves The number of octaves
211  * @param lacunarity The factor applied to frequency
212  * @param persistence The factor applied to amplitude
213  * @param dimension The contrast between the layers
214  */
215  FractalNoise3D(Noise3D& noise, double scale, std::size_t octaves = 8, double lacunarity = 2.0, double persistence = 0.5, double dimension = 1.0);
216 
217  virtual double getValue(double x, double y, double z) override;
218 
219  private:
220  Noise3D& m_noise;
221  double m_scale;
222  std::size_t m_octaves;
223  double m_lacunarity;
224  double m_persistence;
225  double m_dimension;
226  };
227 
228 
229  /**
230  * @ingroup core
231  * @brief Perlin 2D noise
232  *
233  * [Perlin noise](https://en.wikipedia.org/wiki/Perlin_noise) is the
234  * combination of a fractal noise and a gradient noise.
235  *
236  * @sa gf::GradientNoise2D, gf::FractalNoise2D
237  */
238  class GF_API PerlinNoise2D : public Noise2D {
239  public:
240  /**
241  * @brief Constructor
242  *
243  * @param random A random engine
244  * @param scale The scale factor
245  * @param octaves The number of octaves
246  */
247  PerlinNoise2D(Random& random, double scale, std::size_t octaves = 8);
248 
249  virtual double getValue(double x, double y) override;
250 
251  private:
252  GradientNoise2D m_gradient;
253  FractalNoise2D m_fractal;
254  };
255 
256  /**
257  * @ingroup core
258  * @brief Perlin 3D noise
259  *
260  * [Perlin noise](https://en.wikipedia.org/wiki/Perlin_noise) is the
261  * combination of a fractal noise and a gradient noise.
262  *
263  * @sa gf::GradientNoise3D, gf::FractalNoise3D
264  */
265  class GF_API PerlinNoise3D : public Noise3D {
266  public:
267  /**
268  * @brief Constructor
269  *
270  * @param random A random engine
271  * @param scale The scale factor
272  * @param octaves The number of octaves
273  */
274  PerlinNoise3D(Random& random, double scale, std::size_t octaves = 8);
275 
276  virtual double getValue(double x, double y, double z) override;
277 
278  private:
279  GradientNoise3D m_gradient;
280  FractalNoise3D m_fractal;
281  };
282 
283 
284  /**
285  * @ingroup core
286  * @brief Simplex 2D noise
287  *
288  * [Simplex noise](https://en.wikipedia.org/wiki/Simplex_noise) is a lattice
289  * noise based on gradients put on a simplex.
290  *
291  * This implementation is limited to 2D noise and is *not* submitted to the
292  * patent that covers simplex noise.
293  *
294  * @sa gf::GradientNoise2D
295  */
296  class GF_API SimplexNoise2D : public Noise2D {
297  public:
298  /**
299  * @brief Constructor
300  *
301  * @param random A random engine
302  */
303  SimplexNoise2D(Random& random);
304 
305  virtual double getValue(double x, double y) override;
306 
307  private:
308  std::array<uint8_t, 256> m_perm;
309 
310  const Vector2d& at(uint8_t i, uint8_t j) const;
311  };
312 
313 
314  /**
315  * @ingroup core
316  * @brief OpenSimplex 2D noise
317  *
318  * [OpenSimplex noise](https://en.wikipedia.org/wiki/OpenSimplex_noise) is a lattice
319  * noise very similar to simplex noise.
320  *
321  * @sa gf::SimplexNoise2D
322  */
324  public:
325  /**
326  * @brief Constructor
327  *
328  * @param random A random engine
329  */
330  OpenSimplexNoise2D(Random& random);
331 
332  virtual double getValue(double x, double y) override;
333 
334  private:
335  std::array<uint8_t, 256> m_perm;
336 
337  const Vector2d& at(uint8_t i, uint8_t j) const;
338  };
339 
340  /**
341  * @ingroup core
342  * @brief OpenSimplex3D noise
343  *
344  * [OpenSimplex noise](https://en.wikipedia.org/wiki/OpenSimplex_noise) is a lattice
345  * noise very similar to simplex noise.
346  *
347  * @sa gf::SimplexNoise
348  */
350  public:
351  /**
352  * @brief Constructor
353  *
354  * @param random A random engine
355  */
356  OpenSimplexNoise3D(Random& random);
357 
358  virtual double getValue(double x, double y, double z) override;
359 
360  private:
361  std::array<uint8_t, 256> m_perm;
362 
363  const Vector3d& at(uint8_t i, uint8_t j, uint8_t k) const;
364  };
365 
366  /**
367  * @ingroup core
368  * @brief Wavelet 3D noise
369  *
370  * @sa [Wavelet Noise. Robert L. Cook, Tony DeRose, Pixar Animation Studios.](https://graphics.pixar.com/library/WaveletNoise/paper.pdf)
371  */
372  class GF_API WaveletNoise3D : public Noise3D {
373  public:
374  /**
375  * @brief Constructor
376  *
377  * @param random A random engine
378  * @param n Wavelet tile size
379  */
380  WaveletNoise3D(Random& random, std::ptrdiff_t n = 32);
381 
382  virtual double getValue(double x, double y, double z) override;
383 
384  private:
385  std::ptrdiff_t m_n;
386  std::vector<double> m_data;
387  };
388 
389  /**
390  * @ingroup core
391  * @brief Worley 2D noise
392  *
393  * [Worley noise](https://en.wikipedia.org/wiki/Worley_noise) is a point
394  * based noise. It is also known as Voronoi noise or cellular noise or
395  * simply cell noise.
396  */
397  class GF_API WorleyNoise2D : public Noise2D {
398  public:
399  /**
400  * @brief Constructor
401  *
402  * @param random A random engine
403  * @param count The number of points
404  * @param distance A distance function
405  * @param coeffs The coefficients for the noise
406  */
407  WorleyNoise2D(Random& random, std::size_t count, Distance2<double> distance, std::vector<double> coeffs);
408 
409  virtual double getValue(double x, double y) override;
410 
411  private:
412  std::size_t m_count;
413  Distance2<double> m_distance;
414  std::vector<double> m_coeffs;
415  std::vector<Vector2d> m_cells;
416  };
417 
418 
419  /**
420  * @ingroup core
421  * @brief Multi Fractal 2D noise
422  *
423  */
424  class GF_API Multifractal2D : public Noise2D {
425  public:
426  /**
427  * @brief Constructor
428  *
429  * @param noise The basic noise function
430  * @param scale The scale factor
431  * @param octaves The number of octaves
432  * @param lacunarity The factor applied to frequency
433  * @param persistence The factor applied to amplitude
434  * @param dimension The contrast between the layers
435  */
436  Multifractal2D(Noise2D& noise, double scale, std::size_t octaves = 8, double lacunarity = 2.0, double persistence = 0.5, double dimension = 1.0);
437 
438  virtual double getValue(double x, double y) override;
439 
440  private:
441  Noise2D& m_noise;
442  double m_scale;
443  std::size_t m_octaves;
444  double m_lacunarity;
445  double m_persistence;
446  double m_dimension;
447  };
448 
449 
450  /**
451  * @ingroup core
452  * @brief Hetero Terrain 2D noise
453  *
454  */
455  class GF_API HeteroTerrain2D : public Noise2D {
456  public:
457  /**
458  * @brief Constructor
459  *
460  * @param noise The basic noise function
461  * @param scale The scale factor
462  * @param offset The offset
463  * @param octaves The number of octaves
464  * @param lacunarity The factor applied to frequency
465  * @param persistence The factor applied to amplitude
466  * @param dimension The contrast between the layers
467  */
468  HeteroTerrain2D(Noise2D& noise, double scale, double offset = 0.0, std::size_t octaves = 8, double lacunarity = 2.0, double persistence = 0.5, double dimension = 1.0);
469 
470  virtual double getValue(double x, double y) override;
471 
472  private:
473  Noise2D& m_noise;
474  double m_scale;
475  double m_offset;
476  std::size_t m_octaves;
477  double m_lacunarity;
478  double m_persistence;
479  double m_dimension;
480  };
481 
482  /**
483  * @ingroup core
484  * @brief Hybrid Multifractal 2D noise
485  *
486  */
488  public:
489  /**
490  * @brief Constructor
491  *
492  * @param noise The basic noise function
493  * @param scale The scale factor
494  * @param offset The offset
495  * @param octaves The number of octaves
496  * @param lacunarity The factor applied to frequency
497  * @param persistence The factor applied to amplitude
498  * @param dimension The contrast between the layers
499  */
500  HybridMultifractal2D(Noise2D& noise, double scale, double offset = 0.0, std::size_t octaves = 8, double lacunarity = 2.0, double persistence = 0.5, double dimension = 1.0);
501 
502  virtual double getValue(double x, double y) override;
503 
504  private:
505  Noise2D& m_noise;
506  double m_scale;
507  double m_offset;
508  std::size_t m_octaves;
509  double m_lacunarity;
510  double m_persistence;
511  double m_dimension;
512  };
513 
514  /**
515  * @ingroup core
516  * @brief Ridged Multifractal 2D noise
517  *
518  */
520  public:
521  /**
522  * @brief Constructor
523  *
524  * @param noise The basic noise function
525  * @param scale The scale factor
526  * @param offset The offset
527  * @param gain The gain
528  * @param octaves The number of octaves
529  * @param lacunarity The factor applied to frequency
530  * @param persistence The factor applied to amplitude
531  * @param dimension The contrast between the layers
532  */
533  RidgedMultifractal2D(Noise2D& noise, double scale, double offset = 1.0, double gain = 1.0, std::size_t octaves = 8, double lacunarity = 2.0, double persistence = 0.5, double dimension = 1.0);
534 
535  virtual double getValue(double x, double y) override;
536 
537  private:
538  Noise2D& m_noise;
539  double m_scale;
540  double m_offset;
541  double m_gain;
542  std::size_t m_octaves;
543  double m_lacunarity;
544  double m_persistence;
545  double m_dimension;
546  };
547 
548  /**
549  * @ingroup core
550  * @brief An adapter that make a 2D noise from a 3D noise
551  *
552  * The 3D point is taken on a plane defined by a normal and a point. The
553  * 3D point has the same @f$ x @f$ and @f$ y @f$ coordinates as the
554  * 2D point, and the plane is used to determine the @f$ z @f$ coordinate.
555  *
556  * By default, the @f$ z = 0 @f$ plane is used.
557  */
559  public:
560  /**
561  * @brief Constructor
562  *
563  * @param noise The original 3D noise
564  * @param normal The normal of the 3D plane
565  * @param point The point of the 3D plane
566  */
567  Noise3DTo2DAdapter(Noise3D& noise, Vector3d normal = Vector3d(0.0, 0.0, 1.0), Vector3d point = Vector3d(0.0, 0.0, 0.0));
568 
569  virtual double getValue(double x, double y) override;
570 
571  private:
572  Noise3D& m_noise;
573  Vector3d m_normal;
574  Vector3d m_point;
575  };
576 
577 #ifndef DOXYGEN_SHOULD_SKIP_THIS
578 }
579 #endif
580 }
581 
582 #endif // GF_NOISES_H
A random engine.
Definition: Random.h:43
ValueNoise2D(Random &random, Step< double > step)
Constructor.
virtual double getValue(double x, double y) override
Take a 2D noise value.
RidgedMultifractal2D(Noise2D &noise, double scale, double offset=1.0, double gain=1.0, std::size_t octaves=8, double lacunarity=2.0, double persistence=0.5, double dimension=1.0)
Constructor.
WorleyNoise2D(Random &random, std::size_t count, Distance2< double > distance, std::vector< double > coeffs)
Constructor.
virtual double getValue(double x, double y) override
Take a 2D noise value.
virtual double getValue(double x, double y) override
Take a 2D noise value.
virtual double getValue(double x, double y) override
Take a 2D noise value.
virtual double getValue(double x, double y) override
Take a 2D noise value.
WaveletNoise3D(Random &random, std::ptrdiff_t n=32)
Constructor.
virtual double getValue(double x, double y) override
Take a 2D noise value.
Gradient 3D noise.
Definition: Noises.h:109
Gradient 2D noise.
Definition: Noises.h:80
FractalNoise3D(Noise3D &noise, double scale, std::size_t octaves=8, double lacunarity=2.0, double persistence=0.5, double dimension=1.0)
Constructor.
virtual double getValue(double x, double y) override
Take a 2D noise value.
HeteroTerrain2D(Noise2D &noise, double scale, double offset=0.0, std::size_t octaves=8, double lacunarity=2.0, double persistence=0.5, double dimension=1.0)
Constructor.
virtual double getValue(double x, double y) override
Take a 2D noise value.
2D A noise function
Definition: Noise.h:35
3D A noise function
Definition: Noise.h:71
virtual double getValue(double x, double y, double z) override
Take a 3D noise value.
Ridged Multifractal 2D noise.
Definition: Noises.h:519
OpenSimplex3D noise.
Definition: Noises.h:349
GradientNoise2D(Random &random, Step< double > step)
Constructor.
OpenSimplex 2D noise.
Definition: Noises.h:323
virtual double getValue(double x, double y) override
Take a 2D noise value.
virtual double getValue(double x, double y) override
Take a 2D noise value.
GradientNoise3D(Random &random, Step< double > step)
Constructor.
HybridMultifractal2D(Noise2D &noise, double scale, double offset=0.0, std::size_t octaves=8, double lacunarity=2.0, double persistence=0.5, double dimension=1.0)
Constructor.
OpenSimplexNoise3D(Random &random)
Constructor.
PerlinNoise3D(Random &random, double scale, std::size_t octaves=8)
Constructor.
The namespace for gf classes.
Definition: Action.h:34
PerlinNoise2D(Random &random, double scale, std::size_t octaves=8)
Constructor.
Perlin 2D noise.
Definition: Noises.h:238
Perlin 3D noise.
Definition: Noises.h:265
virtual double getValue(double x, double y, double z) override
Take a 3D noise value.
virtual double getValue(double x, double y, double z) override
Take a 3D noise value.
FractalNoise2D(Noise2D &noise, double scale, std::size_t octaves=8, double lacunarity=2.0, double persistence=0.5, double dimension=1.0)
Constructor.
virtual double getValue(double x, double y, double z) override
Take a 3D noise value.
Fractal 3D noise.
Definition: Noises.h:203
virtual double getValue(double x, double y) override
Take a 2D noise value.
Fractal 2D noise.
Definition: Noises.h:168
OpenSimplexNoise2D(Random &random)
Constructor.
virtual double getValue(double x, double y) override
Take a 2D noise value.
Noise3DTo2DAdapter(Noise3D &noise, Vector3d normal=Vector3d(0.0, 0.0, 1.0), Vector3d point=Vector3d(0.0, 0.0, 0.0))
Constructor.
Wavelet 3D noise.
Definition: Noises.h:372
An adapter that make a 2D noise from a 3D noise.
Definition: Noises.h:558
Value 2D noise.
Definition: Noises.h:50
SimplexNoise2D(Random &random)
Constructor.
Hybrid Multifractal 2D noise.
Definition: Noises.h:487
Simplex 2D noise.
Definition: Noises.h:296
#define GF_API
Definition: Portability.h:35
virtual double getValue(double x, double y) override
Take a 2D noise value.
Multifractal2D(Noise2D &noise, double scale, std::size_t octaves=8, double lacunarity=2.0, double persistence=0.5, double dimension=1.0)
Constructor.
Better gradient 2D noise.
Definition: Noises.h:141
Multi Fractal 2D noise.
Definition: Noises.h:424
virtual double getValue(double x, double y, double z) override
Take a 3D noise value.
BetterGradientNoise2D(Random &random)
Constructor.
Hetero Terrain 2D noise.
Definition: Noises.h:455