【问题标题】:Is it possible to render a scene to multiple textures in a single pass with Xna?是否可以使用 Xna 一次将场景渲染到多个纹理?
【发布时间】:2010-08-02 07:15:42
【问题描述】:

我想知道是否可以一次将一个场景渲染到多个渲染目标(或者比通过客户端代码多次绘制它更快)。我想优化一些代码,这些代码被渲染为几个不同尺寸的纹理(例如,512 x 512、256 x 256、128 x 128 和 64 x 64)。

我意识到我可以使用从原始目标派生的 mip 贴图,但我不想混合颜色。我怀疑 mip 映射将从几个纹素中取平均值,但出于我的目的,我只想要未经修饰的渲染,就像显卡渲染的那样。如果 mipmap 有任何设置允许这样做,那么它作为一个可行的解决方案也是相当可观的。

顺便说一句,有谁知道 mipmap 是在 CPU 还是 GPU 上生成的?

感谢阅读。

【问题讨论】:

    标签: optimization xna 3d render-to-texture


    【解决方案1】:

    您的问题没有可能的解决方案。 MRT 不能使用不同的分辨率。 Mipmaping 无法生成看起来与原始纹理完全相同的较小纹理。实际上,绝对没有办法做到这一点。使用新显卡时,mipmap 会在 GPU 上生成。 一个问题:为什么要渲染到方形目标?

    【讨论】:

    • 方形目标是示例,我只是为了说明我想要不同的尺寸。实际上,在我的情况下,我希望每个纹理的大小是前任的一半,而前任应该能够具有任何宽度和高度。
    【解决方案2】:

    正如 Quang Anh 所说 - 没有办法完全按照您的要求去做。那么你到底想达到什么目的呢?

    如果您担心缩小 mipmap 时发生的混合,为什么不使用您的渲染目标,并使用 point sampling 将它(在“全屏”四边形上)渲染到另一个渲染目标? (并为您想要的每个尺寸重复此操作。)


    添加了以下 cmets:

    如果您正在做的事情涉及深度(或类似于深度的数据),并且您需要知道每个像素的最大(或最小)深度,并且每次都将图像的分辨率减半:

    您可以通过使用点采样将一个渲染目标渲染到另一个渲染目标来使用相同的缩放技术(如我在上面的原始答案中所述)。并且在像素着色器中对将成为输出图像中的一个像素的四个像素进行采样。只需从四个像素中选择最大(或最小)值的像素作为输出。

    (我将把排列样本所需的数学作为练习。)

    【讨论】:

    • 我发现了一个利用原语生成剔除数据的优化理论概念。纹理颜色值代表数据,我希望剔除数据以不同的细节进行光栅化,同时保留光栅化器的输出。也就是说,如果我将 2 x 2 纹理缩小为 1 x 1 纹理,如果 2 x 2 包含数据,我应该将 1 x 1 纹理集与数据一起设置。我猜这就是 mipmap 成为问题的地方,因为 mipmap 混合了颜色。为此,颜色不得混合。它们必须像渲染到 1×1 纹理一样返回。
    • 这应该适用于任何可变大小的纹理,而不仅仅是 2x2 和 1x1(因此示例为 512x512 和 256x256)。我想那么解决方案是根据纹理大小多次渲染帧。
    • @Statement:基本上你需要多次渲染场景以获得像素精确的结果。点采样将防止您获得不在原始图像中的值之间的值 - 但结果不一定与光栅化器输出的像素精确......现在,话虽如此 - 如果您的技术基于深度(或其他一些值太大或太小的值仍然可以),那么我的技术可以适应 - 请参阅我对答案所做的补充。
    • 不,它不是基于深度。起初我试图避免“中间”(插值)值,但开始更多地考虑这个问题,我可能真的想要它们。所以我想我无论如何都希望生成mip图。基本思想是在输出纹理中只存储一个标志,类似于模板贴图。如果较小的纹理有任何“可见标记”纹素,则该纹素必须扩展以确定整个块是否通过另一个渲染通道可见,并且具有较大的纹理以放大“可见标记”。
    • 由于渲染是光栅化的,我想我可以保证子采样区域的任何超级采样都包含任何进一步的“可见标志”。请注意,这些并不意味着一个对象占据了整个区域,只是表明它可能会这样做,并且该区域中至少有一个对象覆盖了屏幕空间。
    最近更新 更多