Please refer to piegames answer. PNG is perfectly fine for a "transport" data format. You can even use PNG and push a full 32bit raw into each pixel, then in your shader or depth system unpack the RGB/A into the original depth value.
Im not sure why @user1853 is pushing EXR, this is not used very heavily for depth maps in my experience. EXR is not a great transport format for games, simulations and many other systems. You often need to "touch up" depth maps and having an easily editable format is often very handy. EXR is often _over_kill_ for scenes. I have seen EXR used for textures with depth maps incorporated into the Alpha component, but you can do this in PNG, and other formats.
Additionally, depth maps when used in render systems are rarely linear. Nearly all depth map rendering software uses some form of logarithmic format - high detail near camera, low detail far away. This is very common. So consider a depth map specific format.
The OP solution is also fine. What you are missing is that you have packed your data into a 16bit (65535 max) data range, so it is quite correct ;)
Divide by your data size to get the correct depth 0..1 value.
For example: [3100,65000] == [0.0473, 0.9918]
Also remember that will be scaled by far-near: 10m - 1cm = 99cm
To be clear this means [0.0473, 0.9918] represents 99cm.
Hope this helps.
-- Some notes to above. Clarity here is important, and I think some information is being very muddled.
- There is no "perfect" graphics data transport system It depends heavily on your use case, and even EXR cannot guarantee replication (has a number of different representation systems within the format)
https://en.wikipedia.org/wiki/OpenEXR
Dont be fooled into the concept of a "file format" that will rid you of precision errors - that is just not true. Source data may be in 32bit or float 32bit.. which is very innaccruate if you are doing 200Km train sim scenes :)
- PNGs are fine for Z depth. Even JPEGS can be used (have done so on many web projects to minimise size constraints). It all depends on your use case.
Generally these days, depth buffers are not even put into files (its kind of a waste of time). Render the object in the target render system and capture the buffer and use it there.
Formats Ive used in production of games, sims and other:
PNG, TGA, PPM, RAW, JPEG, even BMP :)
- Depth Maps are subjective. They depend on the following important factors:
- Target use case - is it a single object, or a whole scene, or a combination? Consider in engine rendering if you need high accuracy.
- Data complexity. If you have only a simple plane or cube, then a high quality depth map is obviously not needed. High frequency surfaces are very hard to capture in a depth map, and I wouldn't recommend it.
- Combining sources. Often you want to use a Depth Map, but then layer in a Normal, Tangent and Bitangent setup so you can have properly detailed surfaces. Depth Maps alone are usually not very useful.
- Alternatives - As mentioned, in-render depth maps, a voxel format (these are much more compact and just as accurate), or a simple raw data format (floating point or 32bit/64bit etc data stream).