游戏使用软件渲染在内存中绘制全屏调色板(8 位)图像。
使用 Direct3D 将该图像放在屏幕上的最快方法是什么?
目前我在软件中将调色图像转换为 RGB,然后将其放在D3DUSAGE_DYNAMIC
纹理上(用 锁定D3DLOCK_DISCARD
)。
有更快的方法吗?例如,使用着色器执行调色?
相关问题:
- 使用 OpenGL 快速调色屏幕 blit - 与 OpenGL 相同的问题
- 如何提高 Direct3D 流式处理纹理性能?- SDL作者的类似问题
游戏使用软件渲染在内存中绘制全屏调色板(8 位)图像。
使用 Direct3D 将该图像放在屏幕上的最快方法是什么?
目前我在软件中将调色图像转换为 RGB,然后将其放在D3DUSAGE_DYNAMIC
纹理上(用 锁定D3DLOCK_DISCARD
)。
有更快的方法吗?例如,使用着色器执行调色?
相关问题:
创建D3DFMT_L8
包含调色板图像的纹理和包含调色板的 256x1D3DFMT_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 ...
您可以编写一个简单的像素着色器来处理调色板。创建 L8 动态纹理并将调色板图像复制到其中并创建调色板查找纹理(或常量内存中的颜色数组)。然后只需渲染一个全屏四边形,将调色图像设置为纹理和一个像素着色器,从查找纹理或常量缓冲区执行调色板查找。
也就是说,在 CPU 上执行调色板转换在现代 CPU 上应该不会很昂贵。你确定这是你的性能瓶颈吗?