proper frustum culling
parent
e69c58abd3
commit
383fb60686
|
@ -18,7 +18,7 @@ public:
|
||||||
{
|
{
|
||||||
view = glm::mat4(1.0f);
|
view = glm::mat4(1.0f);
|
||||||
// note that we're translating the scene in the reverse direction of where we want to move
|
// note that we're translating the scene in the reverse direction of where we want to move
|
||||||
projection = glm::perspective(glm::radians(90.0f), 800.0f / 600.0f, 0.1f, 200.0f);
|
projection = glm::perspective(glm::radians(90.0f), 800.0f / 600.0f, 1.0f, 200.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(GLFWwindow *window, float deltaTime)
|
void update(GLFWwindow *window, float deltaTime)
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
|
|
||||||
void viewPortCallBack(GLFWwindow *window, int width, int height)
|
void viewPortCallBack(GLFWwindow *window, int width, int height)
|
||||||
{
|
{
|
||||||
projection = glm::perspective(glm::radians(70.0f), (float)width / (float)height, 0.1f, 350.0f);
|
projection = glm::perspective(glm::radians(80.0f), (float)width / (float)height, 1.0f, 350.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouseCallback(GLFWwindow *window, double xpos, double ypos)
|
void mouseCallback(GLFWwindow *window, double xpos, double ypos)
|
||||||
|
@ -97,6 +97,32 @@ public:
|
||||||
return projection;
|
return projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Plane extraction as per Gribb&Hartmann
|
||||||
|
// 6 planes, each with 4 components (a,b,c,d)
|
||||||
|
void getFrustumPlanes(glm::vec4 planes[6], bool normalize){
|
||||||
|
glm::mat4 mat = transpose(projection*view);
|
||||||
|
|
||||||
|
// This just compressed the code below
|
||||||
|
float ap = mat[3][0], bp = mat[3][1], cp = mat[3][2], dp = mat[3][3];
|
||||||
|
|
||||||
|
planes[0] = glm::vec4(ap + mat[0][0], bp + mat[0][1], cp + mat[0][2], dp + mat[0][3]);
|
||||||
|
planes[1] = glm::vec4(ap - mat[0][0], bp - mat[0][1], cp - mat[0][2], dp - mat[0][3]);
|
||||||
|
planes[2] = glm::vec4(ap + mat[1][0], bp + mat[1][1], cp + mat[1][2], dp + mat[1][3]);
|
||||||
|
planes[3] = glm::vec4(ap - mat[1][0], bp - mat[1][1], cp - mat[1][2], dp - mat[1][3]);
|
||||||
|
planes[4] = glm::vec4(ap + mat[2][0], bp + mat[2][1], cp + mat[2][2], dp + mat[2][3]);
|
||||||
|
planes[5] = glm::vec4(ap - mat[2][0], bp - mat[2][1], cp - mat[2][2], dp - mat[2][3]);
|
||||||
|
|
||||||
|
if(normalize)
|
||||||
|
for(int i = 0; i < 6; i++){
|
||||||
|
float mag = sqrt(planes[i].x + planes[i].x + planes[i].y * planes[i].y +
|
||||||
|
planes[i].z*planes[i].z);
|
||||||
|
|
||||||
|
planes[i] /= mag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::vec3 cameraPos = glm::vec3(static_cast<float>(CHUNK_SIZE)*24, 40.0f, static_cast<float>(CHUNK_SIZE)*24);
|
glm::vec3 cameraPos = glm::vec3(static_cast<float>(CHUNK_SIZE)*24, 40.0f, static_cast<float>(CHUNK_SIZE)*24);
|
||||||
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
|
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||||
|
@ -109,4 +135,4 @@ private:
|
||||||
float yaw, pitch;
|
float yaw, pitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -93,6 +93,7 @@ namespace chunkmanager
|
||||||
int total{0}, toGpu{0};
|
int total{0}, toGpu{0};
|
||||||
int rr{RENDER_DISTANCE * RENDER_DISTANCE};
|
int rr{RENDER_DISTANCE * RENDER_DISTANCE};
|
||||||
uint8_t f = 0;
|
uint8_t f = 0;
|
||||||
|
glm::vec4 frustumPlanes[6];
|
||||||
|
|
||||||
void update(float deltaTime)
|
void update(float deltaTime)
|
||||||
{
|
{
|
||||||
|
@ -103,6 +104,7 @@ namespace chunkmanager
|
||||||
// Iterate over all chunks, in concentric spheres starting fron the player and going outwards
|
// Iterate over all chunks, in concentric spheres starting fron the player and going outwards
|
||||||
// Eq. of the sphere (x - a)² + (y - b)² + (z - c)² = r²
|
// Eq. of the sphere (x - a)² + (y - b)² + (z - c)² = r²
|
||||||
glm::vec3 cameraPos = theCamera.getPos();
|
glm::vec3 cameraPos = theCamera.getPos();
|
||||||
|
theCamera.getFrustumPlanes(frustumPlanes, true);
|
||||||
|
|
||||||
int chunkX{(static_cast<int>(cameraPos.x)) / CHUNK_SIZE}, chunkY{(static_cast<int>(cameraPos.y)) / CHUNK_SIZE}, chunkZ{(static_cast<int>(cameraPos.z)) / CHUNK_SIZE};
|
int chunkX{(static_cast<int>(cameraPos.x)) / CHUNK_SIZE}, chunkY{(static_cast<int>(cameraPos.y)) / CHUNK_SIZE}, chunkZ{(static_cast<int>(cameraPos.z)) / CHUNK_SIZE};
|
||||||
|
|
||||||
|
@ -175,9 +177,9 @@ namespace chunkmanager
|
||||||
b = false;
|
b = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
|
std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
|
||||||
// total = 0;
|
total = 0;
|
||||||
// toGpu = 0;
|
toGpu = 0;
|
||||||
|
|
||||||
if ((f & 1))
|
if ((f & 1))
|
||||||
mutex_queue_generate.unlock();
|
mutex_queue_generate.unlock();
|
||||||
|
@ -188,7 +190,6 @@ namespace chunkmanager
|
||||||
// Generation and meshing happen in two separate threads from the main one
|
// Generation and meshing happen in two separate threads from the main one
|
||||||
// Chunk states are used to decide which actions need to be done on the chunk and queues+mutexes to pass the chunks between the threads
|
// Chunk states are used to decide which actions need to be done on the chunk and queues+mutexes to pass the chunks between the threads
|
||||||
// Uploading data to GPU still needs to be done in the main thread, or another OpenGL context needs to be opened, which further complicates stuff
|
// Uploading data to GPU still needs to be done in the main thread, or another OpenGL context needs to be opened, which further complicates stuff
|
||||||
// For now using frustum culling decreases performance (somehow)
|
|
||||||
void updateChunk(uint32_t index, uint16_t i, uint16_t j, uint16_t k)
|
void updateChunk(uint32_t index, uint16_t i, uint16_t j, uint16_t k)
|
||||||
{
|
{
|
||||||
if (chunks.find(index) == chunks.end())
|
if (chunks.find(index) == chunks.end())
|
||||||
|
@ -253,48 +254,39 @@ namespace chunkmanager
|
||||||
c->setState(Chunk::CHUNK_STATE_MESH_LOADED, true);
|
c->setState(Chunk::CHUNK_STATE_MESH_LOADED, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 chunk = c->getPosition();
|
// Frustum Culling of chunk
|
||||||
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
|
||||||
// chunkmesher::draw(c, model);
|
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
int a{0};
|
glm::vec3 chunk = c->getPosition();
|
||||||
for (int i = 0; i < 8; i++)
|
glm::vec4 chunkW = glm::vec4(chunk.x*static_cast<float>(CHUNK_SIZE), chunk.y*static_cast<float>(CHUNK_SIZE), chunk.z*static_cast<float>(CHUNK_SIZE),1.0);
|
||||||
{
|
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
||||||
glm::vec4 vertex = glm::vec4(chunk.x + (float)(i & 1), chunk.y + (float)((i & 2) >> 1), chunk.z + (float)((i & 4) >> 2), 500.0f) * (theCamera.getProjection() * theCamera.getView() * model);
|
|
||||||
vertex = glm::normalize(vertex);
|
|
||||||
|
|
||||||
a += (-vertex.w <= vertex.x && vertex.x <= vertex.w && -vertex.w <= vertex.y && vertex.y <= vertex.w /*&& -vertex.w < vertex.z && vertex.z < vertex.w*/);
|
bool out=false;
|
||||||
}
|
// First test, check if all the corners of the chunk are outside any of the
|
||||||
if (a)
|
// planes
|
||||||
|
for(int p = 0; p < 6; p++){
|
||||||
|
|
||||||
|
int a{0};
|
||||||
|
for(int i = 0; i < 8; i++) {
|
||||||
|
a+=glm::dot(frustumPlanes[p], glm::vec4(chunkW.x + ((float)(i & 1))*CHUNK_SIZE, chunkW.y
|
||||||
|
+ ((float)((i
|
||||||
|
& 2) >> 1))*CHUNK_SIZE, chunkW.z + ((float)((i & 4) >>
|
||||||
|
2))*CHUNK_SIZE, 1.0)) < 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(a==8){
|
||||||
|
out=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!out)
|
||||||
{
|
{
|
||||||
toGpu++;
|
toGpu++;
|
||||||
chunkmesher::draw(c, model);
|
chunkmesher::draw(c, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ((f & 4) == 4)
|
|
||||||
// {
|
|
||||||
// glm::vec3 chunk = c->getPosition();
|
|
||||||
// glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
|
||||||
// // chunkmesher::draw(c, model);
|
|
||||||
// // total++;
|
|
||||||
|
|
||||||
// // int a{0};
|
|
||||||
// // for (int i = 0; i < 8; i++)
|
|
||||||
// // {
|
|
||||||
// // glm::vec4 vertex = glm::vec4(chunk.x + (float)(i & 1), chunk.y + (float)((i & 2) >> 1), chunk.z + (float)((i & 4) >> 2), 500.0f) * (theCamera.getProjection() * theCamera.getView() * model);
|
|
||||||
// // vertex = glm::normalize(vertex);
|
|
||||||
|
|
||||||
// // a += (-vertex.w <= vertex.x && vertex.x <= vertex.w && -vertex.w <= vertex.y && vertex.y <= vertex.w /*&& -vertex.w < vertex.z && vertex.z < vertex.w*/);
|
|
||||||
// // }
|
|
||||||
// // if (a)
|
|
||||||
// // {
|
|
||||||
// // toGpu++;
|
|
||||||
// chunkmesher::draw(c, model);
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
c->mutex_state.unlock();
|
c->mutex_state.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue