【问题标题】:Setting a texture in a pixel shader and making it the render target?在像素着色器中设置纹理并使其成为渲染目标?
【发布时间】:2009-10-25 05:38:19
【问题描述】:

我想知道,如果我使用着色器渲染场景,我将纹理传递给该纹理,该纹理也恰好是该场景的渲染目标,它会导致任何不需要的行为吗?

所以基本上:

texture t;

shader->SetTexture("texture",t);

device->SetRenderTarget( 0, t->surface );

shader->Begin("effect")
// do some more shader stuff

device->EndScene();

这究竟会导致什么?

如果我在渲染之前不清除渲染目标,纹理仍然可以正常工作吗?我只是假设在调用 device->End 之前,最终的更改不会写入纹理?

【问题讨论】:

    标签: directx shader render-to-texture


    【解决方案1】:

    我假设您说的是 DirectX9。文档没有说明这个具体案例,但我可以告诉你以下内容:

    我只是假设在调用 device->End 之前,最终的更改不会写入纹理中

    这是一个错误的假设。想一想,您假设您绘制的所有三角形的所有像素都将存储在“某处”,并且您的所有纹理提取都将执行,而没有任何像素被写回渲染目标。这需要任意数量的内存,因此是不可能的。

    在实践中:

    • 硬件通常会在三角形出现时处理它们,同时处理多个
    • 它会在需要时更新帧缓冲区(在您的情况下是纹理内存支持),假设不会出现竞争条件

    所以,假设 DX9 没有抱怨(如果你真的想知道,试试吧,我不再做 DX9),它是未定义的。

    也就是说,DirectX10 对此更加明确 (source):

    如果当前也有任何子资源 读或写(也许 在管道的不同部分), 那些绑定点将被 NULL'ed out 防止相同的子资源 被同时读取和写入 在单个渲染操作中。

    因此,在 DirectX10 中,您的纹理设置将被 API 删除。

    【讨论】:

      【解决方案2】:

      虽然我无法指出具体细节,但我很确定这是未定义的行为。显卡用于着色片段的方法可能会有所不同(一次处理不同的数量等),但在任何实际情况下,它一次处理多个片段。这意味着您将同时读取和写入相同的位置,从而导致竞争条件。我觉得不推荐。

      【讨论】:

        【解决方案3】:

        调试运行时会阻止您执行此操作并提供警告。发布运行时“可能”(但可能不会)工作。

        问题来自这样一个事实,即从纹理加载像素和使用它之间存在相当大的延迟。这是通过将一块纹素加载到缓存中来解决的。写入被缓冲并直接写入内存。因此,您可能最终会遇到一个问题,即读取可能已经更新但缓存已过期的纹素。如果您只阅读正在写入它的纹素“可能”工作,但实际上这些实现细节留给 IHV。他们没有义务允许它工作。

        正如其他人所说...这是非常未定义的行为。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-17
          • 2019-06-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多