Class TCastleTerrainNoise
Unit
Declaration
type TCastleTerrainNoise = class(TCastleTerrainData)
Description
Terrain heights are generated from a smooth noise, combined with some terrain-specific improvements (Heterogeneous).
We take the noise (integer noise, i.e. hash), smooth it (how well, and how fast — see Interpolation and Blur), and add several functions ("octaves") of such noise (with varying frequency and amplitude) together. This is the kind of noise used to synthesize textures, terrains and all other procedural stuff.
For more info about math inside:
[http://en.wikipedia.org/wiki/Fractional_Brownian_motion]. This is the idea of summing up octaves of noise. Ken Musgrave's dissertation has a lot of info and interesting references: [http://www.kenmusgrave.com/dissertation.html]
Blender's source code is informative, interesting file is blender/source/blender/blenlib/intern/noise.c
The simplest practical introduction to the idea is on [http://freespace.virgin.net/hugo.elias/models/m_perlin.htm]. It describes how to get nice noise very easily, and my approach follows theirs.
Hierarchy
- TObject
- TPersistent
- TComponent
- TCastleComponent
- TCastleTerrainData
- TCastleTerrainNoise
Overview
Nested Types
TNoise2DMethod = function (const X, Y: Single; const Seed: Cardinal): Single; |
Fields
nested const DefaultOctaves = 4.0; |
|
nested const DefaultSmoothnes = 2.0; |
|
nested const DefaultAmplitude = 8.0; |
|
nested const DefaultFrequency = 0.05; |
|
nested const DefaultInterpolation = niCosine; |
|
nested const DefaultBlur = false; |
|
nested const DefaultHeterogeneous = 0.5; |
Methods
constructor Create(AOwner: TComponent); override; |
|
function Height(const Coord, TexCoord: TVector2): Single; override; |
|
function PropertySections(const PropertyName: String): TPropertySections; override; |
Properties
property Octaves: Single read FOctaves write SetOctaves default DefaultOctaves; |
|
property Smoothness: Single read FSmoothness write SetSmoothness default DefaultSmoothnes; |
|
property Amplitude: Single read FAmplitude write SetAmplitude default DefaultAmplitude; |
|
property Frequency: Single read FFrequency write SetFrequency default DefaultFrequency; |
|
property Interpolation: TNoiseInterpolation
read FInterpolation write SetInterpolation default DefaultInterpolation; |
|
property Blur: Boolean read FBlur write SetBlur default DefaultBlur; |
|
property Seed: Cardinal read FSeed write SetSeed default 0; |
|
property Heterogeneous: Single
read FHeterogeneous write SetHeterogeneous default DefaultHeterogeneous; |
Description
Nested Types
TNoise2DMethod = function (const X, Y: Single; const Seed: Cardinal): Single; |
|
Fields
nested const DefaultOctaves = 4.0; |
|
nested const DefaultSmoothnes = 2.0; |
|
nested const DefaultAmplitude = 8.0; |
|
nested const DefaultFrequency = 0.05; |
|
nested const DefaultInterpolation = niCosine; |
|
nested const DefaultBlur = false; |
|
nested const DefaultHeterogeneous = 0.5; |
|
Methods
constructor Create(AOwner: TComponent); override; |
|
function Height(const Coord, TexCoord: TVector2): Single; override; |
|
function PropertySections(const PropertyName: String): TPropertySections; override; |
|
Properties
property Octaves: Single read FOctaves write SetOctaves default DefaultOctaves; |
|
Number of noise functions to sum. This linearly affects the time for Height call, so don't make it too much. Usually ˜a few are Ok. (The fact that it's a float is just a simple trick to allow smooth transitions from x to x+1. In fact, it's executed like Trunc( Reasonable values are roughly between 0..20. |
property Smoothness: Single read FSmoothness write SetSmoothness default DefaultSmoothnes; |
|
How noise amplitude changes, when frequency doubles. When we double frequency, amplitude is divided by this. Smaller values <=> larger frequency noise is more visible, so terrain is less smooth (more noisy). This is elsewhere called fractal increment, fractal dimension parameter, "H", spectral exponent (see e.g. Blender sources, Musgrave's dissertation). Do not confuse this with "lacunarity" (how frequency changes in each octave), that is simply hardcoded to 2.0 in our code currently. In [http://freespace.virgin.net/hugo.elias/models/m_perlin.htm], the inverse of this 1/ I decided to call it " Value equal 1.0 means that amplitude doesn't change at all, each noise frequency is visible the same, so in effect you will just see a lot of noise. And values < 1.0 are really nonsense, they make more frequency noise even more visible, which means that the terrain is dominated by noise. Reasonable values are roughly between 1..10. |
property Amplitude: Single read FAmplitude write SetAmplitude default DefaultAmplitude; |
|
Amplitude and frequency of the first noise octave. Amplitude scales the height of the result, and Frequency scales the size of the bumps. |
property Frequency: Single read FFrequency write SetFrequency default DefaultFrequency; |
|
property Interpolation: TNoiseInterpolation
read FInterpolation write SetInterpolation default DefaultInterpolation; |
|
How integer noise is interpolated to get smooth float noise. Setting this to niNone turns off Using niLinear (means "bilinear", since this is 2D case) is also usually bad. Unless you use octaves of really high frequencies, usually sharp edges / flat in-betweens will be visible. Using niCosine in right now the best. Using niSpline is even better looking (usese Catmull-Rom splines, which are special case of cubic Hermite spline, see http://en.wikipedia.org/wiki/Cubic_Hermite_spline, http://en.wikipedia.org/wiki/Bicubic_interpolation). But it's more time consuming under current implementation. |
property Blur: Boolean read FBlur write SetBlur default DefaultBlur; |
|
Resulting noise octaves may be blurred. This helps to remove the inherent vertical/horizontal directionality in our 2D noise (it also makes it more smooth, since that's what blurring is about; you may want to increase Frequency * 2 to balance this). This is independent from Interpolation. Although the need for Note about [http://freespace.virgin.net/hugo.elias/models/m_perlin.htm]: this "blurring" is called "smoothing" there. I call it blurring, as it seems more precise to me. |
property Seed: Cardinal read FSeed write SetSeed default 0; |
|
Determines the random seeds used when generating the terrain. |
property Heterogeneous: Single
read FHeterogeneous write SetHeterogeneous default DefaultHeterogeneous; |
|
If non-zero, then we generate terrain using More precisely, this means that we accumulate multiplied previous noise, at each step dividing this accumulated result by This is called "threshold" in Musgrave's dissertation (see algorithm in section 2.3.2.5 "A Large Scale Terrain Model"). Reasonable values for this are between 0..2. |
Generated by PasDoc 0.16.0.