Optimized lighting, frustum culling, generator

- Extended CHUNK_H to 256
- Modified world generator for new world height
- Added simple 2d frustum culling
- Optimized sky lighting calculations
This commit is contained in:
MihailRis 2021-09-17 19:15:14 +03:00 committed by GitHub
parent a11ab33115
commit 01c6c854e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 18 deletions

View File

@ -133,7 +133,7 @@ void Lighting::onChunkLoaded(int cx, int cy, int cz){
break;
current->lightmap->setS(x,y,z, 15);
current->modified = true;
solverS->add(gx,y+ncy*CHUNK_H,gz);
//solverS->add(gx,y+ncy*CHUNK_H,gz);
}
}
}

View File

@ -59,6 +59,8 @@ LineBatch *lineBatch;
Chunks* chunks;
WorldFiles* wfile;
bool occlusion = false;
// All in-game definitions (blocks, items, etc..)
void setup_definitions() {
// AIR
@ -130,15 +132,24 @@ int initialize_assets() {
}
void draw_world(Camera* camera){
glClearColor(0.7f,0.85f,1.0f,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw VAO
shader->use();
shader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
shader->uniformMatrix("u_proj", camera->getProjection());
shader->uniformMatrix("u_view", camera->getView());
shader->uniform1f("u_gamma", 1.6f);
shader->uniform3f("u_skyLightColor", 0.1*2,0.15*2,0.2*2);
shader->uniform3f("u_skyLightColor", 1.8f,1.8f,1.8f);
shader->uniform3f("u_fogColor", 0.7f,0.85f,1.0f);
texture->bind();
mat4 model(1.0f);
const float cameraX = camera->position.x;
const float cameraZ = camera->position.z;
const float camDirX = camera->dir.x;
const float camDirZ = camera->dir.z;
for (size_t i = 0; i < chunks->volume; i++){
Chunk* chunk = chunks->chunks[i];
if (chunk == nullptr)
@ -146,6 +157,28 @@ void draw_world(Camera* camera){
Mesh* mesh = chunks->meshes[i];
if (mesh == nullptr)
continue;
// Simple frustum culling (culling chunks behind the camera in 2D - XZ)
if (occlusion){
bool unoccluded = false;
do {
if ((chunk->x*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + (chunk->z*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if (((chunk->x+1)*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
if ((chunk->x*CHUNK_W-cameraX)*camDirX + ((chunk->z+1)*CHUNK_D-cameraZ)*camDirZ >= 0.0){
unoccluded = true; break;
}
} while (false);
if (!unoccluded)
continue;
}
model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W+0.5f, chunk->y*CHUNK_H+0.5f, chunk->z*CHUNK_D+0.5f));
shader->uniformMatrix("u_model", model);
mesh->draw(GL_TRIANGLES);
@ -210,7 +243,7 @@ int main() {
crosshair = new Mesh(vertices, 4, attrs);
Camera* camera = new Camera(vec3(32,32,32), radians(90.0f));
Hitbox* hitbox = new Hitbox(vec3(32,32,32), vec3(0.2f,0.9f,0.2f));
Hitbox* hitbox = new Hitbox(vec3(32,120,32), vec3(0.2f,0.9f,0.2f));
float lastTime = glfwGetTime();
float delta = 0.0f;
@ -223,7 +256,7 @@ int main() {
int choosenBlock = 1;
long frame = 0;
glfwSwapInterval(1);
glfwSwapInterval(0);
while (!Window::isShouldClose()){
frame++;
@ -231,6 +264,13 @@ int main() {
delta = currentTime - lastTime;
lastTime = currentTime;
//if (frame % 240 == 0)
// std::cout << delta << std::endl;
if (Events::jpressed(GLFW_KEY_O)){
occlusion = !occlusion;
}
if (Events::jpressed(GLFW_KEY_ESCAPE)){
Window::setShouldClose(true);
}

View File

@ -2,7 +2,7 @@
#define VOXELS_CHUNK_H_
#define CHUNK_W 16
#define CHUNK_H 64
#define CHUNK_H 256
#define CHUNK_D 16
#define CHUNK_VOL (CHUNK_W * CHUNK_H * CHUNK_D)

View File

@ -321,7 +321,7 @@ bool Chunks::loadVisible(WorldFiles* worldFiles){
int nearX = 0;
int nearY = 0;
int nearZ = 0;
int minDistance = 1000000000;
int minDistance = (w/2)*(w/2);
for (unsigned int y = 0; y < h; y++){
for (unsigned int z = 1; z < d-1; z++){
for (unsigned int x = 1; x < w-1; x++){

View File

@ -1,29 +1,35 @@
#include "WorldGenerator.h"
#include "voxel.h";
#include "Chunk.h";
#include "voxel.h"
#include "Chunk.h"
#include <math.h>
#include <glm/glm.hpp>
#include <glm/gtc/noise.hpp>
void WorldGenerator::generate(voxel* voxels, int cx, int cy, int cz){
const float s = 0.25f;
for (int z = 0; z < CHUNK_D; z++){
for (int x = 0; x < CHUNK_W; x++){
int real_x = x + cx * CHUNK_W;
int real_z = z + cz * CHUNK_D;
float height = glm::perlin(glm::vec3(real_x*0.0125f,real_z*0.0125f, 0.0f));
height += glm::perlin(glm::vec3(real_x*0.025f,real_z*0.025f, 0.0f))*0.5f;
height *= 0.1f;
height += 0.05f;
float height = glm::perlin(glm::vec3(real_x*0.0125f*s,real_z*0.0125f*s, 0.0f));
height += glm::perlin(glm::vec3(real_x*0.025f*s,real_z*0.025f*s, 0.0f))*0.5f;
height += glm::perlin(glm::vec3(real_x*0.05f*s,real_z*0.05f*s, 0.0f))*0.25f;
height += glm::perlin(glm::vec3(real_x*0.1f*s,real_z*0.1f*s, 0.0f))*0.225f;
height += glm::perlin(glm::vec3(real_x*0.2f*s,real_z*0.2f*s, 0.0f))*0.125f;
height = height * 0.5f + 0.5f;
height *= height;
height *= 140.0f;
height += 48;
for (int y = 0; y < CHUNK_H; y++){
int real_y = y + cy * CHUNK_H;
float noise = height;
int id = noise / std::fmax(0.01f, real_y*0.1f + 0.1f) > 0.1f;
int id = 0;
if (real_y == (int)height)
id = 2;
else if (real_y < height)
id = 1;
if (real_y <= 2)
id = 2;
if (id == 0 && real_y == 14 && height <= 0.01f)
id = 1;
voxels[(y * CHUNK_D + z) * CHUNK_W + x].id = id;
}
}