Overview
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.
Requirements:
- 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 |
// Viewer position
uniform vec3 viewer;
// Depth vertex color
varying vec4 vVertexColor; // Black/near --> White/far
const float MAX_DISTANCE = 1000.0;
void main( void )
{
// Calculate world space position
vec4 pos = calcWorldPos( gl_Vertex );
// Calculate view space position
vec4 vsPos = calcViewPos( pos );
// Calculate Depth
float distance = -vsPos.z / MAX_DISTANCE;//length(pos.xyz - viewer) / MAX_DISTANCE;
// Colorize the vertex with the distance
vVertexColor = vec4(distance);
gl_Position = gl_ModelViewProjectionMatrix * pos;
}
|
Fragment shader:
Linear Depth - Fragment Shader |
varying vec4 vVertexColor;
void main( void )
{
gl_FragColor = vVertexColor;
}
|
Pipeline integration
First of all, you need to add a buffer in the setup tag:
<Setup>
<RenderTarget id="VERTDEPTHBUF" depthBuf="true" numColBufs="1" format="RGBA16F" scale="1.0" />
</Setup>
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" />
</Stage>
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.
Pictures
To-Do List for this Article
- Add an exemple
|