In some occasions a linear depth texture is preferred over the usual non-linear depth buffer (z-buffer). The linearized depth could for example be used when doing SSAO or depth of field. Rendering linear z-buffers is very easy and only the following lines of code is required ( a float texture should be set as render target):
Vertex shader:
varying float depth;
void main()
{
vec4 viewPos = gl_ModelViewMatrix * gl_Vertex; // this will transform the vertex into eyespace
depth = -viewPos.z; // minus because in OpenGL we are looking in the negative z-direction
gl_Position = ftransform();
} |
Fragment shader:
varying float depth;
void main()
{
gl_FragColor.r = depth;
} |
You might want to scale the depth in the vertex shader to a more appropriate range as the the distance will otherwise be the same as the distance from the camera to the vertex. The following vertex shader will map the near and far distances to 0..1 which is often a good idea.
varying float depth;
void main()
{
vec4 viewPos = gl_ModelViewMatrix * gl_Vertex; // this will transform the vertex into eyespace
depth = (-viewPos.z-near)/(far-near); // will map near..far to 0..1
gl_Position = ftransform();
} |
Here’s how the shader looks like if you render a cube.
Link to a page about the depth buffer in DirectX
http://www.mvps.org/directx/articles/linear_z/linearz.htm
A good introduction to the depth buffer in OpenGL
http://www.sjbaker.org/steve/omniv/love_your_z_buffer.html