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; size_t num_behind = 0;
glm::vec4 clip[4];
for (size_t i = 0; i < 4; ++i) for (size_t i = 0; i < 4; ++i)
{ {
glm::vec4 vert = glm::vec4(portal.verts[i], 1.0f); 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++; num_behind++;
continue; // Skip vertices behind the camera continue; // Skip vertices behind the camera
} }
glm::vec2 ndc = clip; glm::vec2 ndc = clip[i];
ndc /= clip.w; ndc /= clip[i].w;
aabb.AddPoint(ndc); 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 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 return true;
aabb = collision::AABB2(glm::vec2(-1.0f), glm::vec2(1.0f)); // Full screen AABB }
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; return true;