Below is the functions I used to convert device depth to linear depth. I derived this code from the projection matrix.
//
Projection._34 = zn*zf/(zn-zf)
//
Projection._33 = zf/(zn-zf)
//float
A = Projection._34;
//float
B = Projection._33;
float A =
ProjectionParams.z/zf;
float B =
ProjectionParams.w;
float LInearZ
= A/(DeviceZ + B);
It did not work. when ZNear value is not small, resulting linear depth was smaller than the real linear depth.
But when I change the code like below, It worked.
//
Projection._34 = zn*zf/(zn-zf)
//
Projection._33 = zf/(zn-zf)
//float
A = Projection._34/zf;
//float
B = Projection._33;
float A =
ProjectionParams.z;
float B =
ProjectionParams.w;
float LInearZ
= A/(DeviceZ + B);
The difference is deviding by 'zf' is done in CPU code. It is exactly same as the crytek's GetLinearDepth function. I still don't know what is the cause.