Generator - Implementing parameters for various ore generations, refactoring and documenting functions.
This commit is contained in:
@@ -14,34 +14,122 @@ namespace CaveGame::Core
|
||||
class Generator
|
||||
{
|
||||
public:
|
||||
static constexpr int PrecomputedWhiteNoiseResolution = 2048;
|
||||
/// Defines the sample count for the pre-generated RNG lookup table.
|
||||
static constexpr int PrecomputedWhiteNoiseResolution = 2048;
|
||||
/// Shifts the ground-level of terrain vertically by this many tiles.
|
||||
|
||||
#pragma region Surface Parameters
|
||||
static constexpr float BaseSurfaceLvl = 100.f;
|
||||
|
||||
static constexpr float HeightMapHighPassAmplitude = 700.f;
|
||||
static constexpr float HeightMapHighPassScale = 700.f;
|
||||
static constexpr float HeightMapLowPassAmplitude = 85.f;
|
||||
static constexpr float HeightMapLowPassScale = 64.f;
|
||||
static constexpr float TopSoilDepth = 345.f;
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Cave Parameters
|
||||
|
||||
static constexpr float CaveInputScale = 800.f;
|
||||
static constexpr float CaveOutputScale = 1.20f;
|
||||
static constexpr float CaveErosionRange = 0.040f;
|
||||
static constexpr float CaveWhiteNoise = 0.002f;
|
||||
static constexpr float CaveAdditiveInputScale = 80.f;
|
||||
static constexpr float CaveAdditiveOutputScale = 0.45f;
|
||||
static constexpr float SurfaceCaveShrinkDepth = 100;
|
||||
static constexpr float SurfaceCaveShrinkFactor = 1.5f;
|
||||
|
||||
#pragma endregion
|
||||
#pragma region Ore Vein Parameters
|
||||
|
||||
static constexpr Vector2 ClayVeinHiPassScale = {200.f, 205.f};
|
||||
static constexpr float ClayVeinHiPassOffset = 0.f;
|
||||
static constexpr float ClayVeinHiPassOutputScale = 2.2f;
|
||||
static constexpr float ClayVeinHiPassOffset = 0.f;
|
||||
static constexpr float ClayVeinHiPassOutputScale = 2.2f;
|
||||
|
||||
static constexpr Vector2 ClayVeinLoPassScale = {17.f, 15.f};
|
||||
static constexpr float ClayVeinLoPassOffset = 420.f;
|
||||
static constexpr float ClayVeinLoPassOutputScale = 1.2f;
|
||||
static constexpr float ClayVeinLoPassOffset = 420.f;
|
||||
static constexpr float ClayVeinLoPassOutputScale = 1.2f;
|
||||
|
||||
static constexpr float ClayVeinNoise = 0.175f;
|
||||
static constexpr float ClayVeinNoise = 0.175f;
|
||||
static constexpr float ClayVeinRampFactor = 2.f;
|
||||
|
||||
static constexpr float ClayVeinRampFactor = 2.f;
|
||||
static constexpr Vector2 SiltVeinHiPassScale = {220.f, 205.f};
|
||||
static constexpr float SiltVeinHiPassOffset = 5.f;
|
||||
static constexpr float SiltVeinHiPassOutputScale = 2.2f;
|
||||
|
||||
static constexpr Vector2 SiltVeinLoPassScale = {27.f, 25.f};
|
||||
static constexpr float SiltVeinLoPassOffset = 422.f;
|
||||
static constexpr float SiltVeinLoPassOutputScale = 1.25f;
|
||||
|
||||
static constexpr float SiltVeinNoise = 0.175f;
|
||||
static constexpr float SiltVeinRampFactor = 2.f;
|
||||
|
||||
static constexpr Vector2 StoneVeinHiPassScale = {30.f, 30.f};
|
||||
static constexpr float StoneVeinHiPassOffset = 666.f;
|
||||
static constexpr float StoneVeinHiPassOutputScale = 2.4f;
|
||||
|
||||
static constexpr Vector2 StoneVeinLoPassScale = {220.f, 220.f};
|
||||
static constexpr float StoneVeinLoPassOffset = 0.5f;
|
||||
static constexpr float StoneVeinLoPassOutputScale = 1.75f;
|
||||
|
||||
static constexpr float StoneVeinNoise = 0.25f;
|
||||
static constexpr float StoneVeinRampFactor = 1.75f;
|
||||
|
||||
static constexpr Vector2 DirtVeinHiPassScale = {30.f, 30.f};
|
||||
static constexpr float DirtVeinHiPassOffset = 12.f;
|
||||
static constexpr float DirtVeinHiPassOutputScale = 1.35f;
|
||||
|
||||
static constexpr Vector2 DirtVeinLoPassScale = {90.f, 90.f};
|
||||
static constexpr float DirtVeinLoPassOffset = 0.5f;
|
||||
static constexpr float DirtVeinLoPassOutputScale = 0.75f;
|
||||
|
||||
static constexpr float DirtVeinNoise = 0.05f;
|
||||
static constexpr float DirtVeinRampFactor = 0.5f;
|
||||
|
||||
static constexpr Vector2 CoalVeinHiPassScale = {30.f, 30.f};
|
||||
static constexpr float CoalVeinHiPassOffset = 12.f;
|
||||
static constexpr float CoalVeinHiPassOutputScale = 1.35f;
|
||||
|
||||
static constexpr Vector2 CoalVeinLoPassScale = {90.f, 90.f};
|
||||
static constexpr float CoalVeinLoPassOffset = 0.5f;
|
||||
static constexpr float CoalVeinLoPassOutputScale = 0.75f;
|
||||
|
||||
static constexpr float CoalVeinNoise = 0.05f;
|
||||
static constexpr float CoalVeinRampFactor = 0.5f;
|
||||
|
||||
static constexpr Vector2 CopperVeinHiPassScale = {30.f, 30.f};
|
||||
static constexpr float CopperVeinHiPassOffset = 12.f;
|
||||
static constexpr float CopperVeinHiPassOutputScale = 1.35f;
|
||||
|
||||
static constexpr Vector2 CopperVeinLoPassScale = {90.f, 90.f};
|
||||
static constexpr float CopperVeinLoPassOffset = 0.5f;
|
||||
static constexpr float CopperVeinLoPassOutputScale = 0.75f;
|
||||
|
||||
static constexpr float CopperVeinNoise = 0.05f;
|
||||
static constexpr float CopperVeinRampFactor = 0.5f;
|
||||
|
||||
static constexpr Vector2 TinVeinHiPassScale = {30.f, 30.f};
|
||||
static constexpr float TinVeinHiPassOffset = 12.f;
|
||||
static constexpr float TinVeinHiPassOutputScale = 1.35f;
|
||||
|
||||
static constexpr Vector2 TinVeinLoPassScale = {90.f, 90.f};
|
||||
static constexpr float TinVeinLoPassOffset = 0.5f;
|
||||
static constexpr float TinVeinLoPassOutputScale = 0.75f;
|
||||
|
||||
static constexpr float TinVeinNoise = 0.05f;
|
||||
static constexpr float TinVeinRampFactor = 0.5f;
|
||||
|
||||
static constexpr Vector2 IronVeinHiPassScale = {30.f, 30.f};
|
||||
static constexpr float IronVeinHiPassOffset = 12.f;
|
||||
static constexpr float IronVeinHiPassOutputScale = 1.35f;
|
||||
|
||||
static constexpr Vector2 IronVeinLoPassScale = {90.f, 90.f};
|
||||
static constexpr float IronVeinLoPassOffset = 0.5f;
|
||||
static constexpr float IronVeinLoPassOutputScale = 0.75f;
|
||||
|
||||
static constexpr float IronVeinNoise = 0.05f;
|
||||
static constexpr float IronVeinRampFactor = 0.5f;
|
||||
#pragma endregion
|
||||
|
||||
public:
|
||||
Generator() = default;
|
||||
@@ -52,8 +140,18 @@ namespace CaveGame::Core
|
||||
|
||||
float Octave(int wx, int wy, float hScale, float vScale, float offset, float outputScale, int octaves);
|
||||
|
||||
float ComputeHiLoPass(float hi, float lo, float offset);
|
||||
/// Returns the sum of hi+lo and (hi*lo) / div, resulting in something approximating noise iterated in 2 octaves.
|
||||
float AddSumAndPartialProduct(float hi, float lo, float div);
|
||||
|
||||
TileID HiLoSelect(float pass, float upperBound, float lowerBound, TileID hiSelect, TileID loSelect, TileID fallback);
|
||||
|
||||
/// This function returns a floating point number (Usually in the range [-1, 1]) to be used as a condition for
|
||||
/// whether ores should spawn at this location, given a set of noise parameters.
|
||||
/// Ores are generated by computing two Perlin Noise passes, taking the sum of adding and multiplying, then adding in random noise.
|
||||
/// Hi-Pass is used to define macro (larger-scale) features of ore veins, and Lo-Pass adds minor detailing for a more organic appearance.
|
||||
float ComputeOre(int wx, int wy, const Vector2& hiPass, const Vector2& loPass, float hiOffset, float loOffset,
|
||||
float hiScale, float loScale, float noise, float ramp);
|
||||
|
||||
TileID ComputeTile(int wx, int wy);
|
||||
void FirstPass(Chunk& chunk);
|
||||
|
||||
|
@@ -17,14 +17,11 @@ namespace CaveGame::Core
|
||||
{
|
||||
precomputed_white_noise_2D[x][y] = rng.Float01Incl();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
float Generator::ComputeDepth(int wx, int wy)
|
||||
{
|
||||
int tile_id = 0;
|
||||
|
||||
// this looks almost the same as the octave noise but with significantly less expense?
|
||||
//float height_map_low_pass = perlin.Noise(wx / HeightMapHighPassScale, 0.f, 0.25f) * HeightMapHighPassAmplitude;
|
||||
@@ -55,11 +52,6 @@ namespace CaveGame::Core
|
||||
return perlin.Noise(wx / hScale, wy / vScale, offset) * outputScale;
|
||||
}
|
||||
|
||||
float Generator::Perlin2(int wx, int wy, const Vector2 hiScale, const Vector2 loScale, Vector2 offset, Vector2 outputScale)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
float Generator::Octave(int wx, int wy, float hScale, float vScale, float offset, float outputScale, int octaves) {
|
||||
|
||||
float noise = 0;
|
||||
@@ -78,8 +70,8 @@ namespace CaveGame::Core
|
||||
|
||||
|
||||
|
||||
float Generator::ComputeHiLoPass(float hi, float lo, float offset) {
|
||||
return hi + lo + ((hi * lo) / offset);
|
||||
float Generator::AddSumAndPartialProduct(float hi, float lo, float div) {
|
||||
return hi + lo + ((hi * lo) / div);
|
||||
}
|
||||
|
||||
TileID Generator::HiLoSelect(float pass, float upperBound, float lowerBound, TileID hiSelect, TileID loSelect, TileID fallback) {
|
||||
@@ -92,31 +84,28 @@ namespace CaveGame::Core
|
||||
return fallback;
|
||||
}
|
||||
|
||||
//bool Generator::CaveTest() { }
|
||||
|
||||
|
||||
float Generator::ComputeOre(int wx, int wy, const Vector2& hiPass, const Vector2& loPass, float hiOffset, float loOffset, float hiScale, float loScale, float noise, float ramp)
|
||||
{
|
||||
float pass_1 = Perlin(wx, wy, hiPass.x, hiPass.y, hiOffset, hiScale);
|
||||
float pass_2 = Perlin(wx, wy, loPass.x, loPass.y, loOffset, loScale);
|
||||
float rng = GetPrecomputedWhiteNoise2D(wx, wy)*noise;
|
||||
return AddSumAndPartialProduct(pass_1, pass_2, ramp) - rng;
|
||||
}
|
||||
|
||||
//float Generator::ComputeLiquidPool() {}
|
||||
|
||||
|
||||
/// Calculates the tile to be placed at a given x,y coordinates during the first terrain iteration.
|
||||
TileID Generator::ComputeTile(int wx, int wy) {
|
||||
float depth = ComputeDepth(wx, wy);
|
||||
TileID base = HeightMap(depth, wx, wy);
|
||||
|
||||
/*float cave_high_sx = 48.f;
|
||||
float cave_high_sy = 48.f;
|
||||
float cave_low_sx = 192.f;
|
||||
float cave_low_sy = 192.f;
|
||||
float cave_high_pass = perlin.Noise(wx / cave_high_sx, wy / cave_high_sy, 1.f);
|
||||
float cave_low_pass = perlin.Noise(wx / cave_low_sx, wy / cave_low_sy, 0.5f);
|
||||
|
||||
float cave_sum = cave_high_pass + cave_low_pass;
|
||||
float cave_product = cave_high_pass * cave_low_pass;
|
||||
|
||||
if (cave_sum > -0.05f && 0.2f > cave_sum && cave_product > -0.15f && 0.15f > cave_product)
|
||||
{
|
||||
return Core::AIR;
|
||||
} else { return base; }*/
|
||||
|
||||
//float cave_erosion = perlin.Noise(wx / CaveInputScale, wy / CaveInputScale, 0.f) * CaveOutputScale;
|
||||
float cave_erosion = Perlin(wx, wy, CaveInputScale, CaveInputScale, 0.f, CaveOutputScale);
|
||||
|
||||
float rng = GetPrecomputedWhiteNoise2D(wx, wy)*0.002;
|
||||
float rng = GetPrecomputedWhiteNoise2D(wx, wy)*CaveWhiteNoise;
|
||||
|
||||
//float cave_addition = perlin.Noise(wx / CaveAdditiveInputScale, wy / CaveAdditiveInputScale, 0.f)*CaveAdditiveOutputScale;
|
||||
float cave_addition = Perlin(wx, wy, CaveAdditiveInputScale, CaveAdditiveInputScale, 0.25f, CaveAdditiveOutputScale);
|
||||
@@ -137,49 +126,91 @@ namespace CaveGame::Core
|
||||
|
||||
if (depth > 1) {
|
||||
// Ore computation
|
||||
float clay_pass_1 = Perlin(wx, wy, ClayVeinHiPassScale.x, ClayVeinHiPassScale.y, ClayVeinHiPassOffset, ClayVeinHiPassOutputScale);
|
||||
float clay_pass_2 = Perlin(wx, wy, ClayVeinLoPassScale.x, ClayVeinLoPassScale.y, ClayVeinLoPassOffset, ClayVeinLoPassOutputScale);
|
||||
float clay_rng = GetPrecomputedWhiteNoise2D(wx, wy)*ClayVeinNoise;
|
||||
float clay_pass = ComputeHiLoPass(clay_pass_1, clay_pass_2, ClayVeinRampFactor) - clay_rng;
|
||||
|
||||
// Chunks of clay and dirt.
|
||||
float clay_pass = ComputeOre(wx, wy, ClayVeinHiPassScale, ClayVeinLoPassScale, ClayVeinHiPassOffset, ClayVeinLoPassOffset,
|
||||
ClayVeinHiPassOutputScale, ClayVeinLoPassOutputScale, ClayVeinNoise, ClayVeinRampFactor);
|
||||
|
||||
// Yes, sometimes we re-use a pass to generate another tile entirely. Why?
|
||||
// We don't need the full parameter space for clay generation, as it's rarer, and it gives
|
||||
// more variety to dirt blob generation, for example.
|
||||
if (clay_pass > 0.85f) { return TileID::CLAY; }
|
||||
if (clay_pass < -0.75f) { return TileID::DIRT; }
|
||||
|
||||
|
||||
float silt_pass_1 = perlin.Noise(wx / 220.f, wy / 205.f, 5.f) * 2.2f;
|
||||
float silt_pass_2 = perlin.Noise(wx / 27.f, wy / 25.f, 422.f) * 1.25f;
|
||||
|
||||
//float rng = GetPrecomputedWhiteNoise2D(wx, wy)*0.175;
|
||||
|
||||
float silt_pass = silt_pass_1 + silt_pass_2 + ((silt_pass_1 * silt_pass_2) / 2.f) - rng;
|
||||
// Chunks of silt and dirt.
|
||||
float silt_pass = ComputeOre(wx, wy, SiltVeinHiPassScale, SiltVeinLoPassScale, SiltVeinHiPassOffset, SiltVeinLoPassOffset,
|
||||
SiltVeinHiPassOutputScale, SiltVeinLoPassOutputScale, SiltVeinNoise, SiltVeinRampFactor);
|
||||
|
||||
if (silt_pass > 0.85f) { return TileID::SILT; }
|
||||
|
||||
if (silt_pass < -0.75f) { return TileID::DIRT; }
|
||||
|
||||
//float stone_pass_1 = perlin.Noise(wx / 30.f, wy / 30.f, 666.f) * 2.4f;
|
||||
//float stone_pass_2 = perlin.Noise(wx / 220.f, wy / 220.f, 0.5f) * 1.75f;
|
||||
//float stone_pass = stone_pass_1 + stone_pass_2 + (stone_pass_1 * stone_pass_2 / 1.75f) + (rng*1.5f);
|
||||
|
||||
float stone_pass_1 = perlin.Noise(wx / 30.f, wy / 30.f, 666.f) * 2.4f;
|
||||
float stone_pass_2 = perlin.Noise(wx / 220.f, wy / 220.f, 0.5f) * 1.75f;
|
||||
|
||||
float stone_pass = stone_pass_1 + stone_pass_2 + (stone_pass_1 * stone_pass_2 / 1.75f) + (rng*1.5f);
|
||||
|
||||
// Chunks of stone.
|
||||
float stone_pass = ComputeOre(wx, wy, StoneVeinHiPassScale, StoneVeinLoPassScale, StoneVeinHiPassOffset, StoneVeinLoPassOffset,
|
||||
StoneVeinHiPassOutputScale, StoneVeinLoPassOutputScale, StoneVeinNoise, StoneVeinRampFactor);
|
||||
|
||||
// Chunks of stone
|
||||
|
||||
if (stone_pass > 0.7f) { return TileID::STONE; }
|
||||
if (stone_pass < -0.7f) { return TileID::STONE; }
|
||||
|
||||
|
||||
float dirt_pass_1 = perlin.Noise(wx / 30.f, wy / 30.f, 12.f) * 1.35f;
|
||||
float dirt_pass_2 = perlin.Noise(wx / 90.f, wy / 90.f, 0.5f) * 0.75f;
|
||||
|
||||
float dirt_pass = dirt_pass_1 + dirt_pass_2;
|
||||
//float dirt_pass_1 = perlin.Noise(wx / 30.f, wy / 30.f, 12.f) * 1.35f;
|
||||
//float dirt_pass_2 = perlin.Noise(wx / 90.f, wy / 90.f, 0.5f) * 0.75f;
|
||||
//float dirt_pass = dirt_pass_1 + dirt_pass_2;
|
||||
|
||||
// Chunks of dirt
|
||||
if (-0.65 > dirt_pass && dirt_pass < 0.65f) {
|
||||
return TileID::DIRT;
|
||||
float dirt_pass = ComputeOre(wx, wy, DirtVeinHiPassScale, DirtVeinLoPassScale, DirtVeinHiPassOffset, DirtVeinLoPassOffset,
|
||||
DirtVeinHiPassOutputScale, DirtVeinLoPassOutputScale, DirtVeinNoise, DirtVeinRampFactor);
|
||||
|
||||
if (-0.65 > dirt_pass && dirt_pass < 0.65f) { return TileID::DIRT; }
|
||||
|
||||
// Coal veins
|
||||
float coal_pass = ComputeOre(wx, wy, CoalVeinHiPassScale, CoalVeinLoPassScale, CoalVeinHiPassOffset, CoalVeinLoPassOffset,
|
||||
CoalVeinHiPassOutputScale, CoalVeinLoPassOutputScale, CoalVeinNoise, CoalVeinRampFactor);
|
||||
|
||||
if (coal_pass > 0.75f) { return TileID::COAL_ORE; }
|
||||
|
||||
// Copper ore veins
|
||||
float copper_pass = ComputeOre(wx, wy, CopperVeinHiPassScale, CopperVeinLoPassScale, CopperVeinHiPassOffset, CopperVeinLoPassOffset,
|
||||
CopperVeinHiPassOutputScale, CopperVeinLoPassOutputScale, CopperVeinNoise, CopperVeinRampFactor);
|
||||
|
||||
if (copper_pass > 0.8f) { return TileID::COPPER_ORE; }
|
||||
|
||||
// Tin ore veins
|
||||
float tin_pass = ComputeOre(wx, wy, TinVeinHiPassScale, TinVeinLoPassScale, TinVeinHiPassOffset, TinVeinLoPassOffset,
|
||||
TinVeinHiPassOutputScale, TinVeinLoPassOutputScale, TinVeinNoise, TinVeinRampFactor);
|
||||
|
||||
if (tin_pass > 0.85) { return TileID::TIN_ORE; }
|
||||
|
||||
// Iron ore veins
|
||||
float iron_pass = ComputeOre(wx, wy, IronVeinHiPassScale, IronVeinLoPassScale, IronVeinHiPassOffset, IronVeinLoPassOffset,
|
||||
IronVeinHiPassOutputScale, IronVeinLoPassOutputScale, IronVeinNoise, IronVeinRampFactor);
|
||||
|
||||
|
||||
if (depth > 1000) {
|
||||
// Lead ore veins
|
||||
|
||||
// Silver ore veins
|
||||
|
||||
// Tungsten ore veins
|
||||
|
||||
// Gold ore veins
|
||||
}
|
||||
|
||||
if (depth > 10000) {
|
||||
// Platinum ore veins
|
||||
|
||||
// Cobalt ore veins
|
||||
|
||||
// Titanium ore veins
|
||||
|
||||
// Uranium ore veins
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user