Я работаю над 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-подобной замены палитры!