Basic earth like generator
This commit is contained in:
parent
5ac3a0037a
commit
4066bf90b9
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
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/Ground_Forest_002_ambientOcclusion.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_002_ambientOcclusion.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_002_baseColor.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_002_baseColor.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_002_height.png (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_002_height.png (Stored with Git LFS)
Normal file
Binary file not shown.
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_002_normal.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_002_normal.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_002_roughness.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_002_roughness.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_003_ROUGH.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_003_ROUGH.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_003_ambientOcclusion.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_003_ambientOcclusion.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_003_baseColor.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_003_baseColor.jpg (Stored with Git LFS)
Normal file
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_003_height.png (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_003_height.png (Stored with Git LFS)
Normal file
Binary file not shown.
Binary file not shown.
BIN
content/textures-src/1024-realistic/Ground_Forest_003_normal.jpg (Stored with Git LFS)
Normal file
BIN
content/textures-src/1024-realistic/Ground_Forest_003_normal.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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
content/textures/1024-realistic/terrain/Stone_path.hos.dds (Stored with Git LFS)
BIN
content/textures/1024-realistic/terrain/Stone_path.hos.dds (Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
36
src/main.cpp
36
src/main.cpp
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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"}};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue