[DX10] pixel-precise picking (reading Z values) [Yes, again!]

Started by
19 comments, last by ET3D 13 years, 10 months ago
Hi, I've been coming back and forth from the forums through the years, since the inception of DX10, which marked my final choice to move on from OpenGL. I've discussed the matters in several threads but still I couldn't get a straightforward technique about this... simply put: I am trying to pick a full x,y,z point from a rendered scene, using DX10. It's something that was fairly easy in OpenGL by unprojecting the x,y mouse pickpoint and then reading the final z value. Nonetheless, I am still failing to accomplish the same apparently simple task in DX10. Is there anyone perhaps that worked on this previously? Any hints? Thanks in advance andrea
..so we ate rare animals, we spent the night eating rare animals..
Advertisement
There's a picking example included the DirectX SDK that uses D3D10, it uses the ID3DX10Mesh::Intersect function.
Quote:Original post by majek
There's a picking example included the DirectX SDK that uses D3D10, it uses the ID3DX10Mesh::Intersect function.


Indeed... but that has nothing to do with my request :)
..so we ate rare animals, we spent the night eating rare animals..
Quote:Original post by resle
It's something that was fairly easy in OpenGL by unprojecting the x,y mouse pickpoint and then reading the final z value.


By that, do you mean sampling a value from the z-buffer?

Quote:Original post by MJP
Quote:Original post by resle
It's something that was fairly easy in OpenGL by unprojecting the x,y mouse pickpoint and then reading the final z value.


By that, do you mean sampling a value from the z-buffer?


Yes exactly: sampling a value from the z-buffer at given x,y coords, just after the whole frame has been rendered.

..so we ate rare animals, we spent the night eating rare animals..
http://www.gamedev.net/community/forums/topic.asp?topic_id=568139

There's a brief discussion of it here. I believe it's a lot more complex than it used to be with OpenGL :(.
I haven't done this myself, but I believe the best way to do this with D3D10 is to create a Texture2D resource with D3D10_USAGE_STAGING that has the same dimensions and format as your depth-stencil buffer. Then you use ID3D10Device::CopyResource to copy the data from your actual depth-stencil buffer to your staging resource, and you can then use ITexture2D::Map() to read the data.

You'll want to be careful though if performance is a concern, since doing a CopyResource to CPU memory will cause a stall to ensure that the GPU processes all pending commands before the data is copied. You can avoid this by double or triple-buffering your buffer so that you're not copying from a resource that is currently being used by the GPU.
It would be better to use CopySubresourceRegion to copy just the relevant pixel. Moves a lot less data to the PC side. However, copying depth this way is only supported on DX10.1 and higher.
Thanks Matt, thanks ET3D, and... yes Burnhard, it's a lot more complex than OpenGL's way. I wonder if doing that stalled GL drivers too or the architecture is completely different.

I will try with copying the... 1-pixel subregion I need, although I remember trying the whole staging/copy/subcopy one year or so ago without succeeding. Maybe I should try it under DX 10.1 rather than 10
..so we ate rare animals, we spent the night eating rare animals..
Quote:Original post by resle
Thanks Matt, thanks ET3D, and... yes Burnhard, it's a lot more complex than OpenGL's way. I wonder if doing that stalled GL drivers too or the architecture is completely different.

I will try with copying the... 1-pixel subregion I need, although I remember trying the whole staging/copy/subcopy one year or so ago without succeeding. Maybe I should try it under DX 10.1 rather than 10


I'd imagine that it did cause a stall...the problem is a consequence of the way the CPU and GPU work (asynchronously), and isn't caused by anything specific to D3D.

If you don't need to be very precise about your depth value, what you could do is shoot off a series of occlusion queries at increasing depths. That would only give you a range of possible depth values, but I'm not sure if that would be sufficient for your purposes.

This topic is closed to new replies.

Advertisement