Hi Tim,
While researching other thing upgrading our application to Unreal 5.8.1, I fell on the below code implementation: (C:\Program Files\Epic Games\UE_5.8\Engine\Plugins\Runtime\nDisplay\Source\DisplayCluster\Public\Math)
/**
* Builds a perspective projection matrix from asymmetric near-plane extents (off-axis frustum).
* Inputs are signed distances from the eye to each frustum edge, measured at the near plane.
* The result uses Unreal’s Z-inverted left-handed convention.
*
* @param InLeft Left edge extent at the near plane (typically negative).
* @param InRight Right edge extent at the near plane (typically positive).
* @param InTop Top edge extent at the near plane (typically positive).
* @param InBottom Bottom edge extent at the near plane (typically negative).
* @param InZNear Near clip plane distance (must be > 0).
* @param InZFar Far clip plane distance. Pass InZNear to use an unlimited far plane.
*/
template <typename T>
static UE::Math::TMatrix<T> MakeAsymmetricProjectionMatrix(const T InLeft, const T InRight, const T InTop, const T InBottom, const T InZNear, const T InZFar)
{
const T mx = static_cast<T>(2) * InZNear / (InRight - InLeft);
const T my = static_cast<T>(2) * InZNear / (InTop - InBottom);
const T ma = -(InRight + InLeft) / (InRight - InLeft);
const T mb = -(InTop + InBottom) / (InTop - InBottom);
// Support unlimited far plane (InZFar == InZNear)
const T mc = (InZFar == InZNear) ? (static_cast<T>(1) - Z_PRECISION) : (InZFar / (InZFar - InZNear));
const T md = (InZFar == InZNear) ? (-InZNear * (static_cast<T>(1) - Z_PRECISION)) : (-(InZFar * InZNear) / (InZFar - InZNear));
const T me = static_cast<T>(1);
// Normal LHS
const UE::Math::TMatrix<T> ProjectionMatrix = UE::Math::TMatrix<T>(
FPlane(mx, 0, 0, 0),
FPlane(0, my, 0, 0),
FPlane(ma, mb, mc, me),
FPlane(0, 0, md, 0));
// Invert Z-axis (UE uses Z-inverted LHS)
static const UE::Math::TMatrix<T> FlipZ = UE::Math::TMatrix<T>(
FPlane(1, 0, 0, 0),
FPlane(0, 1, 0, 0),
FPlane(0, 0, -1, 0),
FPlane(0, 0, 1, 1));
return ProjectionMatrix * FlipZ;
}
Based on the comments, it would be capable of handling both my need at the same time using an easy toggle for the hard / infinite far clip plane.
Are you familiar with this code addition ? At first sight, this seems consistent with the CameraStackTypes code lines you first pointed me to.
Thanks,
Basile
[Attachment Removed]