“I wasn’t trying to reinvent the wheel. I was just trying to roll it my way.”
So I was sitting with my notebook, trying to understand how the orthographic projection matrix works. I knew that it was just a mapping to NDC
I had seen the matrix in OpenGL docs a multiple dozen times:
| 2/(R-L) 0 0 -(R+L)/(R-L) |
| 0 2/(T-B) 0 -(T+B)/(T-B) |
| 0 0 -2/(F-N) -(F+N)/(F-N) |
| 0 0 0 1 |
But instead of just copying it blindly, I wanted to feel where it comes from. So I thought:
“Let me just map near and far (N and F) to -1 and 1… that should work.”
So here’s what I tried:
- I wanted the near plane
N
to go to-1
, and the far planeF
to go to+1
. - To do that, I:
- Added half the range:
(F - N)/2
- Subtracted
F
- Divided by
(F - N)/2
- Added half the range:
Let’s verify with our example values:
- For
z = 2
(near):- Add half range:
2 + 2 = 4
- Subtract F:
4 - 6 = -2
- Divide:
-2 / 2 = -1
✅
- Add half range:
- For
z = 6
(far):- Add half range:
6 + 2 = 8
- Subtract F:
8 - 6 = 2
- Divide:
2 / 2 = 1
✅
- Add half range:
On paper it looked like this:
For mapping a value z
from [N, F]
to [-1, 1]
:
if you expand this even further:
\[z_{ndc} = \frac{2}{F - N} * z - \frac{(F + N)}{(F - N)}\]Then I realized…
Wait — this is exactly what that orthographic matrix is doing, just written in matrix form so the GPU can crunch it in real-time.
Here’s How You Actually Derive the Z-Mapping Row
Let’s say you want f(z)
to map:
N → -1
F → +1
So:
\[f(z) = Az + B\]Solve two equations:
-1 = A*N + B
1 = A*F + B
Subtract to eliminate B:
\[2 = A*(F - N) \Rightarrow A = \frac{2}{F - N}\]Plug back in to find B:
\[B = -1 - A*N = -\frac{F + N}{F - N}\]Boom:
\[z_{ndc} = \frac{2}{F - N} * z - \frac{F + N}{F - N}\]Which matches the orthographic matrix’s Z-row.
Final Thoughts
Sometimes, detours make the best lessons.
I just wanted to understand what the heck it was doing.
Stay curious. Keep breaking things.
Even projection matrices. 😄