【问题标题】:Fast paletted screen blit with Direct3D 9使用 Direct3D 9 快速调色的屏幕 blit
【发布时间】:2012-10-30 18:06:07
【问题描述】:

游戏使用软件渲染在内存中绘制全屏调色板(8 位)图像。

使用 Direct3D 将该图像放在屏幕上的最快方法是什么?

目前我在软件中将调色板图像转换为 RGB,然后将其放在 D3DUSAGE_DYNAMIC 纹理上(使用 D3DLOCK_DISCARD 锁定)。

有没有更快的方法?例如。使用着色器进行调色?

相关问题:

【问题讨论】:

    标签: 2d direct3d palette


    【解决方案1】:

    创建一个包含调色板图像的 D3DFMT_L8 纹理和一个包含调色板的 256x1 D3DFMT_X8R8G8B8 图像。

    HLSL 着色器代码:

    uniform sampler2D image;
    uniform sampler1D palette;
    
    float4 main(in float2 coord:TEXCOORD) : COLOR
    {
        return tex1D(palette, tex2D(image, coord).r * (255./256) + (0.5/256));
    }
    

    请注意,亮度(调色板索引)是通过乘加运算调整的。这是必要的,因为调色板索引 255 被视为白色(最大亮度),当表示为浮点数时变为 1.0f。在该坐标处读取调色板纹理会导致它环绕(因为仅使用小数部分)并改为读取第一个调色板条目。

    编译:

    fxc /Tps_2_0 PaletteShader.hlsl /FhPaletteShader.h
    

    像这样使用它:

    // ... create and populate texture and paletteTexture objects ...
    d3dDevice->CreatePixelShader((DWORD*)g_ps20_main, &shader)
    // ...
    d3dDevice->SetTexture(1, paletteTexture);
    d3dDevice->SetPixelShader(shader);
    // ... draw texture to screen as textured quad as usual ...
    

    【讨论】:

      【解决方案2】:

      您可以编写一个简单的像素着色器来处理调色板。创建 L8 动态纹理并将调色板图像复制到其中并创建调色板查找纹理(或常量内存中的颜色数组)。然后只需渲染一个全屏四边形,将调色图像设置为纹理和一个像素着色器,从查找纹理或常量缓冲区执行调色板查找。

      也就是说,在 CPU 上执行调色板转换在现代 CPU 上应该不会很昂贵。您确定这是您的性能瓶颈吗?

      【讨论】:

      • 是的,我确定。与 8 位调色板 DirectDraw 相比,32 位 DirectDraw 的 CPU 使用率显着增加。我现在正在研究着色器,谢谢(试图弄清楚如何将调色板纹理绑定到采样器统一变量)。
      • 由于调色板只有 256 个条目,并且您不需要利用纹理混合或任何东西,您可以为调色板条目使用一个常量缓冲区,这在着色器上会更简单/绑定面比使用纹理(假设 D3D11)。
      • 我刚刚注意到您正在使用 D3D9,您应该仍然可以使用常量进行调色板查找,但我记得 D3D9 中像素着色器中的索引常量查找存在限制调色板纹理可能是要走的路。
      • 谢谢,一切都解决了(见下面我的回答)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-26
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多