2

我有 3 种不同的 xna 效果,一种称为初始化,一种称为迭代,一种称为终结。

Initialise 不接受纹理输入,并渲染到 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 个迭代像素着色器,其中一个从前 3 个寄存器读取,写入最后 3 个寄存器,另一个从最后 3 个并写入前 3 个?

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

请注意,我可以单独优化着色器中的代码,如果需要,我会提出单独的问题。

4

1 回答 1

0

正如文档所述:

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

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

然而,好消息是我很确定,在 Windows 上,更改纹理和渲染目标是一项相对便宜的操作。您可能想弄乱RenderTargetUsage(可能设置PreserveContents)只创建一个表面。(我不完全确定 XNA 4.0 做了什么,因为该行为仅记录在早期版本中,并且可能已经更改;您可以尝试使用 PIX 找出答案)。

另一方面,Xbox 360 则是另一回事

于 2011-03-31T13:39:25.153 回答