优化具有多个纹理的绘图立方体

Optimizing drawing cube with multiple textures

我正在尝试优化绘制具有 3 种不同纹理的立方体。我要实现的一个效果是:

我现在正在做的是使用三个 Draw() 调用绘制立方体:

            graphicsDevice.Textures[0] = cube.frontTexture;
            graphicsDevice
                .DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
                    36, 0, 2);

            graphicsDevice.Textures[0] = cube.backTexture;
            graphicsDevice
                .DrawIndexedPrimitives(PrimitiveType.TriangleList, 6, 0,
                    30, 0, 2);

            graphicsDevice.Textures[0] = cube.sideTexture;
            graphicsDevice
                .DrawIndexedPrimitives(PrimitiveType.TriangleList, 12, 0,
                    24, 0, 8);

然后我的纹理在像素着色器中处理我对我的纹理进行采样:

texture Texture;
sampler textureSampler  : register(s0) = sampler_state {
    Texture = (Texture);
    Filter = MIN_MAG_MIP_POINT;
    AddressU = Wrap;
    AddressV = Wrap;
};

并产生输出:

return tex2D(textureSampler, texCoord);    // I have my texCoords from vertex shader output

不幸的是,在我的场景中有数百个具有不同纹理的相似立方体以及其他对象,这对 FPS 率有不良影响。我注意到我可以在我的像素着色器中采样不止一种纹理:

        graphicsDevice.Textures[0] = cube.frontTexture;
        graphicsDevice.Textures[1] = cube.backTexture;
        graphicsDevice.Textures[2] = cube.sideTexture;

我能否以某种方式将每个纹理粘贴到我的像素着色器中长方体的正确面上,以便在一次 Draw() 调用中绘制它?我使用 Silverlight 5.0,但任何关于 XNA 或 MonoGames 的答案都将不胜感激:)

您可以将构成 3 个纹理的所有 3 个位图添加到 一个大位图 。结果将是一个大纹理纹理图集。然后你只需将每个面的 UV 设置到大纹理的适当部分。

这样一来,绑定的纹理永远只有一个,无需执行昂贵的纹理上下文切换。

这是一种常见的做法。 sprite sheets.

也很受欢迎

正如@Micky 所说,使用 sprite 表而不是数千个单独的纹理是一种很好的做法。在我的例子中,我想在文件系统中有单独的纹理,但游戏中的纹理很少,所以我写了特殊的 class 来在大精灵表中组成小纹理并重新计算纹理坐标。

代码比较多,最好提供一个link to sources

游戏开始时纹理打包。如果您不介意几秒钟的处理,您可以将它用于您的精灵。