2011-03-31 29 views
2

我有3种不同的xna效果,一种叫initialise,一种叫迭代,一种叫finalize。了解纹理寄存器和采样器,并考虑到了优化

初始化不需要纹理输入,并呈现为3个目标。 迭代将这3个作为纹理输入,并渲染到3个目标,迭代运行多次。 Finalize需要1个纹理输入并呈现给一个目标。

我有几个辅助类,但什么是从我的渲染循环回事低于它应该是显而易见的:

int i = 0; 

FractalInitRenderer.DefineOutputs(IterationsAndControl[i], Variables1And2[i], Variables3And4[i]); 
FractalInitRenderer.Draw(); 

for (; i < 50; i++) 
{ 
    FractalIterateRenderer.ClearInputTextures(); 
    FractalIterateRenderer.AddInput("IterationsAndControl", IterationsAndControl[i % 2]); 
    FractalIterateRenderer.AddInput("Variables1And2", Variables1And2[i % 2]); 
    FractalIterateRenderer.AddInput("Variables3And4", Variables3And4[i % 2]); 
    FractalIterateRenderer.DefineOutputs(IterationsAndControl[(i + 1) % 2], Variables1And2[(i + 1) % 2], Variables3And4[(i + 1) % 2]); 
    FractalIterateRenderer.Draw(); 
} 

FractalFinaliseRenderer.ClearInputTextures(); 
FractalFinaliseRenderer.AddInput("IterationsAndControl", IterationsAndControl[i % 2]); 
FractalFinaliseRenderer.Draw(); 

我的质地声明使用下面的宏,并沿着定义如下,我的输出结构:

#define DECLARE_TEXTURE(Name, index) \ 
    Texture2D<float4> Name : register(t##index); \ 
    sampler Name##Sampler : register(s##index); 
struct FRACTAL_OUTPUT 
{ 
    float4 IterationsAndControl : COLOR0; 
    float4 Variables1And2 : COLOR1; 
    float4 Variables3And4 : COLOR2; 
}; 

什么,我不知道是的,我可以把输入和输出呈现不同的纹理寄存器目标,那么也许跑2个迭代像素着色器交替他们阅读的F一个rom前3个寄存器,写入最后3个,其他读取最后3个,写入前3个?

我猜想,设置渲染目标和输入纹理很多次,我不再需要这样做。这会避免它,它会值得吗?

请注意,我可以在着色器内单独优化代码,如果需要,我会问一个单独的问题。

回答

0

作为documentation状态:

在绘图时,纹理不能同时设置为渲染目标和的阶段的组织。

基本上,你在做什么的概念是好的。有三个输入纹理和三个输出纹理,然后在每次通过时切换它们。但是你必须明确地切换它们。

不过,好消息是,我很确定,在Windows上,,更改纹理和渲染目标是一个相对便宜的操作。您可能想要混淆RenderTargetUsage(可能设置为PreserveContents)以仅创建单个曲面。 (我并不完全确定XNA 4.0是做什么的,因为在早期版本中它的行为只有documented,并且它的may have changed;您可以尝试使用PIX来查找)。

Xbox 360,另一方面,是a different story

+0

感谢您的答案,那里有几个有趣的链接。当然,我做事情的方式目前看起来相当标准,每次迭代都会切换渲染目标/输入纹理。然而,我试图得到的是,我可以在迭代之前将6个不同的寄存器(0,.... 5)中的所有6个纹理放在一起,然后每个迭代都有一个着色器在写入时从0,1和2读取到3,4和5.然后有第二个接近相同的着色器,写入0,1和2时从3,4,5读取。这是可能的吗?它会是值得的(因为我不会移动纹理做不同的寄存器/采样器吗? – 2011-04-01 08:38:19

+0

@George:不,这是我的观点,你*不能*设置纹理作为采样器和同时作为渲染目标。你必须取消它们以便交换它们。**一些经验法则:**复制纹理非常昂贵 - 并且如我所描述的那样在XNA中避免使用棘手的问题。[开始新的批处理是昂贵的(在CPU上)](http://gamedev.stackexchange.com/questions/8521/x/8533#8533)。更改纹理和渲染目标*价格低廉 - 除了需要一个新的批次并可能导致渲染目标的管道刷新 - 但这些成本是您即使想法奏效也不得不承担的成本。 – 2011-04-01 13:38:48

+0

啊,好吧,我想我现在明白了。感谢您解决问题并获取更多信息。 – 2011-04-01 14:53:28