Я працюю над грою на 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 кольорів). Я використовую червоний канал вихідного пікселя як індекс до таблиці кольорів. Це спрацювало як шарм для досягнення мегаманської заміни палітри!