1
0
Fork 0

Basic earth like generator

This commit is contained in:
May B. 2020-08-29 16:35:08 +02:00
parent 5ac3a0037a
commit 4066bf90b9
57 changed files with 315 additions and 97 deletions

View File

@ -18,10 +18,10 @@ in VertexData
{
vec3 Position_modelspace;
#ifdef GEOMETRY
flat uint Materials[3];
vec3 MaterialRatio;
flat uint Textures[3];
vec3 TextureRatio;
#else
flat uint Material;
flat uint Texture;
#endif
vec3 FaceNormal_modelspace;
#ifdef PBR
@ -41,24 +41,24 @@ vec3 expand(vec3 v) {
vec4 getTexture(sampler2DArray sample, vec2 UV) {
#ifdef GEOMETRY
#ifdef BLEND
vec4 colx = texture(sample, vec3(UV, vs.Materials[0]));
if(vs.Materials[1] == vs.Materials[0]) {
return vs.Materials[2] == vs.Materials[0] ? colx :
mix(colx, texture(sample, vec3(UV, vs.Materials[2])), vs.MaterialRatio.z);
vec4 colx = texture(sample, vec3(UV, vs.Textures[0]));
if(vs.Textures[1] == vs.Textures[0]) {
return vs.Textures[2] == vs.Textures[0] ? colx :
mix(colx, texture(sample, vec3(UV, vs.Textures[2])), vs.TextureRatio.z);
} else {
vec4 coly = texture(sample, vec3(UV, vs.Materials[1]));
return vs.Materials[2] == vs.Materials[0] ? mix(colx, coly, vs.MaterialRatio.y) : (
vs.Materials[2] == vs.Materials[1] ? mix(coly, colx, vs.MaterialRatio.x) :
colx * vs.MaterialRatio.x + coly * vs.MaterialRatio.y + texture(sample, vec3(UV, vs.Materials[2])) * vs.MaterialRatio.z);
vec4 coly = texture(sample, vec3(UV, vs.Textures[1]));
return vs.Textures[2] == vs.Textures[0] ? mix(colx, coly, vs.TextureRatio.y) : (
vs.Textures[2] == vs.Textures[1] ? mix(coly, colx, vs.TextureRatio.x) :
colx * vs.TextureRatio.x + coly * vs.TextureRatio.y + texture(sample, vec3(UV, vs.Textures[2])) * vs.TextureRatio.z);
}
#else
int mainMaterial = vs.MaterialRatio.x >= vs.MaterialRatio.y ?
(vs.MaterialRatio.x >= vs.MaterialRatio.z ? 0 : 2) :
(vs.MaterialRatio.y >= vs.MaterialRatio.z ? 1 : 2);
return texture(sample, vec3(UV, vs.Materials[mainMaterial]));
int mainTexture = vs.TextureRatio.x >= vs.TextureRatio.y ?
(vs.TextureRatio.x >= vs.TextureRatio.z ? 0 : 2) :
(vs.TextureRatio.y >= vs.TextureRatio.z ? 1 : 2);
return texture(sample, vec3(UV, vs.Textures[mainTexture]));
#endif
#else
return texture(sample, vec3(UV, vs.Material));
return texture(sample, vec3(UV, vs.Texture));
#endif
}
@ -119,10 +119,10 @@ void main() {
// Colors
#ifdef PBR
// Material properties
vec3 MaterialDiffuseColor = tex;
vec3 MaterialAmbientColor = vec3(.1) * MaterialDiffuseColor * texHOS.y;
vec3 MaterialSpecularColor = vec3(.8) * texHOS.z;
// Texture properties
vec3 TextureDiffuseColor = tex;
vec3 TextureAmbientColor = vec3(.1) * TextureDiffuseColor * texHOS.y;
vec3 TextureSpecularColor = vec3(.8) * texHOS.z;
vec3 Normal_cameraspace = normalize((View * vec4(worldNormal,0)).xyz);
@ -159,11 +159,11 @@ void main() {
color =
// Ambient : simulates indirect lighting
MaterialAmbientColor +
TextureAmbientColor +
// Diffuse : "color" of the object
visibility * MaterialDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) +
visibility * TextureDiffuseColor * LightColor * LightPower * cosTheta / (distance * distance) +
// Specular : reflective highlight, like a mirror
visibility * MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance * distance);
visibility * TextureSpecularColor * LightColor * LightPower * pow(cosAlpha,5) / (distance * distance);
#else
color = tex;
#endif

View File

@ -6,7 +6,7 @@ layout (triangle_strip, max_vertices = 3) out;
in VertexData {
vec3 Position_modelspace;
flat uint Material;
flat uint Texture;
vec3 FaceNormal_modelspace;
#ifdef PBR
vec3 FaceNormal_worldspace;
@ -20,8 +20,8 @@ in VertexData {
out GeometryData {
vec3 Position_modelspace;
flat uint Materials[3];
vec3 MaterialRatio;
flat uint Textures[3];
vec3 TextureRatio;
vec3 FaceNormal_modelspace;
#ifdef PBR
vec3 FaceNormal_worldspace;
@ -41,19 +41,19 @@ void main() {
gs.FaceNormal_modelspace = vs_in[i].FaceNormal_modelspace;
gs.FaceNormal_worldspace = vs_in[i].FaceNormal_worldspace;
gs.Materials[i] = vs_in[i].Material;
gs.Textures[i] = vs_in[i].Texture;
switch(int(mod(i,3))) {
case 0:
gs.MaterialRatio = vec3(1,0,0);
gs.TextureRatio = vec3(1,0,0);
break;
case 1:
gs.MaterialRatio = vec3(0,1,0);
gs.TextureRatio = vec3(0,1,0);
break;
case 2:
gs.MaterialRatio = vec3(0,0,1);
gs.TextureRatio = vec3(0,0,1);
break;
default:
gs.MaterialRatio = vec3(0);
gs.TextureRatio = vec3(0);
break;
};

View File

@ -1,12 +1,12 @@
#version 330 core
layout(location = 0) in vec3 Position_modelspace;
layout(location = 1) in uint Material_model;
layout(location = 1) in uint Texture_model;
layout(location = 2) in vec3 Normal_modelspace;
out VertexData {
vec3 Position_modelspace;
flat uint Material;
flat uint Texture;
vec3 FaceNormal_modelspace;
#ifdef PBR
vec3 FaceNormal_worldspace;
@ -51,7 +51,7 @@ void main(){
vs.Depth = length(Position_cameraspace.xyz) / FogDepth;
#endif
vs.Material = Material_model;
vs.Texture = Texture_model;
vs.FaceNormal_modelspace = normalize(Normal_modelspace);
#ifdef PBR

BIN
content/textures-src/1024-realistic/Grass_001_COLOR.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Grass_001_DISP.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Grass_001_HOS.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Grass_001_NORM.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Grass_001_OCC.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Grass_001_ROUGH.jpg (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
content/textures-src/1024-realistic/Stone_Path_004_HOS.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Water_002_COLOR.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Water_002_DISP.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Water_002_HOS.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Water_002_NORM.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Water_002_OCC.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures-src/1024-realistic/Water_002_ROUGH.jpg (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Forest_grass.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Forest_grass.hos.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Forest_grass.nrm.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Grass.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Grass.hos.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Grass.nrm.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Plain_grass.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Plain_grass.hos.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Plain_grass.nrm.dds (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Water.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Water.hos.dds (Stored with Git LFS) Normal file

Binary file not shown.

BIN
content/textures/1024-realistic/terrain/Water.nrm.dds (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -15,6 +15,7 @@ namespace contouring {
FlatDualMC::FlatDualMC(const std::string &str) : AbstractFlat(str) {
auto opt = toml::parse(str);
transparency = opt["transparency"].value_or(transparency);
iso = opt["iso"].value_or(iso);
manifold = opt["manifold"].value_or(manifold);
reordering = opt["reordering"].value_or(reordering);
@ -67,6 +68,7 @@ namespace contouring {
toml::table tb({
{"load_distance", loadDistance},
{"keep_distance", keepDistance},
{"transparency", transparency},
{"iso", iso},
{"manifold", manifold},
{"reordering", reordering},
@ -177,6 +179,7 @@ namespace contouring {
void FlatDualMC::onGui() {
AbstractFlat::onGui();
ImGui::Separator();
ImGui::Checkbox("Transparency", &transparency);
ImGui::SliderFloat("Iso", &iso, 0, 1);
ImGui::Checkbox("Manifold", &manifold);
ImGui::Checkbox("Reordering", &reordering);
@ -206,8 +209,8 @@ namespace contouring {
auto &cell = grid[((z * SIZE) + y) * SIZE + x];
const auto &chunk = surrounding[(z >= CHUNK_LENGTH) + (y >= CHUNK_LENGTH)*2 + (x >= CHUNK_LENGTH)*4];
const auto &voxel = chunk->get(glm::toIdx(x % CHUNK_LENGTH, y % CHUNK_LENGTH, z % CHUNK_LENGTH));
cell.x = voxel.density_ratio();
cell.w = voxel.material();
cell.x = voxel.density_ratio() * (!world::materials::invisibility[cell.w] && (transparency || !world::materials::transparency[cell.w]));
}}}
}
{
@ -215,7 +218,8 @@ namespace contouring {
std::vector<dualmc::Tri> dmc_tris;
dualmc::DualMC<float> builder;
builder.buildTris(&grid.front(), SIZE, SIZE, SIZE, iso, world::materials::roughness.cbegin(), manifold, dmc_vertices, dmc_tris);
builder.buildTris(&grid.front(), SIZE, SIZE, SIZE, iso, world::materials::textures_map.cbegin(), world::materials::roughness.cbegin(),
manifold, dmc_vertices, dmc_tris);
auto &data = out.first;
tmp.clear();

View File

@ -38,6 +38,7 @@ namespace contouring {
void enqueue(const area_<chunk_pos> &, const chunk_pos &offset, const world::ChunkContainer &);
bool transparency = false;
float iso = .1f;
bool manifold = true;
bool reordering = true;

View File

@ -90,7 +90,7 @@ namespace contouring {
}
bool FlatSurroundingBox::isTransparent(const surrounding::faces &surrounding, const std::pair<ushort, ushort> &idx) {
return !surrounding[idx.first]->get(idx.second).is_full(); // MAYBE: materials::transparent
return !surrounding[idx.first]->get(idx.second).is_full();
}
void FlatSurroundingBox::render(const surrounding::faces &surrounding, std::vector<buffer::PackedVertexData> &vertices) {
@ -105,7 +105,7 @@ namespace contouring {
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Down)) & Faces::Down) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Forward)) & Faces::Forward) |
(isTransparent(surrounding, surrounding::getNeighborIdx(i, Face::Backward)) & Faces::Backward);
box::addCube(vertices, glm::fromIdx(i), center->get(i).material(), faces, glm::vec3(center->get(i).density_ratio()));
box::addCube(vertices, glm::fromIdx(i), center->get(i).texture(), faces, glm::vec3(center->get(i).density_ratio()));
}
}
}

View File

@ -26,33 +26,33 @@ namespace contouring::box {
glm::rotate<float>(glm::mat4(1), glm::half_pi<float>(), glm::vec3(0, 1, 0)),
};
static void addQuad(std::vector<buffer::PackedVertexData> & out, glm::vec3 position, ushort material, Face face, glm::vec3 size) {
static void addQuad(std::vector<buffer::PackedVertexData> & out, glm::vec3 position, ushort texture, Face face, glm::vec3 size) {
for (auto vertex : g_quad_vertices) {
const auto p = glm::vec3(g_cube_rotate[static_cast<int>(face)] * glm::vec4(vertex, 1)) * size + position;
out.emplace_back(meshopt_quantizeHalf(p.x), meshopt_quantizeHalf(p.y),
meshopt_quantizeHalf(p.z), material,
meshopt_quantizeHalf(p.z), texture,
meshopt_quantizeHalf(g_cube_normals[static_cast<int>(face)].x), meshopt_quantizeHalf(g_cube_normals[static_cast<int>(face)].y),
meshopt_quantizeHalf(g_cube_normals[static_cast<int>(face)].z));
}
}
static void addCube(std::vector<buffer::PackedVertexData>& out, glm::vec3 position, uint material, Faces faces = Faces::All, glm::vec3 size = glm::vec3(1)) {
static void addCube(std::vector<buffer::PackedVertexData>& out, glm::vec3 position, uint texture, Faces faces = Faces::All, glm::vec3 size = glm::vec3(1)) {
if (faces && Faces::Right)
addQuad(out, position, material, Face::Right, size);
addQuad(out, position, texture, Face::Right, size);
if(faces && Faces::Left)
addQuad(out, position, material, Face::Left, size);
addQuad(out, position, texture, Face::Left, size);
if (faces && Faces::Up)
addQuad(out, position, material, Face::Up, size);
addQuad(out, position, texture, Face::Up, size);
if (faces && Faces::Down)
addQuad(out, position, material, Face::Down, size);
addQuad(out, position, texture, Face::Down, size);
if (faces && Faces::Forward)
addQuad(out, position, material, Face::Forward, size);
addQuad(out, position, texture, Face::Forward, size);
if (faces && Faces::Backward)
addQuad(out, position, material, Face::Backward, size);
addQuad(out, position, texture, Face::Backward, size);
}
}

View File

@ -38,7 +38,7 @@ struct Vertex {
// components
VertexComponentsType x,y,z;
// material
// texture
PropertyType w;
};
@ -101,6 +101,7 @@ public:
Point const *data,
int32_t const dimX, int32_t const dimY, int32_t const dimZ,
VolumeDataType const iso,
ushort const *textures_map,
float const *roughness,
bool const generateManifold,
std::vector<Vertex> &vertices,
@ -161,7 +162,7 @@ protected:
/// Compute a linearized cell cube index.
int32_t gA(int32_t const x, int32_t const y, int32_t const z) const;
/// Update material if max.
/// Update texture if max.
void maxProp(int32_t const x, int32_t const y, int32_t const z, Vertex &vertex, VolumeDataType& max) const;
protected:
@ -186,6 +187,9 @@ protected:
/// convenience volume data point
Point const *data;
/// point to vertex property table
ushort const *textures_map;
/// property roughness table
float const *roughness;
@ -278,7 +282,7 @@ template<class T> inline
void DualMC<T>::maxProp(int32_t const x, int32_t const y, int32_t const z, Vertex &vertex, VolumeDataType &max) const {
if(data[gA(x, y, z)].x > max) {
max = data[gA(x, y, z)].x;
vertex.w = data[gA(x, y, z)].w;
vertex.w = textures_map[data[gA(x, y, z)].w];
}
}
@ -539,6 +543,7 @@ void DualMC<T>::buildTris(
Point const * data,
int32_t const dimX, int32_t const dimY, int32_t const dimZ,
VolumeDataType const iso,
ushort const * textures_map,
float const * roughness,
bool const generateManifold,
std::vector<Vertex> & vertices,
@ -550,6 +555,7 @@ void DualMC<T>::buildTris(
this->dims[1] = dimY;
this->dims[2] = dimZ;
this->data = data;
this->textures_map = textures_map;
this->roughness = roughness;
this->generateManifold = generateManifold;

View File

@ -131,7 +131,7 @@ int main(int /*unused*/, char */*unused*/[]){
if (state.capture_mouse) {
if (state.look_at.has_value()) {
if (inputs.isPressing(Mouse::Left))
world.setCube(state.look_at.value().pos, world::Voxel(0), options.tool.radius);
world.setCube(state.look_at.value().pos, world::Voxel(world::materials::AIR, options.tool.empty_air * world::Voxel::DENSITY_MAX), options.tool.radius);
else if (inputs.isPressing(Mouse::Right))
world.setCube(state.look_at.value().pos, world::Voxel(options.tool.material, world::Voxel::DENSITY_MAX), options.tool.radius);
}
@ -228,10 +228,36 @@ int main(int /*unused*/, char */*unused*/[]){
lookProgram->useIt();
lookProgram->start(renderer);
const auto draw = [&](const std::vector<glm::mat4>& models, buffer::Abstract *const) {
for(const auto& model: models) { //TODO: batch
reports.models_count++;
reports.tris_count += lookBuffer.draw(lookProgram->setup(renderer, model));
}
reports.models_count += models.size();
reports.tris_count += models.size() * 24; // FIXME: get from buffer
//instancedProgram->setMatrices(&models[batch * BATCH_SIZE]);
/*
unsigned int instanceVBO;
glGenBuffers(1, &instanceVBO);
glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * BATCH_SIZE, &translations[0], GL_STATIC_DRAW); //MAYBE: only rewrite only count
glBindBuffer(GL_ARRAY_BUFFER, 0);
*/
/*
constexpr std::size_t vec4Size = sizeof(glm::vec4);
constexpr auto location = 6;
glEnableVertexAttribArray(location+0);
glVertexAttribPointer(location+0, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)0);
glEnableVertexAttribArray(location+1);
glVertexAttribPointer(location+1, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(1 * vec4Size));
glEnableVertexAttribArray(location+2);
glVertexAttribPointer(location+2, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(2 * vec4Size));
glEnableVertexAttribArray(location+3);
glVertexAttribPointer(location+3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (void*)(3 * vec4Size));
glVertexAttribDivisor(location+0, 1);
glVertexAttribDivisor(location+1, 1);
glVertexAttribDivisor(location+2, 1);
glVertexAttribDivisor(location+3, 1);
*/
//glDrawArraysInstanced(GL_TRIANGLES, 0, 6, count);
for (size_t offset = 0; offset < models.size(); offset++) //TODO: instansiate
lookBuffer.draw(lookProgram->setup(renderer, models[offset]));
};
world.getEntitiesModels(draw, frustum, offset, options.voxel_density);
}

View File

@ -187,24 +187,29 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
if (state.look_at.has_value()) {
const auto &look = state.look_at.value();
ImGui::Text("Look at: (%ld: %lld, %lld, %lld) (%s, %.1f)", look.pos.first.index, look.pos.second.x, look.pos.second.y, look.pos.second.z,
world::materials::textures[look.value.material()].c_str(), look.value.density_ratio());
world::materials::names[look.value.material()].c_str(), look.value.density_ratio());
const auto w_pos = look.pos.second + look.offset;
ImGui::Text("(%.3f, %.3f, %.3f)", w_pos.x * 1. / options.voxel_density, w_pos.y * 1. / options.voxel_density, w_pos.z * 1. / options.voxel_density);
} else {
ImGui::Text("Look at: none");
}
ImGui::Separator();
if (ImGui::BeginCombo("Material", world::materials::textures[options.tool.material].c_str())) {
for (size_t i = 0; i < world::materials::textures.size(); i++) {
const bool is_selected = (options.tool.material == i);
if (ImGui::Selectable(world::materials::textures[i].c_str(), is_selected))
options.tool.material = i;
if (is_selected)
ImGui::SetItemDefaultFocus();
if (ImGui::BeginCombo("Material", world::materials::names[options.tool.material].c_str())) {
for (size_t i = 0; i < world::materials::names.size(); i++) {
if (!world::materials::invisibility[i]) {
const bool is_selected = (options.tool.material == i);
if (ImGui::Selectable(world::materials::names[i].c_str(), is_selected))
options.tool.material = i;
if (is_selected)
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
ImGui::SliderInt("Radius", &options.tool.radius, 0, 10);
ImGui::Checkbox("Empty air", &options.tool.empty_air);
if (ImGui::IsItemHovered())
ImGui::SetTooltip("Is cleaned area breathable");
ImGui::End();
}

View File

@ -174,7 +174,8 @@ struct options {
bool editor_show;
struct tool {
int radius = 2;
unsigned short material = 2;
unsigned short material = 5;
bool empty_air = true;
} tool;
bool overlay_show;

View File

@ -50,13 +50,13 @@ Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"
//TODO: generate universe
const auto radius = 1 << 4;
far_areas.emplace(Area::params{glm::multiply(voxel_pos(radius, 0, 0)), radius,
generator::params(std::in_place_type<generator::CubicPlanet::Params>, radius * CHUNK_LENGTH * 3 / 4, 42)});
generator::params(std::in_place_type<generator::RoundPlanet::Params>, radius * CHUNK_LENGTH * 3 / 4, 42)});
//far_areas.emplace(Area::params{voxel_pos(0), 1 << 20, generator::params(std::in_place_type<generator::Cave::Params>, 42)});
}
index.close();
}
entities.emplace(nullptr, glm::vec3(1), glm::vec3(2));
entities.emplace(nullptr, glm::vec3(1), glm::vec3(2)); //TODO: use contouring to load models
// Workers
for (size_t i = 0; i < std::thread::hardware_concurrency() / 2 - 1; i++) {
@ -450,7 +450,7 @@ void Universe::getEntitiesModels(const std::function<void(const std::vector<glm:
mats.emplace_back(glm::scale(glm::translate(glm::mat4(1), fPos * (float)density), entity.scale));
});
if(!mats.empty()) {
draw(mats, entity.buffer);
draw(mats, entity.buffer.get());
mats.resize(0);
}
});

View File

@ -82,7 +82,7 @@ namespace world {
struct Entity {
Entity(buffer::Abstract* buffer, const glm::vec3& size = glm::vec3(1), const glm::vec3& scale = glm::vec3(1)):
buffer(buffer), size(size), scale(scale) { };
buffer::Abstract* buffer;
std::unique_ptr<buffer::Abstract> buffer;
glm::vec3 size;
glm::vec3 scale;
struct Instance {

View File

@ -1,6 +1,7 @@
#pragma once
#include <robin_hood.h>
#include "materials.hpp"
namespace world {
/// Universe unit
@ -21,30 +22,45 @@ namespace world {
(density & DENSITY_MAX);
}
/// Quantity of material
constexpr inline density_t density() const {
return value & DENSITY_MAX;
}
/// Quantity of material on [0, 1]
constexpr inline float density_ratio() const {
return density() * 1.f / world::Voxel::DENSITY_MAX;
}
/// Material type
constexpr inline material_t material() const {
return (value & 0b0111'1111'1111'1000) >> 3;
}
/// Texture idx
constexpr inline ushort texture() const {
return materials::textures_map[material()];
}
/// Quantity of element
constexpr inline density_t density() const {
return value & DENSITY_MAX;
}
/// Quantity of element on [0, 1]
constexpr inline float density_ratio() const {
return density() * 1.f / world::Voxel::DENSITY_MAX;
}
/// Swap value
/// Use external metadata table
constexpr inline bool swap() const {
return value & 0b1000'0000'0000'0000;
}
/// Is solid
constexpr inline bool is_solid() const {
return density() > 0; //MAYBE: && materials::solid[material()]
return density() > 0 && materials::solidity[material()];
}
/// Is visible matter
constexpr inline bool is_visible() const {
return !materials::invisibility[material()];
}
/// Contains matter
constexpr inline bool is_material() const {
return density() > 0 && is_visible();
}
/// Is full
constexpr inline bool is_full() const {
return density() == DENSITY_MAX;
return density() == DENSITY_MAX && !materials::transparency[material()];
}
};
/// Stock of material

View File

@ -47,8 +47,8 @@ namespace world::generator {
auto materialSet = material.Get(pos, CHUNK_LENGTH);
for (size_t i = 0; i < CHUNK_SIZE; i++) {
const auto density = std::clamp((densitySet.get()[i] + params.density) * params.granularity, 0.f, 1.f) * Voxel::DENSITY_MAX;
const auto material = density > 0 ? 1 + std::clamp(static_cast<int>(std::lrint((materialSet.get()[i] + 1) / 2 * (materials::count - 2))),
0, materials::count - 2) : 0; //NOTE: map (approx -1, 1) to (1, mat_max)
const auto material = density > 0 ? 2 + std::clamp(static_cast<int>(std::lrint((materialSet.get()[i] + 1) / 2 * (materials::count - 3))),
0, materials::count - 3) : 1; //NOTE: map (approx -1, 1) to (1, mat_max)
out[i] = Voxel(material, density);
}
}
@ -65,30 +65,50 @@ namespace world::generator {
class Planet: public Abstract {
public:
struct Params: Cave::Params {
Params(voxel_pos::value_type height, int seed = 42, float surface_roughness = .1, float cave_depth = .2, float density = 0, float gran = 30):
Cave::Params(seed, density, gran), height(height), surface_roughness(surface_roughness), cave_depth(cave_depth) { }
Params(voxel_pos::value_type height, int seed = 42, float surface_roughness = .1, float depth_roughness = .05, float density = 0, float gran = 30):
Cave::Params(seed, density, gran), height(height), surface_roughness(surface_roughness), depth_roughness(depth_roughness) { }
/// Sea level (minimal density)
voxel_pos::value_type height;
/// Density decrease over height
float surface_roughness;
/// Density decrease under height
float cave_depth;
float depth_roughness;
/// Sea border depth
float beach_depth = .01f;
/// Sea ground displacement
float beach_displacement = .01f;
};
Planet(const Params p) : params(p), density(Noise::SimplexFractal(p.seed)), material(Noise::Cellular(p.seed * 5, .1)) {}
Planet(const Params p) : params(p), density(Noise::SimplexFractal(p.seed)), displacement(Noise::Simplex(p.seed * 5, .01)) {}
void generate(const chunk_pos &pos, std::array<Voxel, CHUNK_SIZE> &out) override {
auto densitySet = density.Get(pos, CHUNK_LENGTH);
auto materialSet = material.Get(pos, CHUNK_LENGTH);
const auto verticalDensity = [this, pos](glm::idx i) {
const auto heightRatio = static_cast<float>(getHeight(glm::multiply(pos) + glm::llvec3(glm::fromIdx(i))) - params.height) / params.height;
return heightRatio / (heightRatio >= 0 ? params.surface_roughness : params.cave_depth);
};
auto displacementSet = displacement.Get(pos, CHUNK_LENGTH);
for (size_t i = 0; i < CHUNK_SIZE; i++) {
const auto density = std::clamp((densitySet.get()[i] + params.density - verticalDensity(i)) * params.granularity, 0.f, 1.f) * Voxel::DENSITY_MAX;
const auto material = density > 0 ? 1 + std::clamp(static_cast<int>(std::lrint((materialSet.get()[i] + 1) / 2 * (materials::count - 2))),
0, materials::count - 2) : 0; //NOTE: map (approx -1, 1) to (1, mat_max)
out[i] = Voxel(material, density);
const auto heightRatio = static_cast<float>(getHeight(glm::multiply(pos) + glm::llvec3(glm::fromIdx(i))) - params.height) / params.height;
const auto verticalDensityOffset = heightRatio / (heightRatio >= 0 ? params.surface_roughness : params.depth_roughness);
const auto density = std::clamp((densitySet.get()[i] + params.density - verticalDensityOffset) * params.granularity, 0.f, 1.f) * Voxel::DENSITY_MAX;
out[i] = [&]() -> Voxel {
if (density > 0) {
const auto material = [&]() -> int {
const auto noisedHeightRatio = heightRatio - displacementSet.get()[i] * params.beach_displacement;
if(noisedHeightRatio >= 0) {
return densitySet.get()[i] + params.density < ((heightRatio + 0.007f) / params.surface_roughness) ? materials::GRASS : materials::DIRT;
} else {
return noisedHeightRatio >= -params.beach_depth ? materials::SAND : materials::ROCK;
}
}();
return Voxel(material, density);
} else {
if (heightRatio >= 0) {
return Voxel(materials::AIR, (heightRatio < params.surface_roughness) * Voxel::DENSITY_MAX);
} else {
return Voxel(materials::WATER, Voxel::DENSITY_MAX);
}
}
}();
}
}
private:
@ -102,7 +122,7 @@ namespace world::generator {
}
Params params;
Noise density;
Noise material;
Noise displacement;
};
using CubicPlanet = Planet<PlanetShape::Cube>;
using RoundPlanet = Planet<PlanetShape::Sphere>;

View File

@ -4,12 +4,40 @@
#include <string>
namespace world::materials {
//TODO: AoS to SoA compile time
struct Material {
std::string name;
std::string texture;
float roughness;
bool solid;
//ushort break_to
};
//MAYBE: index name enum
constexpr auto AIR = 0;
constexpr auto DIRT = 1;
constexpr auto GRASS = 2;
constexpr auto SAND = 3;
constexpr auto ROCK = 4;
constexpr auto WATER = 8;
/// Materials count
static const auto count = 9;
static_assert(count < (USHRT_MAX >> 4)); //NOTE: for byte packing see Voxel
/// Materials names
static const std::array<std::string, count> names = {{"Air", "Dirt", "Grass", "Sand", "Rock", "Wall", "Path", "Alien metal", "Water"}};
/// Materials textures
static const std::array<std::string, count> textures = {{"Air", "Sand", "Dirt", "Stone_path", "Mapl", "Seaside_rock", "Stone_wall", "Rough_rock", "Alien"}};
static const std::array<ushort, count> textures_map = {{0, 2, 9, 1, 7, 6, 3, 8, 12}};
/// Materials roughness.
/// -1: slope, 0: normal, 1: cube
static const std::array<float, count> roughness = {{0, 0, 0, 0, 0, 0, 0, -1, .8}};
static const std::array<float, count> roughness = {{0, 0, 0, 0, 0, 0, -1, .8, 0}};
/// Materials interactive
static const std::array<bool, count> invisibility = {{true, false, false, false, false, false, false, false, false}};
/// Materials see throw
static const std::array<bool, count> transparency = {{true, false, false, false, false, false, false, false, true}};
/// Materials is solid
static const std::array<bool, count> solidity = {{false, true, true, true, true, true, true, true, false}};
/// All textures
static const std::array<std::string, 13> textures = {{"Debug", "Sand", "Dirt", "Stone_path", "Mapl", "Seaside_rock", "Stone_wall", "Rough_rock", "Alien", "Grass", "Plain_grass", "Forest_grass", "Water"}};
}