Planet sphere
This commit is contained in:
parent
bfba0544d6
commit
b7669df9ed
18
TODO.md
18
TODO.md
|
@ -29,13 +29,19 @@
|
|||
- [x] Offset
|
||||
- [ ] Rotation
|
||||
- [~] Planet
|
||||
- [ ] CubicSphere
|
||||
- [ ] Healpix
|
||||
- Render
|
||||
- [x] CubeSphere
|
||||
- [ ] Area corrected CubeSphere
|
||||
- [ ] Corrected Normals
|
||||
- [ ] Surface curvature
|
||||
- [ ] Curvature avare frustum
|
||||
- [ ] Healpix
|
||||
- [ ] Surface features
|
||||
- [ ] Biomes
|
||||
- https://imgur.com/kM8b5Zq
|
||||
- https://imgur.com/a/bh2iy
|
||||
- https://speciesdevblog.files.wordpress.com/2012/11/biomemap.png
|
||||
- [ ] Galaxy
|
||||
- [ ] Biomes
|
||||
- https://imgur.com/kM8b5Zq
|
||||
- https://imgur.com/a/bh2iy
|
||||
- https://speciesdevblog.files.wordpress.com/2012/11/biomemap.png
|
||||
- [ ] Leak test
|
||||
- Valgrind
|
||||
- Xtree-memory
|
||||
|
|
|
@ -18,31 +18,49 @@ out VertexData {
|
|||
#endif
|
||||
} vs;
|
||||
|
||||
uniform mat4 MVP;
|
||||
uniform mat4 Model;
|
||||
uniform mat4 View;
|
||||
uniform mat4 Proj;
|
||||
|
||||
uniform vec4 SphereProj;
|
||||
uniform float Curvature;
|
||||
|
||||
uniform vec3 LightInvDirection_worldspace;
|
||||
uniform float FogDepth;
|
||||
|
||||
void main(){
|
||||
gl_Position = MVP * vec4(Position_modelspace, 1);
|
||||
vs.Position_modelspace = Position_modelspace;
|
||||
vec3 Position_worldspace = (Model * vec4(Position_modelspace,1)).xyz;
|
||||
|
||||
#ifdef CURVATURE
|
||||
if(Curvature > 0) {
|
||||
vec3 Position_areaspace = Position_modelspace + SphereProj.xyz;
|
||||
vec2 sph = vec2(acos(Position_areaspace.z / length(Position_areaspace.xyz)), atan(Position_areaspace.y, Position_areaspace.x));
|
||||
#ifdef CURV_DEPTH
|
||||
float radius = max(max(abs(Position_areaspace.x), abs(Position_areaspace.y)), abs(Position_areaspace.z));
|
||||
#else
|
||||
float radius = SphereProj.w;
|
||||
#endif
|
||||
vs.Position_modelspace = mix(vs.Position_modelspace, vec3(sin(sph.x)*cos(sph.y), sin(sph.x)*sin(sph.y), cos(sph.x)) * radius - SphereProj.xyz, Curvature);
|
||||
}
|
||||
#endif
|
||||
|
||||
vec4 Position_cameraspace = View * Model * vec4(vs.Position_modelspace, 1);
|
||||
gl_Position = Proj * Position_cameraspace;
|
||||
|
||||
#ifdef FOG
|
||||
vs.Depth = length((View * vec4(Position_worldspace,1)).xyz) / FogDepth;
|
||||
vs.Depth = length(Position_cameraspace.xyz) / FogDepth;
|
||||
#endif
|
||||
|
||||
vs.Material = Material_model;
|
||||
|
||||
vs.FaceNormal_modelspace = normalize(Normal_modelspace);
|
||||
#ifdef PBR
|
||||
// TODO: correct normal
|
||||
vs.FaceNormal_worldspace = normalize((Model * vec4(vs.FaceNormal_modelspace, 0)).xyz);
|
||||
|
||||
// Vector that goes from the vertex to the camera, in camera space.
|
||||
// In camera space, the camera is at the origin (0,0,0).
|
||||
vs.EyeDirection_cameraspace = vec3(0,0,0) - (View * Model * vec4(Position_modelspace,1)).xyz;
|
||||
vs.EyeDirection_cameraspace = vec3(0,0,0) - Position_cameraspace.xyz;
|
||||
|
||||
// Vector that goes from the vertex to the light, in camera space
|
||||
vs.LightDirection_cameraspace = (View * vec4(LightInvDirection_worldspace,0)).xyz;
|
||||
|
|
|
@ -31,11 +31,14 @@ namespace contouring {
|
|||
// Get camera recommended far range
|
||||
virtual std::pair<float, float> getFarRange() const = 0;
|
||||
|
||||
using area_info = std::tuple<area_pos, voxel_pos::value_type, float>;
|
||||
using draw_call = const std::function<void(glm::mat4, buffer::Abstract *const, const area_info&, const voxel_pos&)> &;
|
||||
|
||||
/// Get buffers in frustum with model matrices
|
||||
/// @note buffers invalidated after update
|
||||
virtual void getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &draw, const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density) = 0;
|
||||
virtual void getModels(draw_call draw, const std::optional<geometry::Frustum>& frustum, const glm::llvec3& offset, int density) = 0;
|
||||
/// Get buffers hitting occlusion rays with model matrices
|
||||
/// @note buffers invalidated after update
|
||||
virtual void getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) = 0;
|
||||
virtual void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) = 0;
|
||||
};
|
||||
}
|
|
@ -12,8 +12,16 @@ namespace contouring {
|
|||
while (it_a != buffers.end()) { // Remove out of range buffers
|
||||
if (const auto area = areas.find(it_a->first); area != areas.end()) {
|
||||
//Update
|
||||
it_a->second.first = area->second->getOffset();
|
||||
const auto center = glm::divide(pos - it_a->second.first.as_voxel());
|
||||
std::get<0>(it_a->second.first) = area->second->getOffset();
|
||||
std::get<1>(it_a->second.first) = area->second->getChunks().getRadius() * static_cast<long long>(CHUNK_LENGTH);
|
||||
const auto centerV = pos - std::get<0>(it_a->second.first).as_voxel();
|
||||
if (auto planet = std::get_if<world::Generator::Properties::planet>(
|
||||
&area->second->getGenerator().getProperties().shape)) {
|
||||
const auto dist = glm::max_axis(glm::abs(centerV));
|
||||
const auto surface = planet->height * planet->surface_roughness;
|
||||
std::get<2>(it_a->second.first) = std::clamp((dist - surface) / (std::get<1>(it_a->second.first) - surface), -0.1f, 1.f);
|
||||
}
|
||||
const auto center = glm::divide(centerV);
|
||||
auto &bfs = it_a->second.second;
|
||||
auto it = bfs.begin();
|
||||
while(it != bfs.end()) {
|
||||
|
@ -61,22 +69,23 @@ namespace contouring {
|
|||
ImGui::SliderInt("Keep Distance", &keepDistance, loadDistance+1, 21);
|
||||
}
|
||||
|
||||
void AbstractFlat::getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &out, const std::optional<geometry::Frustum> &frustum, const glm::llvec3& offset, int density) {
|
||||
void AbstractFlat::getModels(draw_call out, const std::optional<geometry::Frustum> &frustum, const glm::llvec3& offset, int density) {
|
||||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
||||
for (const auto [_, area] : buffers) {
|
||||
for (const auto [pos, buffer] : area.second) {
|
||||
const glm::vec3 fPos = (glm::vec3(area.first.raw_as_long() + glm::multiply(pos) - offset * glm::llvec3(density)) + area.first.offset) / glm::vec3(density);
|
||||
const auto vPos = glm::multiply(pos);
|
||||
const glm::vec3 fPos = (glm::vec3(std::get<0>(area.first).raw_as_long() + vPos - offset * glm::llvec3(density)) + std::get<0>(area.first).offset) / glm::vec3(density);
|
||||
if (buffer != NULL && (!frustum.has_value() || frustum.value().contains(geometry::Box::fromMin(fPos, glm::vec3(CHUNK_LENGTH / (float)density)))))
|
||||
out(glm::translate(scaling, fPos * (float)density), buffer);
|
||||
out(glm::translate(scaling, fPos * (float)density), buffer, area.first, vPos);
|
||||
}}
|
||||
}
|
||||
|
||||
void AbstractFlat::getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &out, const glm::ifvec3& from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) {
|
||||
void AbstractFlat::getModels(draw_call out, const glm::ifvec3& from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) {
|
||||
const auto scaling = glm::scale(glm::mat4(1), glm::vec3(1.f / density));
|
||||
const auto start = glm::ifvec3(glm::divide(from.as_voxel(density)));
|
||||
const auto dist = far * density / CHUNK_LENGTH;
|
||||
for (const auto [_, area] : buffers) {
|
||||
const auto area_offset = glm::divide(area.first.as_voxel());
|
||||
const auto area_offset = glm::divide(std::get<0>(area.first).as_voxel());
|
||||
robin_hood::unordered_set<chunk_pos> done;
|
||||
for (const auto& occ: occlusion) {
|
||||
const geometry::Ray ray(start, occ, dist);
|
||||
|
@ -85,8 +94,9 @@ namespace contouring {
|
|||
for(auto& point: points) {
|
||||
auto it = area.second.find(glm::lvec3(point) - area_offset);
|
||||
if(it != area.second.end() && it->second != NULL && done.insert(it->first).second) {
|
||||
const glm::vec3 fPos = glm::vec3(area.first.raw_as_long() + glm::multiply(it->first) - offset * glm::llvec3(density)) + area.first.offset;
|
||||
out(glm::translate(scaling, fPos), it->second);
|
||||
const auto vPos = glm::multiply(it->first);
|
||||
const glm::vec3 fPos = glm::vec3(std::get<0>(area.first).raw_as_long() + vPos - offset * glm::llvec3(density)) + std::get<0>(area.first).offset;
|
||||
out(glm::translate(scaling, fPos), it->second, area.first, vPos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,15 +18,15 @@ namespace contouring {
|
|||
|
||||
/// Get buffers in frustum with model matrices
|
||||
/// @note buffers invalidated after update
|
||||
void getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &draw, const std::optional<geometry::Frustum> &frustum, const glm::llvec3 &offset, int density) override;
|
||||
void getModels(draw_call draw, const std::optional<geometry::Frustum> &frustum, const glm::llvec3 &offset, int density) override;
|
||||
/// Get buffers hitting occlusion rays with model matrices
|
||||
/// @note buffers invalidated after update
|
||||
void getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) override;
|
||||
void getModels(draw_call draw, const glm::ifvec3 &from, float far, const std::vector<glm::vec3> &occlusion, const glm::llvec3 &offset, int density) override;
|
||||
|
||||
protected:
|
||||
size_t clear(const voxel_pos &, const world::area_map &areas);
|
||||
|
||||
robin_hood::unordered_map<area_id, robin_hood::pair<area_pos, robin_hood::unordered_map<chunk_pos, buffer::Abstract *>>> buffers;
|
||||
robin_hood::unordered_map<area_id, robin_hood::pair<area_info, robin_hood::unordered_map<chunk_pos, buffer::Abstract *>>> buffers;
|
||||
|
||||
int loadDistance = 3;
|
||||
int keepDistance = 4;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace contouring {
|
|||
void onGui() override { }
|
||||
std::string getOptions() const override { return ""; }
|
||||
std::pair<float, float> getFarRange() const override { return std::make_pair(0, 0); }
|
||||
void getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &, const std::optional<geometry::Frustum> &, const glm::llvec3 &, int) override {}
|
||||
void getModels(const std::function<void(glm::mat4, buffer::Abstract *const)> &, const glm::ifvec3 &, float, const std::vector<glm::vec3> &, const glm::llvec3 &, int) override {}
|
||||
void getModels(draw_call, const std::optional<geometry::Frustum> &, const glm::llvec3 &, int) override {}
|
||||
void getModels(draw_call, const glm::ifvec3 &, float, const std::vector<glm::vec3> &, const glm::llvec3 &, int) override {}
|
||||
};
|
||||
}
|
|
@ -133,8 +133,16 @@ namespace contouring {
|
|||
while (it_a != buffers.end()) { // Remove out of range buffers
|
||||
if (const auto area = areas.find(it_a->first); area != areas.end()) {
|
||||
//Update
|
||||
it_a->second.first = area->second->getOffset();
|
||||
const auto center = glm::divide(pos - it_a->second.first.as_voxel());
|
||||
std::get<0>(it_a->second.first) = area->second->getOffset();
|
||||
std::get<1>(it_a->second.first) = area->second->getChunks().getRadius() * static_cast<long long>(CHUNK_LENGTH);
|
||||
const auto centerV = pos - std::get<0>(it_a->second.first).as_voxel();
|
||||
if (auto planet = std::get_if<world::Generator::Properties::planet>(
|
||||
&area->second->getGenerator().getProperties().shape)) {
|
||||
const auto dist = glm::max_axis(glm::abs(centerV));
|
||||
const auto surface = planet->height * (1.1+planet->surface_roughness);
|
||||
std::get<2>(it_a->second.first) = std::clamp<float>((dist - surface) / (std::get<1>(it_a->second.first) - surface), -0.1f, 1.f);
|
||||
}
|
||||
const auto center = glm::divide(centerV);
|
||||
auto &bfs = it_a->second.second;
|
||||
auto it = bfs.begin();
|
||||
while(it != bfs.end()) {
|
||||
|
|
|
@ -40,7 +40,7 @@ private:
|
|||
GLFWwindow *window;
|
||||
const InputMap &inputs;
|
||||
|
||||
float HorizontalAngle = 3.14f;
|
||||
float HorizontalAngle = 3.14f / 2;
|
||||
float VerticalAngle = 0.0f;
|
||||
|
||||
bool capturingMouse = false;
|
||||
|
|
|
@ -200,7 +200,9 @@ int main(int /*unused*/, char */*unused*/[]){
|
|||
}
|
||||
const auto offset = state.position.raw_as_long();
|
||||
{ // Chunks
|
||||
const auto draw = [&](glm::mat4 model, buffer::Abstract *const buffer) {
|
||||
const auto draw = [&](glm::mat4 model, buffer::Abstract *const buffer, const contouring::Abstract::area_info &area, const voxel_pos &pos) {
|
||||
renderer->SphereProj = glm::vec4(pos, std::get<1>(area));
|
||||
renderer->Curvature = std::get<2>(area);
|
||||
reports.models_count++;
|
||||
reports.tris_count += buffer->draw(pass.setup(model));
|
||||
};
|
||||
|
|
|
@ -36,6 +36,12 @@ public:
|
|||
glm::vec3 FogColor;
|
||||
GLfloat FogDepth;
|
||||
|
||||
/// Sphere bending
|
||||
/// offset.xyz radius.w
|
||||
glm::vec4 SphereProj;
|
||||
/// Ratio between spherical and cartesian
|
||||
float Curvature;
|
||||
|
||||
bool SkyEnable;
|
||||
|
||||
glm::mat4 getProjectionMatrix() const {
|
||||
|
|
|
@ -83,6 +83,14 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
|
|||
ImGui::TextDisabled("Blend");
|
||||
}
|
||||
|
||||
changeRenderer |= ImGui::Checkbox("Curvature", &options.renderer.main.curvature);
|
||||
ImGui::SameLine();
|
||||
if(options.renderer.main.curvature) {
|
||||
changeRenderer |= ImGui::Checkbox("Depth", &options.renderer.main.curv_depth);
|
||||
} else {
|
||||
ImGui::TextDisabled("Depth");
|
||||
}
|
||||
|
||||
changeRenderer |= ImGui::Checkbox("Fog", &options.renderer.main.fog);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Skybox", &options.renderer.skybox);
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace buffer {
|
|||
Nrm[3] = nw;
|
||||
}
|
||||
GLushort PosMat[4];
|
||||
GLushort Nrm[4];
|
||||
GLushort Nrm[4]; //NOTE: Triplanar does not handle 10_10_10_2_REV
|
||||
bool operator<(const PackedVertexData that) const {
|
||||
return memcmp((void *)this, (void *)&that, sizeof(PackedVertexData)) > 0;
|
||||
};
|
||||
|
|
|
@ -18,6 +18,11 @@ MainProgram::MainProgram(const MainProgram::options& opts): Program() {
|
|||
if (opts.blend)
|
||||
flags.emplace_back("BLEND");
|
||||
}
|
||||
if (opts.curvature) {
|
||||
flags.emplace_back("CURVATURE");
|
||||
if (opts.curv_depth)
|
||||
flags.emplace_back("CURV_DEPTH");
|
||||
}
|
||||
|
||||
std::vector<Shader*> shaders;
|
||||
shaders.push_back(loadShader(GL_VERTEX_SHADER, flags));
|
||||
|
@ -26,9 +31,9 @@ MainProgram::MainProgram(const MainProgram::options& opts): Program() {
|
|||
shaders.push_back(loadShader(GL_GEOMETRY_SHADER, flags));
|
||||
load(shaders);
|
||||
|
||||
MVPMatrixID = glGetUniformLocation(ProgramID, "MVP");
|
||||
ModelMatrixID = glGetUniformLocation(ProgramID, "Model");
|
||||
ViewMatrixID = glGetUniformLocation(ProgramID, "View");
|
||||
ProjMatrixID = glGetUniformLocation(ProgramID, "Proj");
|
||||
|
||||
TextureID = glGetUniformLocation(ProgramID, "TextureAtlas");
|
||||
NormalID = glGetUniformLocation(ProgramID, "NormalAtlas");
|
||||
|
@ -38,6 +43,9 @@ MainProgram::MainProgram(const MainProgram::options& opts): Program() {
|
|||
|
||||
FogDepthID = glGetUniformLocation(ProgramID, "FogDepth");
|
||||
FogColorID = glGetUniformLocation(ProgramID, "FogColor");
|
||||
|
||||
SphereProjID = glGetUniformLocation(ProgramID, "SphereProj");
|
||||
CurvatureID = glGetUniformLocation(ProgramID, "Curvature");
|
||||
}
|
||||
|
||||
MainProgram::~MainProgram() { }
|
||||
|
@ -51,17 +59,18 @@ void MainProgram::start(Renderer *renderer) {
|
|||
bindHOS(renderer->getHOSAtlas());
|
||||
setLightInvDir(&renderer->LightInvDir[0]);
|
||||
setFog(&renderer->FogColor[0], renderer->FogDepth);
|
||||
setView(&renderer->getViewMatrix()[0][0]);
|
||||
setProj(&renderer->getProjectionMatrix()[0][0]);
|
||||
}
|
||||
buffer::params MainProgram::setup(Renderer *renderer, glm::mat4 modelMatrix) {
|
||||
setModel(&modelMatrix[0][0]);
|
||||
setView(&renderer->getViewMatrix()[0][0]);
|
||||
const auto mvp = renderer->getProjectionMatrix() * renderer->getViewMatrix() * modelMatrix;
|
||||
setMVP(&mvp[0][0]);
|
||||
setSphereProj(&renderer->SphereProj[0]);
|
||||
setCurvature(renderer->Curvature);
|
||||
return buffer::params{.vertexOnly = false};
|
||||
}
|
||||
|
||||
void MainProgram::setMVP(const GLfloat *matrix) {
|
||||
glUniformMatrix4fv(MVPMatrixID, 1, GL_FALSE, matrix);
|
||||
void MainProgram::setProj(const GLfloat *matrix) {
|
||||
glUniformMatrix4fv(ProjMatrixID, 1, GL_FALSE, matrix);
|
||||
}
|
||||
void MainProgram::setModel(const GLfloat *matrix) {
|
||||
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, matrix);
|
||||
|
@ -92,4 +101,11 @@ void MainProgram::setLightInvDir(const GLfloat *pos) {
|
|||
void MainProgram::setFog(const GLfloat *color, const GLfloat depth) {
|
||||
glUniform3fv(FogColorID, 1, color);
|
||||
glUniform1f(FogDepthID, depth);
|
||||
}
|
||||
|
||||
void MainProgram::setSphereProj(const GLfloat *posRad) {
|
||||
glUniform4fv(SphereProjID, 1, posRad);
|
||||
}
|
||||
void MainProgram::setCurvature(GLfloat ratio) {
|
||||
glUniform1f(CurvatureID, ratio);
|
||||
}
|
|
@ -18,6 +18,10 @@ namespace pass {
|
|||
bool blend = true;
|
||||
/// Depth fog
|
||||
bool fog = true;
|
||||
/// Map planets to sphere
|
||||
bool curvature = true;
|
||||
/// Keep depth in sphere
|
||||
bool curv_depth = true;
|
||||
};
|
||||
|
||||
MainProgram(const options &opts);
|
||||
|
@ -27,9 +31,9 @@ namespace pass {
|
|||
void start(Renderer *) override;
|
||||
buffer::params setup(Renderer *, glm::mat4 modelMatrix) override;
|
||||
|
||||
void setMVP(const GLfloat *matrix);
|
||||
void setModel(const GLfloat *matrix);
|
||||
void setView(const GLfloat *matrix);
|
||||
void setProj(const GLfloat *matrix);
|
||||
|
||||
void bindTexture(const GLuint textureID);
|
||||
void bindNormal(const GLuint textureID);
|
||||
|
@ -38,10 +42,13 @@ namespace pass {
|
|||
void setLightInvDir(const GLfloat *pos);
|
||||
void setFog(const GLfloat *color, GLfloat depth);
|
||||
|
||||
void setSphereProj(const GLfloat *offRad);
|
||||
void setCurvature(GLfloat ratio);
|
||||
|
||||
private:
|
||||
GLuint MVPMatrixID;
|
||||
GLuint ModelMatrixID;
|
||||
GLuint ViewMatrixID;
|
||||
GLuint ProjMatrixID;
|
||||
|
||||
GLuint TextureID;
|
||||
GLuint NormalID;
|
||||
|
@ -50,5 +57,8 @@ namespace pass {
|
|||
GLuint LightInvDirID;
|
||||
GLuint FogDepthID;
|
||||
GLuint FogColorID;
|
||||
|
||||
GLuint SphereProjID;
|
||||
GLuint CurvatureID;
|
||||
};
|
||||
}
|
|
@ -48,9 +48,9 @@ Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"
|
|||
} else {
|
||||
LOG_E("No index file!!! Probably a new world...");
|
||||
//TODO: generate universe
|
||||
/*const auto radius = 1 << 4;
|
||||
far_areas.emplace(Area::params{glm::multiply(voxel_pos(radius)), radius, Generator::Properties(radius * CHUNK_LENGTH * 3 / 4, 42)});*/
|
||||
far_areas.emplace(Area::params{voxel_pos(0), 1 << 20, Generator::Properties(42)});
|
||||
const auto radius = 1 << 4;
|
||||
far_areas.emplace(Area::params{glm::multiply(voxel_pos(radius, 0, 0)), radius, Generator::Properties(radius * CHUNK_LENGTH * 3 / 4, 42)});
|
||||
//far_areas.emplace(Area::params{voxel_pos(0), 1 << 20, Generator::Properties(42)});
|
||||
}
|
||||
index.close();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue