在像素着色器中设置纹理并使其成为渲染目标?
我想知道,如果我使用着色器渲染场景,并传入一个纹理,而该纹理也恰好是该场景的渲染目标,是否会导致任何不需要的行为?
基本上:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我假设您正在谈论 DirectX9。该文档没有提及任何有关此特定情况的内容,但我可以告诉您以下内容:
这是一个错误的假设。想想看,您假设您绘制的所有三角形的所有像素都将存储在“某处”,并且执行所有纹理提取,而不会将任何像素写回渲染目标。这需要任意数量的内存,因此是不可能的。
在实践中:
所以,假设 DX9 不会抱怨(如果你真的想知道,请尝试一下,我不再做DX9了),它将是未定义的。
也就是说,DirectX10对此更加明确(来源):
因此,在 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:
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:
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):
So, in DirectX10, your texture setting will be removed by the API.
虽然我不能指出具体细节,但我很确定这是未定义的行为。显卡用于着色片段的方法可能会有所不同(一次处理不同的数量等),但在任何实际情况下,它一次都会处理多个片段。这意味着您将读取和写入相同的位置,从而导致竞争条件。我认为不推荐。
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.
调试运行时将阻止您执行此操作并提供警告。发布运行时“可能”(但可能不会)工作。
问题来自于从纹理加载像素和使用像素之间存在相当大的延迟。通过将纹理像素块加载到缓存中可以解决此问题。写入会被缓冲并直接写入内存。因此,您可能最终会遇到一个问题,即读取可能已更新的纹素,但缓存将过期。如果您只读取正在写入的纹理元素,“可能”可以工作,但实际上此类实现细节留给了 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.