shaderdirectxdirect3d9

How to read depth texture in DirectX 9 pixel shader?


I can use DirectX 9 and asm only. If I use following vertex shader:

struct VS_INPUT
{
    float4 pos : POSITION;
    float2 t0 : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4  pos : POSITION;
    float4  t0 : TEXCOORD0;
};

VS_OUTPUT main(const VS_INPUT v)
{
    VS_OUTPUT o;

    o.pos=v.pos;
    o.t0=float4(v.t0.x, v.t0.y, 0, 1);

    return o;
}

and pixel shader:

ps.1.4

texld r0, t0

I get white rectangle. If I start to play with third component of t0 (for example I set it to 0.5), I get something that close to correct depth map.

How to do this in right way? I can not find any documentation about t0 with 4 components and how it works with depth texture.


Solution

  • It looks like there is no way to read from depth texture. If you read with texld instruction from texture with format D3DFMT_D16 and usage D3DUSAGE_DEPTHSTENCIL then, in fact, you do shadow test.

    This is the reason why third component of address vector affects sampling result. NVIDIA developers portal says:

    If an extra coordinate compared to the texture dimensionality is present it is used to perform a shadow comparison. The value used in the shadow comparison is always the last component of the coordinate vector.

    So when we use address with four components, we do shadow test against third component and we get 0 or 1. The only way I found so far is to sample several times to get closer to depth value:

    struct VS_OUTPUT
    {
        float4 pos : POSITION;
        float2 t0 : TEXCOORD0;
    };
    
    texture DepthTexture;
    sampler2D DepthSampler = sampler_state
    {
        Texture = (DepthTexture);
        MinFilter = Linear;
        MagFilter = Linear;
        MipFilter = Linear;
        AddressU  = Clamp;
        AddressV  = Clamp;
    };
    
    int NumberOfSteps = 10;
    
    float4 main(VS_OUTPUT In) : COLOR
    {
        float4 r = 0;
        float depth = 0;
        float stepWeight = 1.0 / NumberOfSteps;
        for (int i = 0; i < NumberOfSteps; i++)
        {
            r += tex2Dproj(DepthSampler, float4(In.t0.x, In.t0.y, depth, 1.0)) * stepWeight;
            depth += stepWeight;
        }
        return r;
    }