microsoft / DirectXMath

DirectXMath is an all inline SIMD C++ linear algebra library for use in games and graphics apps
https://walbourn.github.io/introducing-directxmath/
MIT License
1.54k stars 236 forks source link

Add matrix functions for generating infinite reversed-z perspective projection matrix #158

Open TheRealMJP opened 1 year ago

TheRealMJP commented 1 year ago

Hello, I think it would be really great if DirectXMath added support for generating perspective projection matrices with infinite reversed-z clip planes. This style of projection matrix has become increasing popular in recent years since they result in excellent distribution of depth precision when used with floating-point depth buffers, and they effectively remove the need for having a maximum view distance. This blog post gives a good overview of why it's good and how it works, and this article has some great visualizations of why reversed-z is beneficial.

walbourn commented 1 year ago

Thanks for the feedback. It turns out you can trivially use the existing functions for reverse-z: swap the far/near values:

m_proj = XMMatrixPerspectiveFovLH(XM_PIDIV4, aspect, c_farZ, c_nearZ);

Be sure to clear the depth-buffer with 0.0 instead of 1.1, and use the reverse depth comparison operator for the Depth/Stencil state (i.e. D3Dxx_COMPARISON_GREATER_EQUAL instead of D3Dxx_COMPARISON_LESS_EQUAL).

I have support for reverse-z in the DirectX Tool Kit CommonStates.

TheRealMJP commented 1 year ago

Hey @walbourn, thank you for replying! To be clear I was specifically referring to the "infinite" variant of a reversed-z projection, which cannot be done with the existing perspective matrix functions (finite reversed projections can be done as you suggested). The infinite reversed matrix has this form for the LH variant:

xScale     0          0             0
0        yScale       0             0
0          0          0             1
0          0          znear         0
walbourn commented 1 year ago

Thanks for the clarification.

walbourn commented 7 months ago

Thank you for the suggestion. I definitely see the value in this, but I'll need a bit more time to do the full validation/verification this warrants. In the meantime, you can of course easily create your own projection matrix with existing constructors and functions.