我有3种不同的xna效果,一种叫做初始化,一种叫做迭代,一种叫做终结。
Initialise不接受纹理输入,并渲染到3个目标。 Iterate将这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个迭代像素着色器,其中一个从前3个寄存器读取,写入最后3个,另一个从最后3个读到写入第3个?
我猜测设置渲染目标和输入纹理的成本很多次,我不再需要这样做了。这会避免它吗,它会值得吗?
注意,我可以单独优化着色器中的代码,如果需要,我会问一个单独的问题。
答案 0 :(得分:0)
正如documentation所述:
在绘制时,纹理不能同时设置为渲染目标和舞台上的纹理。
基本上你正在做的事情的概念很好。有三个输入纹理和三个输出纹理,然后在每次传递时切换它们。但是你必须明确地切换它们。
然而,好消息是,我非常确定,在Windows 上,更改纹理和渲染目标是一种相对便宜的操作。你可能想要混淆RenderTargetUsage
(可能设置PreserveContents
)只创建一个表面。 (我不完全确定XNA 4.0的作用,因为在早期版本中它的行为只有documented并且它may have changed;你可能会试着找出PIX)。