Directx Direct3D9-访问像素着色器中的深度/模具缓冲区(并可能将其复制到其他纹理)

Directx Direct3D9-访问像素着色器中的深度/模具缓冲区(并可能将其复制到其他纹理),directx,directx-9,Directx,Directx 9,编辑:无法复制D24S8纹理。时期但是,有时可以将深度缓冲区格式更改为INTZ,这是一种特殊的FOURCC格式,具有相同的布局,但可以设置为纹理采样器的输入 最后,我的方法是使用代理dll截获所有纹理创建调用,以便在给定D24S8的位置更改格式。然后,我可以将该纹理绑定到像素着色器的纹理采样器,设置一个R32F渲染目标,并将采样值(两个基本体的三角形条上的DrawPrimitive)写入该目标 开发人员通常已经在D3D9中使用了R32F纹理来存储深度值,并避免了D3D9深度/模具问题。在这种情况

编辑:无法复制D24S8纹理。时期但是,有时可以将深度缓冲区格式更改为INTZ,这是一种特殊的FOURCC格式,具有相同的布局,但可以设置为纹理采样器的输入

最后,我的方法是使用代理dll截获所有纹理创建调用,以便在给定D24S8的位置更改格式。然后,我可以将该纹理绑定到像素着色器的纹理采样器,设置一个R32F渲染目标,并将采样值(两个基本体的三角形条上的DrawPrimitive)写入该目标

开发人员通常已经在D3D9中使用了R32F纹理来存储深度值,并避免了D3D9深度/模具问题。在这种情况下,如果需要访问,可以直接将该纹理复制到系统内存中


原职:

我正在开发一个激光雷达传感器插件,该插件与一个名为VBS的模拟环境一起使用,在新帧渲染到后缓冲区后调用该环境。它有两个IDirect3DSurface9*类型的输入参数,一个用于渲染目标(格式为X8R8G8B8),另一个用于深度缓冲区(格式为D24S8)

目前,我正试图以某种方式提取每个像素相对于相机的位置。 因为我需要使用游戏API来检索计算投影矩阵所需的视锥体值,所以我首先考虑将深度缓冲区值从GPU复制到系统内存。 我已经尝试过GetRenderTargetData和DXLoadSurfaceFromSurface将深度缓冲区值复制到在系统内存中创建的纹理,但这两种方法都没有成功

在[1]中,@ozeanix建议使用像素着色器并添加额外的渲染过程,以将深度值复制到具有非深度/模具格式的格式的纹理,然后“锁定”该纹理

尝试实现这种方法时,我意识到我不知道如何将深度缓冲区值传递给像素着色器。我想到的唯一方法是将深度缓冲区曲面复制到新创建的相同格式的1级纹理(然后将该纹理传递到ps着色器),但GetRenderTargetData、DXLoadSurfaceFromSurface和UpdateSurface均未成功

为了确保限制明确:我不能重复渲染调用(如我所说,我的插件只有在整个帧渲染后才会被调用),我不能更改现有着色器(因此我认为我不能启用MRT),我也不能将深度/模具输出重定向到不同的纹理(渲染目标)首先,然后将该纹理复制到最终深度缓冲区

  • 有没有办法将深度缓冲区传递给像素着色器

  • 如果我的着色器可以访问缓冲区,我应该如何执行该像素着色器?我是否必须使用“DrawPrimitive”或类似的东西(在这种情况下,我不知道哪些顶点必须设置为参数)

  • 写这篇文章时,我考虑了计算像素着色器内部的相对位置(因此在回调中设置投影矩阵,然后直接输出位置)——这可能是更好的方法吗

  • 提前谢谢


    [1]

    不幸的是,我帮不了什么忙。您遇到的问题(我并没有一直这么想)是D24S8曲面没有纹理,就我所知有限,您无法将曲面作为纹理对象附加到像素着色器中。换句话说,您需要的是
    IDirect3DTexture9*
    ,而不是
    IDirect3DSurface9*
    。问题是,要获得纹理,您需要创建一个相同大小的新纹理,然后可能使用
    StretchRectangle
    将曲面绘制到纹理的0级。尝试查看是否可以使用来获得拥有正在通过的D24S8曲面的
    IDirect3DTexture9*
    。如果可以成功获得该纹理,则可以在调用中将该纹理绑定到名称的调用中使用它。例如,如果你能做到这一点,那么你必须弄清楚如何在像素着色器中对纹理进行实际采样,这远远超出了我的理解范围——我从未尝试过从D24S8中采样,我不确定你会如何处理它。也许R、G和B通道可以解释为总共24个深度位中的8位,而alpha通道将绑定到模具缓冲区的8位?不幸的是,GetContainer方法不起作用。同时,我还多次读到,不可能将D24S8表面绑定到纹理。。。