50 clampMin_ = std::min(minHeight, maxHeight);
51 clampMax_ = std::max(minHeight, maxHeight);
58float smoother(
float edge0,
float edge1,
float x) {
59 if (edge1 <= edge0)
return x < edge0 ? 0.f : 1.f;
60 const float t = std::clamp((
x - edge0) / (edge1 - edge0), 0.f, 1.f);
61 return t *
t * (3.f - 2.f *
t);
66 const float mx =
x * frequency_;
67 const float my =
y * frequency_;
71 float cx = mx * 0.36f;
72 float cy = my * 0.36f;
73 const float maskWarp = 0.70f;
74 cx += (field_.
perlinNoise(mx * 0.18f + 2.4f, my * 0.18f + 9.1f) - 0.5f) * maskWarp;
75 cy += (field_.
perlinNoise(mx * 0.18f + 7.6f, my * 0.18f + 1.3f) - 0.5f) * maskWarp;
78 if (island_ > 0.f && worldW_ > 0 && worldH_ > 0) {
79 const float nx =
x / float(worldW_) * 2.f - 1.f;
80 const float ny =
y / float(worldH_) * 2.f - 1.f;
81 const float dSq = 1.f - (1.f -
nx *
nx) * (1.f -
ny *
ny);
82 const float dEu = std::sqrt(std::min(1.f,
nx *
nx +
ny *
ny));
83 const float d = std::clamp(dSq * 0.5f + dEu * 0.5f, 0.f, 1.f);
85 macro *= 1.f - island_ * std::pow(
d, 1.25f);
91 (field_.
perlinNoise(mx * 0.42f + 11.f, my * 0.42f + 4.f) - 0.5f) * coastSoft_ * 0.55f;
92 const float sea = 0.54f - continent_ * 0.14f + wiggle;
93 const float land = smoother(sea - coastSoft_ * 0.45f, sea + coastSoft_ * 0.55f, macro);
94 const float inland = land * land;
99 dx += (field_.
fbmPerlin(mx + 19.1f, my + 7.3f, 2) - 0.5f) * warp_;
100 dy += (field_.
fbmPerlin(mx + 5.2f, my + 31.7f, 2) - 0.5f) * warp_;
105 const float mountains =
109 detail = std::pow(std::clamp(
detail, 0.f, 1.f), exponent_);
112 const float shelf = 0.06f + land * 0.32f;
113 const float e = shelf + inland *
detail * 0.62f;
115 float h = base_ + e * amplitude_;
116 if (clamp_)
h = std::clamp(
h, clampMin_, clampMax_);
121 return sample(
float(tileX) + 0.5f,
float(tileY) + 0.5f);
125 return [self = *
this](
float x,
float y) {
return self.sample(
x,
y); };
133 const float wavelength =
params.getFloat(
"wavelength", 0.f);
134 if (wavelength > 0.f) {
135 s.setWavelength(wavelength);
136 }
else if (
params.has(
"frequency")) {
137 s.setFrequency(
params.getFloat(
"frequency", 1.f / 32.f));
139 s.setScale(
params.getFloat(
"scale", 1.f / 32.f));
142 s.setOctaves(
params.getInt(
"octaves", 5));
143 s.setLacunarity(
params.getFloat(
"lacunarity", 2.f));
144 s.setGain(
params.getFloat(
"gain", 0.5f));
145 s.setRidge(
params.getFloat(
"ridge", 0.35f));
146 s.setWarp(
params.getFloat(
"warp", 0.35f));
147 s.setExponent(
params.getFloat(
"exponent", 2.f));
148 s.setContinent(
params.getFloat(
"continent", 0.55f));
149 s.setIsland(
params.getFloat(
"island", 0.38f));
150 s.setCoastSoftness(
params.getFloat(
"coast", 0.12f));
151 s.setBase(
params.getFloat(
"base", 0.f));
152 s.setAmplitude(
params.getFloat(
"amplitude", 1.f));
153 const float lo =
params.getFloat(
"heightMin", 0.f);
154 const float hi =
params.getFloat(
"heightMax", 1.f);
155 s.setClamp(
params.getInt(
"clamp", 1) != 0, lo, hi);
170 bands.
waterMax = std::clamp(
params.getFloat(
"waterMax", 0.25f), 0.f, 1.f);
171 bands.
sandMax = std::clamp(
params.getFloat(
"sandMax", 0.35f), 0.f, 1.f);
172 bands.
grassMax = std::clamp(
params.getFloat(
"grassMax", 0.65f), 0.f, 1.f);
173 bands.
dirtMax = std::clamp(
params.getFloat(
"dirtMax", 0.80f), 0.f, 1.f);
174 bands.
stoneMax = std::clamp(
params.getFloat(
"stoneMax", 0.92f), 0.f, 1.f);
std::array< float, 3 > scale
Owning, typed generation parameters.
Deterministic terrain height sampling (Red Blob Games / Perlin fBm recipe).
float getContinent() const
Returns the continent.
void setOctaves(int octaves)
Sets the octaves.
float getGain() const
Returns the gain.
void setSeed(uint32_t seed)
Sets the seed.
float sample(float x, float y) const
Sample.
float sampleTile(int tileX, int tileY) const
Height at the center of map tile (tileX, tileY).
float getClampMin() const
Returns the clamp min.
void setRidge(float ridge)
Sets the ridge.
void setLacunarity(float lacunarity)
Sets the lacunarity.
void setIsland(float island)
Sets the island.
float getClampMax() const
Returns the clamp max.
void setFrequency(float frequency)
Sets the frequency.
float getFrequency() const
Returns the frequency.
float getRidge() const
Returns the ridge.
uint32_t getSeed() const
Returns the seed.
float getExponent() const
Returns the exponent.
void setGain(float gain)
Sets the gain.
void setWarp(float warp)
Sets the warp.
float getScale() const
Returns the scale.
float getCoastSoftness() const
Returns the coast softness.
bool isClamped() const
True when clamped.
void setContinent(float continent)
Sets the continent.
void setClamp(bool enabled, float minHeight, float maxHeight)
Sets the clamp.
int getWorldWidth() const
Returns the world width.
float getWarp() const
Returns the warp.
void setAmplitude(float amplitude)
Sets the amplitude.
float getBase() const
Returns the base.
void setScale(float scale)
Cycles per world unit (alias of frequency). Default 1/32.
void setCoastSoftness(float softness)
Shore width of the land mask smoothstep. Smaller = cleaner, harder coast.
int getWorldHeight() const
Returns the world height.
float getLacunarity() const
Returns the lacunarity.
void setBase(float base)
Sets the base.
void setWorldSize(int width, int height)
Sets the world size.
void setExponent(float exponent)
Sets the exponent.
static TerrainSampler fromParams(const Params ¶ms)
From params.
float getAmplitude() const
Returns the amplitude.
float getWavelength() const
Returns the wavelength.
std::function< float(float, float)> asFunction() const
Float.
void setWavelength(float wavelength)
Distance per large oscillation. Sets frequency = 1/wavelength.
int getOctaves() const
Returns the octaves.
float getIsland() const
Returns the island.
std::vector< ParamSpec > params
float fbmPerlin(float x, float y, int octaves=4, float lacunarity=2.f, float gain=0.5f) const
Fbm perlin.
float perlinNoise(float x, float y) const
Classic 2D Perlin gradient noise, remapped to [0, 1].
float ridgedPerlin(float x, float y, int octaves=4, float lacunarity=2.f, float gain=0.5f) const
Ridged perlin.
uint32_t semanticAt(float height) const
Semantic at.
static TerrainBands fromParams(const Params ¶ms)
From params.