Shading Technique - Linear Depth Buffer

From Horde3D Wiki
Jump to: navigation, search



Why using a custom Depth buffer? The default depth buffer generated by Horde3D is a non-linear depth buffer and it is relative to the "Z Far" and the "Z Near" parameter. If you need to create screen space shader like "Depth of field" and "Screen Space Ambien Occlusion", a non-linear depth buffer could cause some problems since you will need to linearize the depth buffer each frames and any changement to the Z far and the Z near could affect any shaders using the Depth Buffer.

- Basic knowledge of the Horde3D pipeline system.

The shader

Vertex shader: Here, you can change the max distance constant. It determine the range and the precision of the depth buffer.

As you can see, there is two ways to calculate the depth of a vertex. The first one is to take the view space position of the vertex, and with this, you can take the Z value to get the depth. The second way is to create a vector from the view position to the vertex position, wich gave a slightly different result.

Linear Depth - Vertex Shader
  1. // Viewer position
  2. uniform vec3 viewer;
  4. // Depth vertex color
  5. varying vec4 vVertexColor; // Black/near --> White/far
  7. const float MAX_DISTANCE = 1000.0;
  9. void main( void )
  10. {
  11.         // Calculate world space position
  12.         vec4 pos = calcWorldPos( gl_Vertex );
  14.         // Calculate view space position
  15.         vec4 vsPos = calcViewPos( pos );
  17.         // Calculate Depth
  18.         float distance = -vsPos.z / MAX_DISTANCE;//length( - viewer) / MAX_DISTANCE;
  20.         // Colorize the vertex with the distance
  21.         vVertexColor = vec4(distance);
  23.         gl_Position = gl_ModelViewProjectionMatrix * pos;
  24. }

Fragment shader:

Linear Depth - Fragment Shader
  1. varying vec4 vVertexColor;
  3. void main( void )
  4. {
  5.         gl_FragColor = vVertexColor;
  6. }

Pipeline integration

First of all, you need to add a buffer in the setup tag:

    <RenderTarget id="VERTDEPTHBUF" depthBuf="true" numColBufs="1" format="RGBA16F"  scale="1.0" />     

Then, you need to add the depth buffer pass:

<Stage id="VertexDepth">                
        <SwitchTarget target="VERTDEPTHBUF" />
        <ClearTarget depthBuf="true" colBuf0="true" />  
        <DrawGeometry context="DEPTH" class="~Translucent" />

With this, you only have to bind the VERTDEPTHBUF to any stage you want.

I have called the depth pass DEPTH, but you can call it whatever you want. Don't forget to put the shader pass in EACH shaders that need to be affected by the depth buffer.

How to use it

You must put the shader pass in EACH shaders that need to be affected by the depth buffer.

Example Result

To be added.



To-Do List for this Article

- Add an exemple

Technique - Linear Depth Buffer
Creating a custom linear depth buffer
Version: 1.0
Compatible with Horde3D: 1.0 beta
Release date: 2008-09-06
Author(s): Mikmacer
Personal tools