Reversed-Z and infinite zFar in projections

Reversed-Z and infinite zFar are techniques that increases the precision of a projection matrix and helps with z-fighting. Both are described in this article.

Do you think this should be implemented? Should I open two separate issues?

Those are indeed important as well, and was surprised the C++ glm didn’t fully implement them.

Infinite reversed z projection matrix is really the only perspective projection matrix one ever needs to use, and also turns out to be the simplest ones :slight_smile:

I implemented them fairly recently here for the engine that we are building here at Embark (we are using nalgebra-glm) and been meaning to do a PR to have them integrated but haven’t had the time. Here is the code for them.

/// Build infinite perspective projection matrix with [0,1] depth range.
pub fn perspective_infinite(aspect_ratio: f32, fov_y: f32, z_near: f32) -> glm::Mat4 {
    let f = 1.0 / (0.5 * fov_y).tan();
    let mut mat = glm::Mat4::zeros();
    mat[(0, 0)] = f / aspect_ratio;
    mat[(1, 1)] = f;
    mat[(2, 2)] = -1.0;
    mat[(2, 3)] = -z_near;
    mat[(3, 2)] = -1.0;
    mat
}

/// Build infinite reverse perspective projection matrix with [0,1] depth range.
pub fn perspective_infinite_reverse(aspect_ratio: f32, fov_y: f32, z_near: f32) -> glm::Mat4 {
    let f = 1.0 / (0.5 * fov_y).tan();
    let mut mat = glm::Mat4::zeros();
    mat[(0, 0)] = f / aspect_ratio;
    mat[(1, 1)] = f;
    mat[(2, 3)] = z_near;
    mat[(3, 2)] = -1.0;
    mat
}

For integration into nalgebra one should suffix the functions with _rh_zo as they are right handed and [0,1] depth range.

That’s interesting! I implemented some of the variants for nalgebra-glm into that PR: https://github.com/rustsim/nalgebra/pull/574. I reused some of the code you posted here if that’s OK with you @repi!

1 Like

Great, and yeah perfectly fine to use the code I posted, that was the intent! :slight_smile: