Jump to content
  • Advertisement
Sign in to follow this  
ajithk

Drawing depth buffer in pixel shader

This topic is 1064 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

Hi everyone,

I am trying to draw depth info of a scene into a texture bound as a UAV in pixel shader. I did not bind either render target or depth stencil target. Btw my shader model is 5.0

Below is the pixel shader i used (struct PS_IN not shown for simplicity )

RWTexture2D tex : register(u0)
void PS(PS_IN input)
{
if ( tex[uint(input.pos.xy)] >= input.pos.z )
tex[uint(input.pos.xy)] = input.pos.z;
}

After clearing UAV with float4(1,1,1,1) and binding UAV with OMSetRenderTargetAndUnorderedAccessViews (0,NULL,NULL,0,1,&uav_view,NULL ), I drew the scene. The program crashed promptly and I am not at all surprised :D

I have a couple of doubts.

1. Is that the correct way to use [] operator?(If it is, I have to look somewhere else for bug causing the crash) If operator [] can do both read and write, doesn't that make Load function redundant.
2. This question occurred to me while I was posting this. My UAV texture is 512x512 size. How does Direct3D know to invoke pixel shader 512*512 times. I haven't bound the render target at all. I am not sure if my question makes any sense in the first place.

Share this post


Link to post
Share on other sites
Advertisement

 

 

tex[uint(input.pos.xy)]

 

You are supposed to use two coordinates uint2(...)

 

 

 

2. This question occurred to me while I was posting this. My UAV texture is 512x512 size. How does Direct3D know to invoke pixel shader 512*512 times. I haven't bound the render target at all. I am not sure if my question makes any sense in the first place. 

 

You have to specify Viewport to let the rasterizer know for which pixels on the screen to call the pixel shader.

 

What is the format of your output resource?

Do you have debug layer enabled?

Edited by _void_

Share this post


Link to post
Share on other sites
In addition to the above answer (set the viewport!), D3D11.1 introduced the "forced sample count" rasterizer state, which lets you specify how many samples exist per viewport pixel.

The program crashed promptly and I am not at all surprised

D3D never crashes, unless you've got a bug in your own code and are passing invalid pointers into D3D. Double check that every function that can fail (e.g. ones that return HRESULT) are accompanied by error checking.

BTW, why not just use a regular depth stencil view? What's up your sleeve? :)

Share this post


Link to post
Share on other sites
@ _void_

Yeah, I replaced tex[uint(input.pos.xy)] with tex[uint2(input.pos.xy)]. The program didn't crash. Earlier I did not enable debug layer, now I did. The format for my UAV is DXGI_FORMAT_R16_UNORM if that's what you asked. I have set the viewport also btw.

Since I have no way of knowing if the contents of UAV are correct, I bound rendering target this time. It's format is DXGI_FORMAT_R8G8B8A8_UNORM. And I added the below line

return float4(tex[uint2(input.pos.xy)],tex[uint2(input.pos.xy)],tex[uint2(input.pos.xy)],tex[uint2(input.pos.xy)])

with float4 as return type and SV_Target as return semantic (Sorry for bad formatting. Ah! The misery of typing in a tab). I expected to see my scene in black and white colors. The sort of image they show to visualize the depth buffer. But I got only black(blank) screen (no white colors ;) )

@ Hodgman

For using forced sample count, I need to upgrade the driver. I will keep that on mind.

And yeah, you guessed it right. Usually I dont check for HRESULT errors but now that I am getting more and more involved with this, I will.

I am writing depth in pixel shader just to learn using UAVs. But now that you asked, I came to think of it :). For point lights we need 6 depth maps. Instancing geometry shaders 6 times with six different matrices and rendering depth in pixel to an array of Texture2Ds with array index as SV_GSInstanceID will give me 6 depth maps in a single pass. Not sure of performance though.

Share this post


Link to post
Share on other sites

 

 

But I got only black(blank) screen (no white colors ;) )

Which color do you clear your RTV?

 

Your geometry could be clipped (as it is not inside the clipping volume) or culled away. As a result pixel shader is never invoked.

if your pixel shader does this only line of code return float4(1, 0, 0, 1); Do you get anything red on the screen?

Share this post


Link to post
Share on other sites
I use black color to clear my RTV. When I return float4(1,0,0,1) the whole screen is red.

Btw, my scene is a room with a chair, bed, table and a lamp. I have a first person camera working. I noticed something here. I replaced the return statement with this
return float4(input.pos.z,input.pos.z,input.pos.z,input.pos.z). The whole screen is white. As i remember the scene, I walked to my lamp and chair. As I approached these, I can see a faint grey outline of lamp, chair etc. The more nearer I approach them the more greyish they appear. Even walls appear greyish when I walk to them.

Share this post


Link to post
Share on other sites

That's the normal behavior of  a visualized depth buffer. The values are distributed hyperbolically, so more values are near 1 (white). If you want better visualization, transform them back to linear depth.
 
PS: Save yourself some typing: return float4(input.pos.z,input.pos.z,input.pos.z,input.pos.z) is equivalent to return input.pos.zzzz wink.png

 

Edit: Waaaaait, is that SV_Position ? I don't even know what z means here, never checked myself and the docs are enigmatic. But the effect you're describing sounds like the depth value. Could be worse though, if it's e.g. view space z grey might be even rarer (z can go higher than 1 and will be clamped to one).

Edited by unbird

Share this post


Link to post
Share on other sites
My pixel shader is writing to render target but not to UAV. Actually it's not even reading from UAV. Since I clear UAV with float(1.0f) it should atleast show white screen if I return float4(tex1[uint2(input.pos.xy)],....) . I bound it to slot 1 since now I have render target. Not sure how to proceed with further debugging.

Share this post


Link to post
Share on other sites
Actually I can't and I don't know how to. That's why I am returning contents of UAV to render target to see it on screen. I just

return float4(tex1[uint2(input.pos.xy)],tex1[uint2(input.pos.xy)],tex1[uint2(input.pos.xy)],tex1[uint2(input.pos.xy)]);

to SV_Target in my pixel shader. Why? Won't this work?

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!