**Vulkan perspective projection matrix** 🏠 [Home]("https://blog.linearconstraints.net") ✉ ounanding@gmail.com 📅 Sun Dec 19 02:13:24 PM PST 2021
$$ \newcommand{\mx}[1]{\begin{pmatrix} #1 \end{pmatrix}} \newcommand{\gp}[1]{\left( #1 \right)} \newcommand{\abs}[1]{\left| #1 \right|} \newcommand{\norm}[1]{\left\lVert #1 \right\rVert} \newcommand{\cp}[1]{{#1^\times}} \DeclareMathOperator{\tr}{tr} \renewcommand{\AA}{\mathbf{A}} \newcommand{\BB}{\mathbf{B}} \newcommand{\CC}{\mathbf{C}} \newcommand{\EE}{\mathbf{E}} \newcommand{\FF}{\mathbf{F}} \newcommand{\HH}{\mathbf{H}} \newcommand{\II}{\mathbf{I}} \newcommand{\KK}{\mathbf{K}} \newcommand{\LL}{\mathbf{L}} \newcommand{\MM}{\mathbf{M}} \newcommand{\NN}{\mathbf{N}} \newcommand{\OO}{\mathbf{O}} \newcommand{\PP}{\mathbf{P}} \newcommand{\QQ}{\mathbf{Q}} \newcommand{\RR}{\mathbf{R}} \renewcommand{\SS}{\mathbf{S}} \newcommand{\TT}{\mathbf{T}} \renewcommand{\TT}{\mathbf{T}} \newcommand{\UU}{\mathbf{U}} \newcommand{\VV}{\mathbf{V}} \newcommand{\WW}{\mathbf{W}} \newcommand{\XX}{\mathbf{X}} \renewcommand{\aa}{\mathbf{a}} \newcommand{\bb}{\mathbf{b}} \newcommand{\cc}{\mathbf{c}} \newcommand{\dd}{\mathbf{d}} \newcommand{\ee}{\mathbf{e}} \newcommand{\ff}{\mathbf{f}} \renewcommand{\gg}{\mathbf{g}} \newcommand{\jj}{\mathbf{j}} \newcommand{\mm}{\mathbf{m}} \newcommand{\nn}{\mathbf{n}} \newcommand{\pp}{\mathbf{p}} \newcommand{\qq}{\mathbf{q}} \newcommand{\rr}{\mathbf{r}} \renewcommand{\tt}{\mathbf{t}} \newcommand{\uu}{\mathbf{u}} \newcommand{\vv}{\mathbf{v}} \newcommand{\ww}{\mathbf{w}} \newcommand{\xx}{\mathbf{x}} \newcommand{\yy}{\mathbf{y}} \newcommand{\zz}{\mathbf{z}} \newcommand{\ttau}{\boldsymbol{\tau}} \newcommand{\eye}{\boldsymbol{\delta}} $$
Vulkan uses a different NDC than OpenGL. Y axis is downward and Z is mapped to $[0,1]$. I would like to preserve the convention in shaders and only encode those differences in the projection transform. ~~~~ restart; n00:=; n10:=; n11:=; n01:=; m00:=n*<-1,1,0,1>; m10:=n*<1,1,0,1>; m11:=n*<1,-1,0,1>; m01:=n*<-1,-1,0,1>; h:=f/n; f00:=; f10:=; f11:=; f01:=; g00:=f*<-1,1,1,1>; g10:=f*<1,1,1,1>; g11:=f*<1,-1,1,1>; g01:=f*<-1,-1,1,1>; P:=Matrix(4,4,(i,j)->p||i||j); E1:=[seq(seq(op(convert(P.n||i||j-m||i||j,list)),i=0..1),j=0..1)]; E2:=[seq(seq(op(convert(P.f||i||j-g||i||j,list)),i=0..1),j=0..1)]; s:=eliminate([op(E1),op(E2)],indets(P)); M:=subs(s[1],P); s1:=eliminate([op(E1),op(E2),t=-b,t=tan(q/2)*n,r=-l,r=k*t],indets(P) union {t,b,r,l}); M1:=subs(s1[1],P); ~~~~