Anonymous
Функция Frustum Culling прерывается при взгляде вверх или вниз.
Сообщение
Anonymous » 11 май 2024, 00:50
Название все объясняет, но подведем итог. Когда направление камеры не направлено вниз или вверх, отсечение Frustum работает нормально (я проверял количество вызовов отрисовки и т. д. через консоль).
НО оно не работает при взгляде вверх и вниз (выглядит так, как будто это не так). масштабируется правильно, но я не уверен).
Я загрузил это видео здесь, так что вам, вероятно, стоит его посмотреть.
https://streamable.com/pjp0nh
Frustum.h
Код: Выделить всё
struct BoundingBox
{
Vec center;
Vec extents;
};
struct Plane_t
{
Vec normal;
float distance;
};
struct Frustum_t
{
Plane_t topface;
Plane_t bottomface;
Plane_t rightface;
Plane_t leftface;
Plane_t farface;
Plane_t nearface;
};
Frustum_t MakeFrustumFromView(const Vec& pos, const Vec& dir, float fov, float near, float far);
bool isBoundingBoxOnForwardPlane(const BoundingBox& boundingbox, const Plane_t& plane);
bool IsBoundingBoxInFrustum(const BoundingBox& boundingbox, const Frustum_t& frustum, const Mat4& transform);
Frustum.cpp
Код: Выделить всё
inline Plane_t MakeFrustumPlane(const Vec& point, const Vec& norm)
{
return { norm, norm.Dot(point) };
}
Frustum_t MakeFrustumFromView(const Vec& pos, const Vec& dir, float fov, float near, float far)
{
Vec normdir = dir.Normalize();
Vec upvec = { 0.0f, 1.0f, 0.0f };
Vec right = normdir.Cross(upvec).Normalize();
Vec up = right.Cross(normdir).Normalize();
Frustum_t frustum;
const float fHalfVSide = far * tanf(fov * DEG2RAD * 0.5f);
const float fHalfHSide = fHalfVSide * ((float)g_pGlobals->m_iScreenWidth / g_pGlobals->m_iScreenHeight);
const Vec fDirFar = normdir * far;
frustum.nearface = MakeFrustumPlane(pos + normdir * near, normdir);
frustum.farface = MakeFrustumPlane(pos + fDirFar, -normdir);
frustum.rightface = MakeFrustumPlane(pos, (fDirFar - right * fHalfHSide).Cross(up));
frustum.leftface = MakeFrustumPlane(pos, up.Cross(fDirFar + right * fHalfHSide));
frustum.topface = MakeFrustumPlane(pos, right.Cross(fDirFar - up * fHalfVSide));
frustum.bottomface = MakeFrustumPlane(pos, (fDirFar + up * fHalfVSide).Cross(right));
return frustum;
}
bool isBoundingBoxOnForwardPlane(const BoundingBox& boundingbox, const Plane_t& plane)
{
const float r = boundingbox.extents.x * fabsf(plane.normal.x) + boundingbox.extents.y * fabsf(plane.normal.y) + boundingbox.extents.z * fabsf(plane.normal.z);
return -r Кроме того, я хотел бы отметить, что для этого кода я следил за LearnOpenGL.
Подробнее здесь: [url]https://stackoverflow.com/questions/78460419/frustum-culling-breaks-when-looking-up-or-down[/url]
1715377840
Anonymous
Название все объясняет, но подведем итог. Когда направление камеры не направлено вниз или вверх, отсечение Frustum работает нормально (я проверял количество вызовов отрисовки и т. д. через консоль). НО оно не работает при взгляде вверх и вниз (выглядит так, как будто это не так). масштабируется правильно, но я не уверен). Я загрузил это видео здесь, так что вам, вероятно, стоит его посмотреть. https://streamable.com/pjp0nh Frustum.h [code]struct BoundingBox { Vec center; Vec extents; }; struct Plane_t { Vec normal; float distance; }; struct Frustum_t { Plane_t topface; Plane_t bottomface; Plane_t rightface; Plane_t leftface; Plane_t farface; Plane_t nearface; }; Frustum_t MakeFrustumFromView(const Vec& pos, const Vec& dir, float fov, float near, float far); bool isBoundingBoxOnForwardPlane(const BoundingBox& boundingbox, const Plane_t& plane); bool IsBoundingBoxInFrustum(const BoundingBox& boundingbox, const Frustum_t& frustum, const Mat4& transform); [/code] Frustum.cpp [code]inline Plane_t MakeFrustumPlane(const Vec& point, const Vec& norm) { return { norm, norm.Dot(point) }; } Frustum_t MakeFrustumFromView(const Vec& pos, const Vec& dir, float fov, float near, float far) { Vec normdir = dir.Normalize(); Vec upvec = { 0.0f, 1.0f, 0.0f }; Vec right = normdir.Cross(upvec).Normalize(); Vec up = right.Cross(normdir).Normalize(); Frustum_t frustum; const float fHalfVSide = far * tanf(fov * DEG2RAD * 0.5f); const float fHalfHSide = fHalfVSide * ((float)g_pGlobals->m_iScreenWidth / g_pGlobals->m_iScreenHeight); const Vec fDirFar = normdir * far; frustum.nearface = MakeFrustumPlane(pos + normdir * near, normdir); frustum.farface = MakeFrustumPlane(pos + fDirFar, -normdir); frustum.rightface = MakeFrustumPlane(pos, (fDirFar - right * fHalfHSide).Cross(up)); frustum.leftface = MakeFrustumPlane(pos, up.Cross(fDirFar + right * fHalfHSide)); frustum.topface = MakeFrustumPlane(pos, right.Cross(fDirFar - up * fHalfVSide)); frustum.bottomface = MakeFrustumPlane(pos, (fDirFar + up * fHalfVSide).Cross(right)); return frustum; } bool isBoundingBoxOnForwardPlane(const BoundingBox& boundingbox, const Plane_t& plane) { const float r = boundingbox.extents.x * fabsf(plane.normal.x) + boundingbox.extents.y * fabsf(plane.normal.y) + boundingbox.extents.z * fabsf(plane.normal.z); return -r Кроме того, я хотел бы отметить, что для этого кода я следил за LearnOpenGL. Подробнее здесь: [url]https://stackoverflow.com/questions/78460419/frustum-culling-breaks-when-looking-up-or-down[/url]