Clean up NoiseSample class & MapGen, allow heightmap and volume noise.
parent
af9c38abf3
commit
7886dc8097
|
@ -4,8 +4,11 @@
|
|||
|
||||
#include "BiomeDef.h"
|
||||
|
||||
BiomeDef::BiomeDef(const std::string& identifier, unsigned int index, float temperature, float humidity, float roughness,
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock, const std::vector<noise::module::Module*>& modules, glm::vec3 biomeTint) :
|
||||
BiomeDef::BiomeDef(
|
||||
const std::string& identifier, unsigned int index, float temperature, float humidity, float roughness,
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock,
|
||||
const std::vector<noise::module::Module*>& heightmap, const std::vector<noise::module::Module*>& volume,
|
||||
glm::vec3 biomeTint) :
|
||||
|
||||
identifier(identifier),
|
||||
index(index),
|
||||
|
@ -18,6 +21,7 @@ BiomeDef::BiomeDef(const std::string& identifier, unsigned int index, float temp
|
|||
soilBlock(soilBlock),
|
||||
rockBlock(rockBlock),
|
||||
|
||||
modules(modules),
|
||||
heightmap(heightmap),
|
||||
volume(volume),
|
||||
|
||||
biomeTint(biomeTint) {}
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
struct BiomeDef {
|
||||
BiomeDef() = default;
|
||||
BiomeDef(const std::string& identifier, unsigned int index, float temperature, float humidity, float roughness,
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock, const std::vector<noise::module::Module*>& modules, glm::vec3 biomeTint);
|
||||
unsigned int topBlock, unsigned int soilBlock, unsigned int rockBlock,
|
||||
const std::vector<noise::module::Module*>& heightmap, const std::vector<noise::module::Module*>& volume,
|
||||
glm::vec3 biomeTint);
|
||||
|
||||
std::string identifier = "";
|
||||
unsigned int index = 0;
|
||||
|
@ -25,7 +27,8 @@ struct BiomeDef {
|
|||
unsigned int soilBlock = 0;
|
||||
unsigned int rockBlock = 0;
|
||||
|
||||
std::vector<noise::module::Module*> modules;
|
||||
std::vector<noise::module::Module*> heightmap;
|
||||
std::vector<noise::module::Module*> volume;
|
||||
|
||||
glm::vec3 biomeTint {};
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
LocalBiomeAtlas::LocalBiomeAtlas() {
|
||||
//Invalid Biome
|
||||
BiomeDef* invalid = new BiomeDef("invalid", 0, -1, -1, -1, 0, 0, 0, {}, {});
|
||||
BiomeDef* invalid = new BiomeDef("invalid", 0, -1, -1, -1, 0, 0, 0, {}, {}, {});
|
||||
defs.push_back(invalid);
|
||||
defTable.insert({"invalid", 0});
|
||||
}
|
||||
|
|
|
@ -81,34 +81,31 @@ void MapGen::generateChunk(chunk_partials_map& chunks, glm::ivec3 worldPos) {
|
|||
}
|
||||
|
||||
void MapGen::buildDensityMap(MapGenJob* job, glm::ivec3 worldPos) {
|
||||
job->temperature = NoiseSample(temperature, {worldPos.x, 0, worldPos.z}, {4, 1}, true);
|
||||
job->humidity = NoiseSample(humidity, {worldPos.x, 0, worldPos.z}, {4, 1}, true);
|
||||
job->roughness = NoiseSample(roughness, {worldPos.x, 0, worldPos.z}, {4, 1}, true);
|
||||
job->temperature = {}; job->humidity = {}; job->roughness = {};
|
||||
|
||||
// TODO: This is... a travesty. Please stop doing this weird jank insertion into a
|
||||
// noisesample and create a proper constructor or *something*... could probs use a module owo
|
||||
job->temperature.fill([&](glm::ivec3 pos) {
|
||||
return temperature.GetValue(worldPos.x + pos.x / 16.f, 0, worldPos.z + pos.z / 16.f); }, 4);
|
||||
job->humidity.fill([&](glm::ivec3 pos) {
|
||||
return humidity.GetValue(worldPos.x + pos.x / 16.f, 0, worldPos.z + pos.z / 16.f); }, 4);
|
||||
job->roughness.fill([&](glm::ivec3 pos) {
|
||||
return roughness.GetValue(worldPos.x + pos.x / 16.f, 0, worldPos.z + pos.z / 16.f); }, 4);
|
||||
|
||||
auto terrain = NoiseSample({4, 4});
|
||||
NoiseSample volume = {}, heightmap = {};
|
||||
|
||||
float offsetH = 16.f / 4.f;
|
||||
float offsetV = 16.f / 4.f;
|
||||
volume.fill([&](glm::ivec3 pos) {
|
||||
auto& biome = biomes.getBiomeAt(job->temperature.get(pos), job->humidity.get(pos), job->roughness.get(pos));
|
||||
return biome.volume[biome.volume.size() - 1]->GetValue(worldPos.x + pos.x / 16.f, worldPos.y + pos.y / 16.f, worldPos.z + pos.z / 16.f);
|
||||
}, {4, 4});
|
||||
|
||||
for (int i = 0; i <= 4; i++) {
|
||||
for (int j = 0; j <= 4; j++) {
|
||||
for (int k = 0; k <= 4; k++) {
|
||||
glm::vec3 localPos = {(offsetH * i) / 1.01f, (offsetV * j) / 1.01f, (offsetH * k) / 1.01f};
|
||||
glm::vec3 pos = {(worldPos.x * 16 + offsetH * i) / 16.f, (worldPos.y * 16 + offsetV * j) / 16.f, (worldPos.z * 16 + offsetH * k) / 16.f};
|
||||
auto& biome = biomes.getBiomeAt(job->temperature.get(localPos), job->humidity.get(localPos), job->roughness.get(localPos));
|
||||
auto& mod = biome.modules[biome.modules.size() - 1];
|
||||
terrain.set({i, j, k}, static_cast<float>(mod->GetValue(pos.x, pos.y, pos.z)));
|
||||
}
|
||||
}
|
||||
}
|
||||
heightmap.fill([&](glm::ivec3 pos) {
|
||||
auto& biome = biomes.getBiomeAt(job->temperature.get(pos), job->humidity.get(pos), job->roughness.get(pos));
|
||||
return biome.heightmap[biome.heightmap.size() - 1]->GetValue(worldPos.x + pos.x / 16.f, 0, worldPos.z + pos.z / 16.f);
|
||||
}, 4);
|
||||
|
||||
glm::ivec3 lp;
|
||||
for (int m = 0; m < 4096; m++) {
|
||||
Vec::indAssignVec(m, lp);
|
||||
job->density[m] = terrain.get(lp) - (lp.y + worldPos.y * 16);
|
||||
job->density[m] = (volume.get(lp) + heightmap.get(lp)) - (lp.y + worldPos.y * 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,8 +183,6 @@ void MapGen::generateBlocks(chunk_partial& chunk) {
|
|||
chunk.second->biomes.emplace_back(biome.index);
|
||||
}
|
||||
|
||||
// if (chunk.second->blocks[ind] != DefinitionAtlas::INVALID) continue;
|
||||
|
||||
int d = std::floor(chunk.first->depth[m]);
|
||||
unsigned int targetBlock
|
||||
= d <= 1 ? DefinitionAtlas::AIR
|
||||
|
|
|
@ -3,61 +3,65 @@
|
|||
//
|
||||
#include "NoiseSample.h"
|
||||
|
||||
NoiseSample::NoiseSample(glm::ivec2 precision) :
|
||||
prec(precision) {
|
||||
reserveSpace();
|
||||
void NoiseSample::fill(const NoiseSample::fill_function &fun, float precision) {
|
||||
fill(fun, {precision, 1});
|
||||
}
|
||||
|
||||
NoiseSample::NoiseSample(noise::module::Module &module, glm::vec3 chunkPos, glm::ivec2 precision, bool flat) :
|
||||
prec(precision) {
|
||||
reserveSpace();
|
||||
void NoiseSample::fill(const NoiseSample::fill_function &fun, glm::ivec2 precision) {
|
||||
this->precision = precision;
|
||||
reserve();
|
||||
|
||||
float offsetH = 16.f / prec.x;
|
||||
float offsetV = 16.f / prec.y;
|
||||
float offsetH = 16.f / precision.x;
|
||||
float offsetV = 16.f / precision.y;
|
||||
|
||||
for (int i = 0; i <= prec.x; i++) {
|
||||
for (int j = 0; j <= prec.y; j++) {
|
||||
for (int k = 0; k <= prec.x; k++) {
|
||||
glm::vec3 pos = {(chunkPos.x * 16 + offsetH * i) / 16.f,
|
||||
flat ? 0 : (chunkPos.y * 16 + offsetV * j) / 16.f,
|
||||
(chunkPos.z * 16 + offsetH * k) / 16.f};
|
||||
set({i, j, k}, static_cast<float>(module.GetValue(pos.x, pos.y, pos.z)));
|
||||
// Iterate over the array
|
||||
for (int i = 0; i <= precision.x; i++) {
|
||||
for (int j = 0; j <= (precision.y == 1 ? 0 : precision.y); j++) {
|
||||
for (int k = 0; k <= precision.x; k++) {
|
||||
set({i, j, k}, fun({ offsetH * i, offsetV * j, offsetH * k }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseSample::set(glm::ivec3 pos, float value) {
|
||||
data[pos.x][pos.y][pos.z] = value;
|
||||
}
|
||||
float NoiseSample::get(glm::ivec3 localPos) {
|
||||
assert(precision.x != 0);
|
||||
assert(precision.y != 0);
|
||||
|
||||
float NoiseSample::get(const glm::ivec3& pos) {
|
||||
glm::vec3 prec3 {prec.x, prec.y, prec.x};
|
||||
glm::vec3 prec3 {precision.x, precision.y, precision.x};
|
||||
|
||||
const glm::ivec3 base = pos / (glm::ivec3(16) / glm::ivec3(prec3));
|
||||
const glm::vec3 factor = glm::floor(glm::mod(glm::vec3(pos), (glm::vec3(16.f) / prec3))) / 16.f * prec3;
|
||||
if (localPos.x == 16) localPos.x = 15;
|
||||
if (localPos.y == 16) localPos.y = 15;
|
||||
if (localPos.z == 16) localPos.z = 15;
|
||||
glm::ivec3 base = localPos / (glm::ivec3(16) / glm::ivec3(prec3));
|
||||
|
||||
const glm::vec3 factor = glm::floor(glm::mod(glm::vec3(localPos), (glm::vec3(16.f) / prec3))) / 16.f * prec3;
|
||||
|
||||
const auto& x0y0 = data[base.x][base.y];
|
||||
const auto& x1y0 = data[base.x + 1][base.y];
|
||||
|
||||
//No Vertical Interpolation
|
||||
if (prec.y <= 1)
|
||||
return Interp::bilerp(x0y0[base.z], x1y0[base.z], x0y0[base.z + 1], x1y0[base.z + 1], factor.x, factor.z);
|
||||
if (precision.y <= 1) return Interp::bilerp(x0y0[base.z], x1y0[base.z], x0y0[base.z + 1], x1y0[base.z + 1], factor.x, factor.z);
|
||||
|
||||
const auto& x0y1 = data[base.x][base.y + 1];
|
||||
const auto& x1y1 = data[base.x + 1][base.y + 1];
|
||||
|
||||
return Interp::trilerp(x0y0[base.z], x1y0[base.z], x0y0[base.z + 1], x1y0[base.z + 1],
|
||||
x0y1[base.z], x1y1[base.z], x0y1[base.z + 1], x1y1[base.z + 1], factor.x, factor.z, factor.y);
|
||||
return Interp::trilerp(
|
||||
x0y0[base.z], x1y0[base.z], x0y0[base.z + 1], x1y0[base.z + 1],
|
||||
x0y1[base.z], x1y1[base.z], x0y1[base.z + 1], x1y1[base.z + 1], factor.x, factor.z, factor.y);
|
||||
}
|
||||
|
||||
void NoiseSample::reserveSpace() {
|
||||
data.reserve(prec.x + 1);
|
||||
for (unsigned int i = 0; i <= prec.x; i++) {
|
||||
void NoiseSample::set(glm::ivec3 localPos, float value) {
|
||||
data[localPos.x][localPos.y][localPos.z] = value;
|
||||
}
|
||||
|
||||
void NoiseSample::reserve() {
|
||||
data.reserve(precision.x + 1);
|
||||
for (unsigned int i = 0; i <= precision.x; i++) {
|
||||
std::vector<std::vector<float>> subdata;
|
||||
subdata.reserve(prec.y + 1);
|
||||
for (int j = 0; j <= prec.y; j++)
|
||||
subdata.emplace_back(prec.x + 1);
|
||||
subdata.reserve(precision.y + 1);
|
||||
for (int j = 0; j <= precision.y; j++)
|
||||
subdata.emplace_back(precision.x + 1);
|
||||
data.push_back(subdata);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,20 +9,24 @@
|
|||
#include <noise/noise.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/common.hpp>
|
||||
#include <functional>
|
||||
#include "../../util/Interp.h"
|
||||
|
||||
class NoiseSample {
|
||||
public:
|
||||
typedef std::function<float(glm::ivec3 pos)> fill_function;
|
||||
|
||||
NoiseSample() = default;
|
||||
explicit NoiseSample(glm::ivec2 precision);
|
||||
NoiseSample(noise::module::Module& module, glm::vec3 pos, glm::ivec2 precision, bool flat = false);
|
||||
|
||||
void set(glm::ivec3 pos, float value);
|
||||
float get(const glm::ivec3& pos);
|
||||
void fill(const fill_function& fun, float precision);
|
||||
void fill(const fill_function& fun, glm::ivec2 precision);
|
||||
|
||||
float get(glm::ivec3 localPos);
|
||||
void set(glm::ivec3 localPos, float value);
|
||||
private:
|
||||
void reserveSpace();
|
||||
void reserve();
|
||||
|
||||
glm::ivec2 prec {};
|
||||
std::vector<std::vector<std::vector<float>>> data {};
|
||||
glm::ivec2 precision {};
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
ServerBiomeAtlas::ServerBiomeAtlas() {
|
||||
//Invalid Biome
|
||||
BiomeDef* invalid = new BiomeDef("invalid", INVALID, -1, -1, -1, 0, 0, 0, {}, {});
|
||||
BiomeDef* invalid = new BiomeDef("invalid", INVALID, -1, -1, -1, 0, 0, 0, {}, {}, {});
|
||||
registerBiome(invalid);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,11 @@ MeshGenStream::MeshGenStream(ClientGame &defs, LocalDimension &dimension) :
|
|||
offsetTurbulence.SetFrequency(4.0);
|
||||
offsetTurbulence.SetPower(0.125);
|
||||
|
||||
noiseSampler = { NoiseSample {}, NoiseSample {}, NoiseSample {} };
|
||||
//8 is just a random value to offset results
|
||||
noiseSampler = {
|
||||
NoiseSample {offsetTurbulence, {0, 0, 8}, {16, 16}},
|
||||
NoiseSample {offsetTurbulence, {0, 8, 0}, {16, 16}},
|
||||
NoiseSample {offsetTurbulence, {8, 0, 0}, {16, 16}}
|
||||
};
|
||||
noiseSampler[0].fill([&](glm::ivec3 pos) -> float { return offsetTurbulence.GetValue(pos.x + 8, pos.y, pos.z); }, {16, 16});
|
||||
noiseSampler[1].fill([&](glm::ivec3 pos) -> float { return offsetTurbulence.GetValue(pos.x, pos.y + 8, pos.z); }, {16, 16});
|
||||
noiseSampler[2].fill([&](glm::ivec3 pos) -> float { return offsetTurbulence.GetValue(pos.x, pos.y, pos.z + 8); }, {16, 16});
|
||||
|
||||
threads.reserve(THREADS);
|
||||
for (int i = 0; i < THREADS; i++) {
|
||||
|
|
|
@ -282,9 +282,23 @@ namespace RegisterBiomes {
|
|||
auto biomeTint = biomeTable.get < sol::optional < std::string >> ("biome_tint");
|
||||
if (!biomeTint) throw identifier + "biome definitions require a biome_tint";
|
||||
|
||||
// Parse Noise params
|
||||
std::vector<noise::module::Module*> modules;
|
||||
parseNoise(modules, biomeTable.get<sol::table>("noise"));
|
||||
// Get noise parameters
|
||||
auto noiseList = biomeTable.get<sol::optional<sol::table>>("noise");
|
||||
std::vector<noise::module::Module*> volumeModules, heightmapModules;
|
||||
|
||||
if (noiseList) {
|
||||
if (noiseList->get<sol::optional<sol::table>>("heightmap"))
|
||||
parseNoise(heightmapModules, noiseList->get<sol::table>("heightmap"));
|
||||
else heightmapModules.push_back(new noise::module::Const);
|
||||
|
||||
if (noiseList->get<sol::optional<sol::table>>("volume"))
|
||||
parseNoise(volumeModules, noiseList->get<sol::table>("volume"));
|
||||
else volumeModules.push_back(new noise::module::Const);
|
||||
}
|
||||
else {
|
||||
volumeModules.push_back(new noise::module::Const);
|
||||
heightmapModules.push_back(new noise::module::Const);
|
||||
}
|
||||
|
||||
// Create biome definition
|
||||
BiomeDef* biomeDef = new BiomeDef(
|
||||
|
@ -293,7 +307,8 @@ namespace RegisterBiomes {
|
|||
defs.blockFromStr(*bTop).index,
|
||||
defs.blockFromStr(*bSoil).index,
|
||||
defs.blockFromStr(*bRock).index,
|
||||
modules,
|
||||
heightmapModules,
|
||||
volumeModules,
|
||||
glm::vec3(Util::hexToColorVec((*biomeTint)))
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
local formspec = zepha.create_menu(function()
|
||||
return Gui.Body {
|
||||
background = "#0003",
|
||||
|
||||
callbacks = {
|
||||
primary = zepha.player:close_menu
|
||||
},
|
||||
|
||||
Gui.Rect {
|
||||
key = "inventory",
|
||||
position = { pc(50), pc(50) },
|
||||
position_anchor = { pc(50), pc(55) },
|
||||
size = { 218, 160 },
|
||||
|
||||
Gui.Rect {
|
||||
key = "inventory_background",
|
||||
|
||||
position = { 0, 45 },
|
||||
size = { 218, 100 },
|
||||
padding = { 20, 10, 8, 10 },
|
||||
background = "zeus:inventory:inventory",
|
||||
|
||||
Gui.InventoryList {
|
||||
position = { 1, 1 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "main",
|
||||
}
|
||||
},
|
||||
Gui.Rect {
|
||||
key = "crafting_background",
|
||||
|
||||
position = { 0, -5 },
|
||||
size = { 218, 72 },
|
||||
padding = { 20, 10, 8, 10 },
|
||||
background = "zeus:inventory:crafting",
|
||||
|
||||
Gui.InventoryList {
|
||||
position = { 111, 1 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "craft",
|
||||
},
|
||||
Gui.InventoryList {
|
||||
position = { 163, 10 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "craft_result",
|
||||
},
|
||||
Gui.Rect {
|
||||
key = "player_clamp",
|
||||
|
||||
position = { 41, -8 },
|
||||
size = { 32, 52 },
|
||||
overflow = "hidden",
|
||||
|
||||
Gui.Model {
|
||||
position = { 15, 52 },
|
||||
scale = { 86, 86 },
|
||||
|
||||
type = "model",
|
||||
source = "zeus:default:player",
|
||||
texture = "zeus:default:player",
|
||||
anim_range = { 0, 300 }
|
||||
}
|
||||
}
|
||||
},
|
||||
Gui.Rect {
|
||||
position = { 2, 160 },
|
||||
size = { 214, 67 },
|
||||
background = "zeus:inventory:inventory_wheel",
|
||||
|
||||
children = {
|
||||
Gui.InventoryList {
|
||||
position = { 9, 1 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "hot_wheel_1",
|
||||
},
|
||||
Gui.InventoryList {
|
||||
position = { 117, 1 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "hot_wheel_2",
|
||||
},
|
||||
Gui.InventoryList {
|
||||
position = { 125, 25 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "hot_wheel_3",
|
||||
},
|
||||
Gui.InventoryList {
|
||||
position = { 117, 50 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "hot_wheel_4",
|
||||
},
|
||||
Gui.InventoryList {
|
||||
position = { 9, 50 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "hot_wheel_5",
|
||||
},
|
||||
Gui.InventoryList {
|
||||
position = { 1, 25 },
|
||||
slot_spacing = { 2, 2 },
|
||||
source = "current_player",
|
||||
list = "hot_wheel_6",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end)
|
||||
|
||||
-- Register the inventory menu and keybind
|
||||
zepha.register_keybind("zeus:inventory:open_inventory", {
|
||||
description = "Open Inventory",
|
||||
default = zepha.keys.e,
|
||||
on_press = function()
|
||||
if (zepha.player.menu_state == "") then
|
||||
zepha.player:open_menu(formspec)
|
||||
else
|
||||
zepha.player:close_menu()
|
||||
end
|
||||
}
|
||||
})
|
|
@ -1,31 +1,30 @@
|
|||
local noise = {
|
||||
module = "add",
|
||||
sources = {
|
||||
{
|
||||
volume = {
|
||||
module = "add",
|
||||
sources = {{
|
||||
module = "add",
|
||||
sources = {
|
||||
{ ## Voronoi
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "voronoi",
|
||||
frequency = 0.2,
|
||||
displacement = 5
|
||||
},
|
||||
scale = 8,
|
||||
bias = -32
|
||||
sources = {{
|
||||
## Voronoi
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "voronoi",
|
||||
frequency = 0.2,
|
||||
displacement = 5
|
||||
},
|
||||
{ ## Features
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.6,
|
||||
octaves = 3,
|
||||
},
|
||||
scale = 3
|
||||
}
|
||||
}
|
||||
},
|
||||
{ ## Variation
|
||||
scale = 8,
|
||||
bias = -32
|
||||
}, {
|
||||
## Features
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
frequency = 0.6,
|
||||
octaves = 3,
|
||||
},
|
||||
scale = 3
|
||||
}}
|
||||
}, {
|
||||
## Variation
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
|
@ -33,7 +32,7 @@ local noise = {
|
|||
octaves = 6
|
||||
},
|
||||
scale = 15
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
local noise = {
|
||||
module = "add",
|
||||
sources = {
|
||||
{ ## Elevation
|
||||
heightmap = {
|
||||
module = "add",
|
||||
sources = {{
|
||||
## Elevation
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
|
@ -10,8 +11,8 @@ local noise = {
|
|||
},
|
||||
scale = 250,
|
||||
bias = -32
|
||||
},
|
||||
{ ## Features
|
||||
}, {
|
||||
## Features
|
||||
module = "scale_bias",
|
||||
source = {
|
||||
module = "perlin",
|
||||
|
@ -20,7 +21,7 @@ local noise = {
|
|||
},
|
||||
scale = 6,
|
||||
bias = 6
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue