编辑:D24S8纹理无法复制。期。但是,有时可以将深度缓冲区格式更改为INTZ,这是一种特殊的FOURCC格式,具有相同的布局,但可以设置为纹理采样器的输入。
最后,我的方法是使用代理dll拦截所有纹理创建调用,以便能够在给定D24S8的地方更改格式。然后,我可以将此纹理绑定到像素着色器的纹理采样器,设置R32F渲染目标并将采样值(两个基元的三角形条上的DrawPrimitive)写入此目标。
开发人员通常使用带有D3D9的R32F纹理来存储深度值并避开D3D9深度/模板问题。在这种情况下,如果需要访问,可以将此纹理直接复制到系统内存。
原帖:
我正在开发一个Lidar传感器插件,该插件与称为VBS的模拟环境一起使用,在将新帧渲染到后缓冲区后调用该插件。它有两个类型为IDirect3DSurface9 *的输入参数,一个用于渲染目标(格式为X8R8G8B8),另一个用于深度缓冲区(格式为D24S8)。
目前我试图以某种方式提取每个像素相对于相机的位置。 因为我需要使用游戏API来检索计算投影矩阵所需的平截头体值,所以我首先考虑将深度缓冲区值从GPU复制到系统内存。 我已经尝试过GetRenderTargetData和DXLoadSurfaceFromSurface将深度缓冲区值复制到系统内存中创建的纹理,但这些方法都没有成功。
在[1]中@ozeanix建议使用像素着色器并添加一个额外的渲染过程,将深度值复制到格式不是深度/模板格式的纹理,然后“LockRect”这个纹理。
尝试实现该方法我意识到我不知道如何将深度缓冲区值传递给像素着色器。我想出的唯一方法是将深度缓冲区表面复制到新创建的相同格式的1级纹理(然后将该纹理传递给ps着色器),但GetRenderTargetData和DXLoadSurfaceFromSurface以及UpdateSurface都没有成功。
只是为了确保限制是明确的:我不能重复渲染调用(正如我所说,我的插件仅在整个帧渲染后才被调用),我无法更改现有的着色器(所以我想我不能启用MRT)我也不能先将深度/模板输出重定向到不同的纹理(渲染目标),然后将此纹理复制到最终的深度缓冲区。
有什么方法可以将深度缓冲区传递给像素着色器吗?
如果我的着色器可以访问缓冲区我应该如何执行此像素着色器?我是否必须使用“DrawPrimitive”或类似的东西(在这种情况下我不知道我必须将哪些顶点设置为参数)?
写这篇文章我想到计算像素着色器内部的相对位置(所以在我的回调中设置投影矩阵,然后直接输出位置) - 这可能是更好的方法吗?
提前致谢!
[1] Copy depth buffer with non-lockable format (D24S8) to system memory with Direct3D9, Win 8.1