I had 2 issues in my case:
1. Large distance between nearZ
and farZ
2. I tried to use gl_FragCoord.z
which is has low precision. It was resolved with rendering to framebuffer, which is had just depth component (without color buffer!) and then render result of depth texture in second pass to another framebuffer with color renderbuffer and shader which has the same pack
function as in question.
Answer is here on OpenGL.org FAQ
12.050 Why is my depth buffer precision so poor?
The depth buffer precision in eye coordinates is strongly affected by the ratio of zFar to zNear, the zFar clipping plane, and how far an object is from the zNear clipping plane.
You need to do whatever you can to push the zNear clipping plane out and pull the zFar plane in as much as possible.
12.070 Why is there more precision at the front of the depth buffer?
After the projection matrix transforms the clip coordinates, the XYZ-vertex values are divided by their clip coordinate W value, which results in normalized device coordinates. This step is known as the perspective divide. The clip coordinate W value represents the distance from the eye. As the distance from the eye increases, 1/W approaches 0. Therefore, X/W and Y/W also approach zero, causing the rendered primitives to occupy less screen space and appear smaller. This is how computers simulate a perspective view.
As in reality, motion toward or away from the eye has a less profound effect for objects that are already in the distance. For example, if you move six inches closer to the computer screen in front of your face, it's apparent size should increase quite dramatically. On the other hand, if the computer screen were already 20 feet away from you, moving six inches closer would have little noticeable impact on its apparent size. The perspective divide takes this into account.
As part of the perspective divide, Z is also divided by W with the same results. For objects that are already close to the back of the view volume, a change in distance of one coordinate unit has less impact on Z/W than if the object is near the front of the view volume. To put it another way, an object coordinate Z unit occupies a larger slice of NDC-depth space close to the front of the view volume than it does near the back of the view volume.
In summary, the perspective divide, by its nature, causes more Z precision close to the front of the view volume than near the back.
12.080 There is no way that a standard-sized depth buffer will have enough precision for my astronomically large scene. What are my options?
The typical approach is to use a multipass technique. The application might divide the geometry database into regions that don't interfere with each other in Z. The geometry in each region is then rendered, starting at the furthest region, with a clear of the depth buffer before each region is rendered. This way the precision of the entire depth buffer is made available to each region.
lowp
andmediump
are identical on the A7 (both 16-bit). The older models hadlowp
= 12-bit andmediump
= 16-bit. – Cockleboat