Jump to content
  • Advertisement
Sign in to follow this  
Medo Mex

Getting Pixel Depth

This topic is 1746 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Advertisement

You render depth into texture (or to depth stencil that can be read as textures but it is vendor specific), so for examaple you could use MRT to do this in one pass:

 

1. Create MRTs (check all functions for failure, i didn't do that for readability) :

d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
D3DFORMAT fmt = D3DFMT_A32B32G32R32F;
device->CreateTexture(SIZE_X, SIZE_Y, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &DepthTex, NULL); // use for depth/position
DepthTex->GetSurfaceLevel(0, &DepthSurface);
if(caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS) // if device supports independent bit depth for each RT you can save some space
{
            fmt = D3DFMT_A8R8G8B8;
}
device->CreateTexture(SIZE_X, SIZE_Y, 1, D3DUSAGE_RENDERTARGET, fmt D3DPOOL_DEFAULT, &ColorTex, NULL); // use for color/diffuse
ColorTex->GetSurfaceLevel(0, &ColorSurface);

 

2. While rendering:

void DrawAll()
{
...
IDirect3DSurface9*  oldBB; // "old" backbuffer surface
device->GetRenderTarget(0, &oldBB); // store it, increments ref count
 
device->SetRenderTarger(0, DepthSurface);
device->SetRenderTarger(1, ColorSurface);
 
DrawStuff();
 
device->SetRenderTarger(0, oldBB);
device->SetRenderTarger(1, NULL);
oldBB->Release(); // decrement ref count
 
... // here you must use above color and depth to draw to backbuffer
 

}

 

3. In DrawStuff you'll have shader something like this:

...
struct VS_OUTPUT
{
    float4 Position : POSITION;
    float3 DepthWorldPos : TEXCOORD0;
    float2 TexCoord : TEXCOORD1;
    ...// and rest of the stuff you need
}
void VertexProgram(...)
{
    OUT.Position = mul( IN.Position, WorldViewProj );
    // let say we want to store world space xyz position
    // i wrote this because there is multiple ways/spaces to store "depth", and you must choose what is what you want
   OUT.DepthWorldPos = mul( IN.Position, World ).xyz;
    OUT.TexCoord = IN.TexCoord;
}
 
struct PS_OUTPUT
{
    float4 DepthPos : COLOR0; // first render target
    float4 Color : COLOR1; // second render target
};
 
void PixelProgram(...)
{
   float4 diffuse = tex2D( diffuseSamp, IN.TexCoord );
   ...// rest of the stuff you need
 
    OUT.DepthPos = float4(IN.DepthWorldPos.xyz, 1.0f);
    OUT.Color = diffuse;
}

 

and now you have it.

Share this post


Link to post
Share on other sites

No, I meant the depth of the particles, not the depth of the entire scene.

 

How do I get the depth of the particles in my Particles Pixel Shader?

Share this post


Link to post
Share on other sites

like the depth of a pixel on a particle?

 

Well... I actually do agree with belfegor.

 

But if you don't want to write it to any texture, you can just access it in the same shader, so you could do the following:

VS
output.DepthPos.xyz = mul(float4(input.position.xyz,1), mul(worldMatrix, viewMatrix)).xyz;

PS
float pixelDepth = input.DepthPos.z; // Tada!

About this:

... not the depth of the entire scene.

 

Well you need to compare the particle depth to the scene depth at some point. biggrin.png

Edited by Migi0027

Share this post


Link to post
Share on other sites

@Migi0027: Creating INTZ depth texture fail when anti-analyzing is enabled, can I use MRT depth texture instead?

Share this post


Link to post
Share on other sites

Hodgman recommended to create INTZ depth texture and pass it to Pixel Shader:

http://www.gamedev.net/topic/641964-smoke-environment/

 

He said that MRT requires editing all our shaders, I'm not sure what editing all shaders means.

 

Creating INTZ depth texture fail when I have anti-analyzing enabled.

 

So I'm looking for alternatives for creating depth texture and at the same time having anti-analyzing enabled.

Share this post


Link to post
Share on other sites

He said that MRT requires editing all our shaders, I'm not sure what editing all shaders means.

Usually you output to one render target from pixel shader:

cpp:

device->SetRenderTarget(0, someSurface);

shader:

struct PS_OUTPUT
{
    float4 Color0 : COLOR0;
};
 
void PixelProgram( out PS_OUTPUT OUT )
{
    ...
    OUT.Color0 = ...// something
}

With MRTs (to avoid multiple passes) you can output to multiple render targets (up to 4 is maximum i think):

cpp:

device->SetRenderTarget(0, rt0Surface);
device->SetRenderTarget(1, rt1Surface);
device->SetRenderTarget(2, rt2Surface);
device->SetRenderTarget(3, rt3Surface);

shader:

struct PS_OUTPUT
{
    float4 Depth : COLOR0;
    float4 Color : COLOR1;
    float4 Normal : COLOR2;
    float4 FooBar : COLOR3;
};
 
void PixelProgram( out PS_OUTPUT OUT )
{
    ...
    OUT.Depth = ...// something
    OUT.Color = ...// something
    OUT.Normal = ...// something
    OUT.FooBar = ...// something
}

Do you get it now?

Edited by belfegor

Share this post


Link to post
Share on other sites

I actually use 5 render targets now ph34r.png I have secretly packed the depth and the view space positions into two different textures.

 

Hmm. I thought the D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT was 8, at least in mine it is. tongue.png

 

EDIT: Whoops, this is dx9...

Edited by Migi0027

Share this post


Link to post
Share on other sites

So that means I will have to return depth, color and normal with each Pixel Shader?

 

If yes, is there is anyway without that cost?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!