我正在开发类似Megaman的游戏,需要在运行时更改某些像素的颜色。供参考:在Megaman中,当您更改所选武器时,主角色的调色板会更改以反映所选武器。并非所有精灵的颜色都会改变,只有某些会改变。
由于程序员可以访问调色板以及像素和调色板索引之间的逻辑映射,因此这种效果在NES上很常见并且很容易实现。但是,在现代硬件上,这更具挑战性,因为调色板的概念并不相同。
我所有的纹理都是32位的,并且不使用调色板。
我知道有两种方法可以达到我想要的效果,但是我很好奇是否有更好的方法可以轻松实现此效果。我知道的两个选项是:
- 使用着色器并编写一些GLSL来执行“调色板交换”行为。
- 如果着色器不可用(例如,因为图形卡不支持着色器),则可以克隆“原始”纹理并生成具有预先应用的颜色更改的不同版本。
理想情况下,我想使用着色器,因为它看起来很简单,并且与重复纹理方法相反,几乎不需要其他工作。我担心复制纹理只是为了更改颜色而浪费了VRAM,我不应该为此担心吗?
编辑:我最终使用了可接受的答案的技术,这是我的着色器供参考。
uniform sampler2D texture;
uniform sampler2D colorTable;
uniform float paletteIndex;
void main()
{
vec2 pos = gl_TexCoord[0].xy;
vec4 color = texture2D(texture, pos);
vec2 index = vec2(color.r + paletteIndex, 0);
vec4 indexedColor = texture2D(colorTable, index);
gl_FragColor = indexedColor;
}
两种纹理都是32位的,一种纹理用作查找表,其中包含多个大小相同的调色板(在我的情况下为6种颜色)。我将源像素的红色通道用作颜色表的索引。这就像实现类似于Megaman的调色板交换一样具有魅力!