Clear["Global`*"]

(* Reverse-Z projection *)
rp={{p/a,0,0,0},{0,p,0,0},{0,0,n/(n-f),-n*f/(n-f)},{0,0,1,0}};
rp//MatrixForm

(* Inverse projection *)
ip=Inverse[rp];
ip// MatrixForm

(* Inverse projection [infinite far plane] *)
iip=Limit[ip,f->Infinity];
iip// MatrixForm

(* Z from W *)
zw[w_]=(w*n/(n-f)-n*f/(n-f))/w

Solve[z==((-((f n)/(-f+n))+((n w)/(-f+n)))/w),w]

(* W from Z *)
wz[z_]=1/(z*(f-n)/(f*n)+(1/f))

(* W from Z [infinite far plane] *)
wiz[z_]=Limit[wz[z],f->Infinity]

zw[n]//FullSimplify

wz[1]//FullSimplify

zw[f]

wz[0]

(* Depth encoding parameters *)
n=1/10;
f=10000;

(* W [meters] as a function of Z *)
Plot[wz[z],{z,0,1},PlotRange->Full,AxesLabel->{z,w}]
LogPlot[wz[z],{z,0,1},PlotRange->Full,AxesLabel->{z,w}]

(* Fixed-point number encoding parameters *)
k=24;

(* Unsigned normalized (fixed-point) number from the decimal interpretation of its binary representation *)
ud[d_]:=d/(2^k-1)

(* W [meters] as a function of the decimal interpretation of the binary representation of a fixed-point value of Z *)
LogPlot[wz[ud[d]],{d,0,2^k-1},PlotRange->Full,AxesLabel->{d,w}]

Solve[wz[ud[d]]==1,d]

N[(18639485865/11111)/(2^k-1)]

N[Abs[D[wz[ud[x]],x]]/.x->d]

(* Resolution of W [meters/decimal] as a function of the decimal interpretation of the binary representation of a fixed-point value of Z *)
LogPlot[Evaluate[Abs[D[wz[ud[x]],x]]/.x->d],{d,0,2^k-1},PlotRange->Full,AxesLabel->{d,Δw}]

(* Resolution of W [meters/decimal] as a function of W (still using fixed-point) *)
ListLogPlot[ParallelTable[{wz[ud[d]],Evaluate[Abs[D[wz[ud[x]],x]]/.x->d]},{d,0,2^k-1,1}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{w,Δw}]

(* Floating-point number encoding parameters *)
k=32;(* 1+w+t *)
t=23;
b=127;
dfone=1065353216;
dfmin=8388608;
dfmax=2139095039;

N[(dfone-dfmin+1)/2^32]

N[(dfone-dfmin+1)/2^24]

(* Sign (±1) from the decimal interpretation of the binary representation of a normalized floating-point number *)
sd[d_]:=1-2*Floor[d*(2^(1-k))]

(* Biased exponent from the decimal interpretation of the binary representation of a normalized floating-point number *)
ed[d_]:=Floor[d*(2^(-t))]-(2^(k-t-1))*Floor[d*(2^(1-k))]

(* Trailing significand from the decimal interpretation of the binary representation of a normalized floating-point number *)
td[d_]:=Sum[(Floor[d*(2^(-i))]-2*Floor[d*(2^(-i-1))])*2^(i-t),{i,0,t-1}]

(* Normalized floating-point number from the decimal interpretation of its binary representation *)
fd[d_]:=sd[d]*(1+td[d])*2^(ed[d]-b)

fd[dfone](* 1.0f *)

fmin=N[fd[dfmin]](* FLT_MIN *)

fmax=N[fd[dfmax]](* FLT_MAX *)

(* Plot the floats on a linear scale as a function of the decimal interpretation of the binary representation *)
ListPlot[ParallelTable[{d,fd[d]},{d,dfmin,dfone,2^14}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,ϕ}]
ListPlot[ParallelTable[{d,fd[d]},{d,dfone-3*2^23,dfone,2^8}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,ϕ}]
Plot[fd[d],{d,dfone-16,dfone},PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,ϕ}]

(* W [meters] as a function of the decimal interpretation of the binary representation of a normalized floating-point value of Z *)
ListPlot[ParallelTable[{d,wz[fd[d]]},{d,dfmin,dfone,2^14}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,w}]
ListLogPlot[ParallelTable[{d,wz[fd[d]]},{d,dfmin,dfone,2^14}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,w}]

N[fd[7*10^8]]

N[wz[fd[7*10^8]],8]

(* Resolution of W [meters/decimal] as a function of the decimal view of the binary representation of a normalized floating-point value of Z *)
ListLogPlot[ParallelTable[{d,Abs[wz[fd[d+1]]-wz[fd[d-1]]]/2},{d,dfmin+1,dfone-1,2^14}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,Δw}]
ListPlot[ParallelTable[{d,Abs[wz[fd[d+1]]-wz[fd[d-1]]]/2},{d,dfone-3*2^23+1,dfone-1,2^8}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{d,Δw}]

(* Resolution of W [meters/decimal] as a function of W (still using floating-point) *)
ListLogPlot[ParallelTable[{wz[fd[d]],Abs[wz[fd[d+1]]-wz[fd[d-1]]]/2},{d,dfmin+1,dfone-1,2^10}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{w,Δw}]

(* Resolution of W [meters/decimal] as a function of W (still using floating-point) [reduced range of 'd'] *)
ListLogPlot[ParallelTable[{wz[fd[d]],Abs[wz[fd[d+1]]-wz[fd[d-1]]]/2},{d,9*10^8,dfone-1,2^10}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{w,Δw}]

(* Resolution of W [meters/decimal] as a function of W (still using floating-point) [reduced range of 'd', infinite far plane] *)
ListLogPlot[ParallelTable[{wiz[fd[d]],Abs[wiz[fd[d+1]]-wiz[fd[d-1]]]/2},{d,9267/1000*10^8,dfone-1,2^10}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{w,Δw}]
Show[ListLogPlot[ParallelTable[{wiz[fd[d]],Abs[wiz[fd[d+1]]-wiz[fd[d-1]]]/2},{d,9267/1000*10^8,dfone-1,2^10}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{w,Δw}],ListLogPlot[ParallelTable[{wz[fd[d]],Abs[wz[fd[d+1]]-wz[fd[d-1]]]/2},{d,9*10^8,dfone-1,2^10}],PlotRange->Full,PlotStyle->Green,AxesLabel->{w,Δw}]]

(* Resolution of W [meters/decimal] as a function of W (still using floating-point) [infinite far plane] *)
ListLogLogPlot[ParallelTable[{wiz[fd[d]],Abs[wiz[fd[d+1]]-wiz[fd[d-1]]]/2},{d,dfmin+1,dfone-1,2^14}],PlotRange->Full,PlotStyle->Thick,AxesLabel->{w,Δw}]

(* Fixed-point logarithmic depth buffer *)
m=32;
wld[d_]=n*Exp[(d/(2^m-1))*Log[f/n]]
f=10^37;

(* Resolution of W [meters/decimal] [infinite far plane vs logarithmic depth] *)Show[ListLogLogPlot[ParallelTable[{wiz[fd[d]],Abs[wiz[fd[d+1]]-wiz[fd[d-1]]]/2},{d,dfmin+1,dfone-1,2^14}],PlotRange->Full,PlotStyle->Blue,AxesLabel->{w,Δw}],ListLogLogPlot[ParallelTable[{wld[d],Abs[wld[d+1]-wld[d-1]]/2},{d,0,2^k-1,2^16}],PlotRange->Full,PlotStyle->Red,AxesLabel->{w,Δw}]]

(* Resolution of W [meters/decimal] [reduced range of 'd', infinite far plane vs logarithmic depth] *)Show[ListLogPlot[ParallelTable[{wiz[fd[d]],Abs[wiz[fd[d+1]]-wiz[fd[d-1]]]/2},{d,9267/1000*10^8,dfone-1,2^14}],PlotRange->Full,PlotStyle->Blue,AxesLabel->{w,Δw}],ListLogPlot[ParallelTable[{wld[d],Abs[wld[d+1]-wld[d-1]]/2},{d,0,9267/1000*10^8,2^14}],PlotRange->Full,PlotStyle->Red,AxesLabel->{w,Δw}]]