在像素着色器中设置纹理并使其成为渲染目标?

发布于 2024-08-08 16:05:10 字数 375 浏览 5 评论 0原文

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

基本上:

texture t;

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

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

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

device->EndScene();

这到底会导致什么?

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

I was wondering, if I render a scene using a shader to which I pass in a texture that also happens to be the render target for that scene will it cause any unwanted behaviour?

So basically:

texture t;

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

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

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

device->EndScene();

what will this cause exactly?

If I don't clear the render target before rendering will the texture still work all the same? I just assume the final changes don't get written into the texture until device->End is called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

策马西风 2024-08-15 16:05:10

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

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

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

在实践中:

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

所以,假设 DX9 不会抱怨(如果你真的想知道,请尝试一下,我不再做DX9了),它是未定义的。

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

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

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

I assume you're talking about DirectX9. The documentation does not say anything about this specific case, but I can tell you the following:

I just assume the final changes don't get written into the texture until device->End is called

This is a wrong assumption. Think about it, you're assuming all the pixels of all the triangles you draw will be stored 'somewhere' and all your texture fetches executed without any pixels being written back to the render target. This requires an arbitrary amount of memory and is therefore not possible.

In practice:

  • the hardware usually processes triangles as they come, many at once
  • it updates the frame buffer (which in your case is the texture memory backing) when it wants, assuming there can't be race conditions

So, assuming DX9 does not complain (try it if you really want to know, I don't do DX9 anymore), it will be undefined.

That said, DirectX10 is being more explicit about it (source):

If any subresources are also currently
bound for reading or writing (perhaps
in a different part of the pipeline),
those bind points will be NULL'ed out
to prevent the same subresource from
being read and written simultaneously
in a single rendering operation.

So, in DirectX10, your texture setting will be removed by the API.

梦年海沫深 2024-08-15 16:05:10

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

Though I can't point out specifics, I'm pretty sure it's undefined behavior. The method a graphics card uses for shading fragments can vary (do different amounts at a time, etc), but in any practical case, it does more than one fragment at a time. This means you'll be both reading and writing to the same locations, causing race conditions. I don't think it's recommended.

雨后咖啡店 2024-08-15 16:05:10

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

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

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

The debug runtime will prevent you doing this and provide a warning. The release runtime "might" (but probably won't) work.

The problem comes form the fact that there is quite a delay between loading the pixel from a texture and it being used. This is fixed by loading a block of texels into a cache. The writes are buffered and written straight to memory. Thus you will likely end up with a problem that may be reading a texel that may already have been updated but the cache will be out of date. If you are ONLY reading the texel that is being written to it "may" work but realistically such implementation details are left to the IHVs. They are under no obligation to allow this to work.

As said by others ... it is very much undefined behaviour.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文