我想知道,如果我使用着色器渲染场景,并传入一个纹理,而该纹理也恰好是该场景的渲染目标,是否会导致任何不需要的行为?

所以基本上:

texture t;

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

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

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

device->EndScene();

这究竟会导致什么?

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

有帮助吗?

解决方案

我假设您正在谈论 DirectX9。该文档没有提及任何有关此特定情况的内容,但我可以告诉您以下内容:

我只是假设最终的更改不会写入纹理,直到调用 device->End

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

在实践中:

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

所以,假设DX9没有抱怨(如果你真的想知道的话可以尝试一下,我不再做DX9了),它 将要 未定义。

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

如果当前还绑定了任何子资源键入读取或写作(也许在管道的不同部分),则这些绑定点将被删除,以防止同一子资源在单个渲染操作中同时读取和书写。

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

其他提示

虽然我不能指出具体细节,但我很确定它是未定义的行为。图形卡用于着色片段的方法可以变化(一次做不同的量等),但在任何实际情况下,它一次做多个片段。这意味着您将同时阅读和写入相同的位置,从而导致竞争条件。我不认为这是推荐的。

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

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

正如其他人所说......这是非常不明确的行为。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top