proper frustum culling
parent
e69c58abd3
commit
383fb60686
|
@ -18,7 +18,7 @@ public:
|
|||
{
|
||||
view = glm::mat4(1.0f);
|
||||
// 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)
|
||||
|
@ -49,7 +49,7 @@ public:
|
|||
|
||||
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)
|
||||
|
@ -97,6 +97,32 @@ public:
|
|||
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:
|
||||
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);
|
||||
|
|
|
@ -93,6 +93,7 @@ namespace chunkmanager
|
|||
int total{0}, toGpu{0};
|
||||
int rr{RENDER_DISTANCE * RENDER_DISTANCE};
|
||||
uint8_t f = 0;
|
||||
glm::vec4 frustumPlanes[6];
|
||||
|
||||
void update(float deltaTime)
|
||||
{
|
||||
|
@ -103,6 +104,7 @@ namespace chunkmanager
|
|||
// 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²
|
||||
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};
|
||||
|
||||
|
@ -175,9 +177,9 @@ namespace chunkmanager
|
|||
b = false;
|
||||
}
|
||||
}
|
||||
// std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
|
||||
// total = 0;
|
||||
// toGpu = 0;
|
||||
std::cout << "Total chunks to draw: " << total << ". Sent to GPU: " << toGpu << "\n";
|
||||
total = 0;
|
||||
toGpu = 0;
|
||||
|
||||
if ((f & 1))
|
||||
mutex_queue_generate.unlock();
|
||||
|
@ -188,7 +190,6 @@ namespace chunkmanager
|
|||
// 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
|
||||
// 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)
|
||||
{
|
||||
if (chunks.find(index) == chunks.end())
|
||||
|
@ -253,48 +254,39 @@ namespace chunkmanager
|
|||
c->setState(Chunk::CHUNK_STATE_MESH_LOADED, true);
|
||||
}
|
||||
|
||||
glm::vec3 chunk = c->getPosition();
|
||||
glm::mat4 model = glm::translate(glm::mat4(1.0), ((float)CHUNK_SIZE) * chunk);
|
||||
// chunkmesher::draw(c, model);
|
||||
// Frustum Culling of chunk
|
||||
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);
|
||||
glm::vec3 chunk = c->getPosition();
|
||||
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);
|
||||
|
||||
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)
|
||||
bool out=false;
|
||||
// First test, check if all the corners of the chunk are outside any of the
|
||||
// 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++;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue