As described in 'T45409: Incorrect Z values when using Z pass' the behavior of the internal Blender render engine and the Cycles renderer are different. The Z buffer should store the Z component of the original point to be projected as the name suggests and not the distance to the camera center. The internal render engine does this:
--- source / blender / render / intern / source / rendercore.c --- 457 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr) .... 469 case SCE_PASS_Z: 470 fp= rpass->rect + offset; 471 *fp= shr->z; ... --- end ---
As seen in the previous snippet only the Z component is used as a result. This behavior is identical to what OpenGL for example does (see https://www.opengl.org/wiki/Depth_Test and https://www.opengl.org/wiki/Vertex_Post-Processing#Viewport_transform ).
The cycles render engine instead calculates the distance of the projected point the camera center:
--- src / kernel / kernel_passes.h --
63 ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L,
64 ShaderData *sd, int sample, ccl_addr_space PathState *state, float3 throughput)
...
84 if(flag & PASS_DEPTH) {
85 float depth = camera_distance(kg, ccl_fetch(sd, P));
86 kernel_write_pass_float(buffer + kernel_data.film.pass_depth, sample, depth);
...
--- end ---For compatibility reasons to the internal engine, OpenGL and the definition of the Z-Buffer the behavior should be changed. It leads to severe issues for compositing making use of the Z buffer values when the engine is switched especially when a wide angle focal length is used. Further a simple inversion of the projection using the camera intrinsic parameters and the Z buffer is not possible anymore.
Regards
Philipp