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:

Hierarchy

Overview

Nested Types

Published TNoise2DMethod = function (const X, Y: Single; const Seed: Cardinal): Single;

Fields

Public nested const DefaultOctaves = 4.0;
Public nested const DefaultSmoothnes = 2.0;
Public nested const DefaultAmplitude = 8.0;
Public nested const DefaultFrequency = 0.05;
Public nested const DefaultInterpolation = niCosine;
Public nested const DefaultBlur = false;
Public nested const DefaultHeterogeneous = 0.5;

Methods

Public constructor Create(AOwner: TComponent); override;
Public function Height(const Coord, TexCoord: TVector2): Single; override;
Public function PropertySections(const PropertyName: String): TPropertySections; override;

Properties

Published property Octaves: Single read FOctaves write SetOctaves default DefaultOctaves;
Published property Smoothness: Single read FSmoothness write SetSmoothness default DefaultSmoothnes;
Published property Amplitude: Single read FAmplitude write SetAmplitude default DefaultAmplitude;
Published property Frequency: Single read FFrequency write SetFrequency default DefaultFrequency;
Published property Interpolation: TNoiseInterpolation read FInterpolation write SetInterpolation default DefaultInterpolation;
Published property Blur: Boolean read FBlur write SetBlur default DefaultBlur;
Published property Seed: Cardinal read FSeed write SetSeed default 0;
Published property Heterogeneous: Single read FHeterogeneous write SetHeterogeneous default DefaultHeterogeneous;

Description

Nested Types

Published TNoise2DMethod = function (const X, Y: Single; const Seed: Cardinal): Single;
 

Fields

Public nested const DefaultOctaves = 4.0;
 
Public nested const DefaultSmoothnes = 2.0;
 
Public nested const DefaultAmplitude = 8.0;
 
Public nested const DefaultFrequency = 0.05;
 
Public nested const DefaultInterpolation = niCosine;
 
Public nested const DefaultBlur = false;
 
Public nested const DefaultHeterogeneous = 0.5;
 

Methods

Public constructor Create(AOwner: TComponent); override;
 
Public function Height(const Coord, TexCoord: TVector2): Single; override;
 
Public function PropertySections(const PropertyName: String): TPropertySections; override;
 

Properties

Published 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(Octaves) * some noises + Frac(Octaves) * some last noise.)

Reasonable values are roughly between 0..20.

Published 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/Smoothness is called "Persistence".

I decided to call it "Smoothness", since this is the practical intuitive meaning.

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.

Published 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.

Published property Frequency: Single read FFrequency write SetFrequency default DefaultFrequency;
 
Published 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 interpolation, which means that your terrain is a sum of a couple of blocky noises — ugly.

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.

Published 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 Blur is most obvious in poor/none interpolation methods (none, linear), it also helps for the nicer interpolation methods (cosine, cubic).

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.

Published property Seed: Cardinal read FSeed write SetSeed default 0;

Determines the random seeds used when generating the terrain.

Published property Heterogeneous: Single read FHeterogeneous write SetHeterogeneous default DefaultHeterogeneous;

If non-zero, then we generate terrain using heterogeneous fBm. Intuitively, the idea is that the terrain details (from higher octaves) are more noisy when ground is higher. This is realistic (debris gathers in lower terrain, smoothing it more).

More precisely, this means that we accumulate multiplied previous noise, at each step dividing this accumulated result by Heterogeneous, and clamping at 1.0. So when Heterogeneous is very small, this always ends up 1.0, and we get normal (homogeneous) generation. When Heterogeneous is larger, the details (at lower ground) are scaled down (terrain is smoother).

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.