Fix portal culling when looking down or up

This commit is contained in:
tovjemam 2025-08-14 21:40:01 +02:00
parent be42793021
commit 0c32e21955

View File

@ -240,19 +240,20 @@ bool gfx::Renderer::ComputePortalScreenAABB(const game::Portal& portal, const gl
{
size_t num_behind = 0;
glm::vec4 clip[4];
for (size_t i = 0; i < 4; ++i)
{
glm::vec4 vert = glm::vec4(portal.verts[i], 1.0f);
glm::vec4 clip = view_proj * vert;
clip[i] = view_proj * vert;
if (clip.w <= 0.0f)
if (clip[i].w <= 0.0f)
{
num_behind++;
continue; // Skip vertices behind the camera
}
glm::vec2 ndc = clip;
ndc /= clip.w;
glm::vec2 ndc = clip[i];
ndc /= clip[i].w;
aabb.AddPoint(ndc);
}
@ -262,10 +263,73 @@ bool gfx::Renderer::ComputePortalScreenAABB(const game::Portal& portal, const gl
return false; // All vertices are behind the camera, no visible portal
}
if (num_behind > 0)
if (num_behind == 0)
{
// Some vertices are behind the camera, cannot use the AABB
aabb = collision::AABB2(glm::vec2(-1.0f), glm::vec2(1.0f)); // Full screen AABB
return true;
}
aabb = collision::AABB2(glm::vec2(-1.0f), glm::vec2(1.0f)); // Full screen AABB
// Check if all vertices are behind any clipping plane
size_t num_behind_plane = 0;
for (size_t i = 0; i < 4; ++i)
{
if (clip[i].x < -clip[i].w)
{
num_behind_plane++;
}
}
if (num_behind_plane == 4)
{
return false; // All vertices are behind the clipping plane, no visible portal
}
num_behind_plane = 0;
for (size_t i = 0; i < 4; ++i)
{
if (clip[i].x > clip[i].w)
{
num_behind_plane++;
}
}
if (num_behind_plane == 4)
{
return false; // All vertices are in front of the clipping plane, no visible portal
}
num_behind_plane = 0;
for (size_t i = 0; i < 4; ++i)
{
if (clip[i].y < -clip[i].w)
{
num_behind_plane++;
}
}
if (num_behind_plane == 4)
{
return false; // All vertices are below the clipping plane, no visible portal
}
num_behind_plane = 0;
for (size_t i = 0; i < 4; ++i)
{
if (clip[i].y > clip[i].w)
{
num_behind_plane++;
}
}
if (num_behind_plane == 4)
{
return false; // All vertices are above the clipping plane, no visible portal
}
return true;