Ссылка на видео с последовательностью действий:
Перейди в builtins, в materials:
Скопируй эти три файла в любую папку:

Зайди в компонент sprite, твоего игрового объекта и нажми на ... в поле materials:
Выбери тот материал, который ты скопировал ранее:
Теперь нажми на стрелочку:
Добавь фрагментный и вершинный шейдеры (скопированные ранее файлы с расширением .fp и .vp):
Создай константу и присвой такие значения:
Если хочешь посмотреть как будет выглядеть спрайт под шейдером, установи такое значение:
Зайди в фрагментный шейдер (sprite.fm у меня) и вставь какой-нибудь из этих блоков кода:
Красное мигание
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Красный оттенок при попадании
color = mix(color, vec4(1.0, 0.0, 0.0, color.a), 0.7);
}
gl_FragColor = color;
}
Белая вспышка
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Белая вспышка
color = mix(color, vec4(1.0, 1.0, 1.0, color.a), 0.8);
}
gl_FragColor = color;
}
Жёлтый оттенок
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Жёлтый оттенок (для критических ударов)
color = mix(color, vec4(1.0, 1.0, 0.0, color.a), 0.6);
}
gl_FragColor = color;
}
Инверсия цвета
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Инвертируем цвета
color.rgb = vec3(1.0 - color.r, 1.0 - color.g, 1.0 - color.b);
}
gl_FragColor = color;
}
Красный + яркость
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Красный + ярче
color.rgb = mix(color.rgb, vec3(1.0, 0.0, 0.0), 0.6);
color.rgb += vec3(0.3, 0.0, 0.0); // Ещё ярче красный
}
gl_FragColor = color;
}
Оттенки серого
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Преобразуем в чёрно-белое
lowp float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
color.rgb = vec3(gray, gray, gray);
}
gl_FragColor = color;
}
Чёрно-белое + контраст
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Чёрно-белое с высоким контрастом
lowp float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
gray = smoothstep(0.3, 0.7, gray); // Увеличиваем контраст
color.rgb = vec3(gray, gray, gray);
}
gl_FragColor = color;
}
Полностью чёрный
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Полностью чёрный
color.rgb = vec3(0.0, 0.0, 0.0);
}
gl_FragColor = color;
}
Полностью белый
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Полностью белый
color.rgb = vec3(1.0, 1.0, 1.0);
}
gl_FragColor = color;
}
Негатив
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Чёрно-белое + инвертировано
lowp float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
gray = 1.0 - gray; // Инвертируем
color.rgb = vec3(gray, gray, gray);
}
gl_FragColor = color;
}
Мягкий зелёный (Исцеление)
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Мягкий зелёный оттенок
color = mix(color, vec4(0.0, 1.0, 0.0, color.a), 0.5);
}
gl_FragColor = color;
}
Яркий зелёный (Токсин/Яд)
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Яркий зелёный + свечение
color.rgb += vec3(0.0, 0.5, 0.0);
color = mix(color, vec4(0.0, 1.0, 0.0, color.a), 0.4);
}
gl_FragColor = color;
}
Лайм-зелёный (Эффект энергии)
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Лайм-зелёный (очень яркий)
color = mix(color, vec4(0.5, 1.0, 0.0, color.a), 0.6);
}
gl_FragColor = color;
}
Тёмно-зелёный (отравление)
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Тёмно-зелёный
color = mix(color, vec4(0.0, 0.5, 0.0, color.a), 0.7);
}
gl_FragColor = color;
}
Зелёный + свечение
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Зелёный с ярким свечением
color.rgb = color.rgb * vec3(0.7, 1.2, 0.7);
color = mix(color, vec4(0.0, 1.0, 0.0, color.a), 0.3);
}
gl_FragColor = color;
}
Простая радуга по позиции:
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Радуга на основе UV координат
lowp float r = sin(var_texcoord0.x * 3.14159 * 6.0) * 0.5 + 0.5;
lowp float g = sin(var_texcoord0.x * 3.14159 * 6.0 + 2.0) * 0.5 + 0.5;
lowp float b = sin(var_texcoord0.x * 3.14159 * 6.0 + 4.0) * 0.5 + 0.5;
lowp vec3 rainbow = vec3(r, g, b);
color = mix(color, vec4(rainbow, color.a), 0.7);
}
gl_FragColor = color;
}
Циклическая радуга:
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
uniform lowp float tint;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Радуга через HSV в RGB
lowp float hue = mod(tint + var_texcoord0.x, 1.0);
lowp vec3 rgb = vec3(0.0);
if(hue < 0.167) rgb = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), hue / 0.167);
else if(hue < 0.333) rgb = mix(vec3(1.0, 1.0, 0.0), vec3(0.0, 1.0, 0.0), (hue - 0.167) / 0.166);
else if(hue < 0.5) rgb = mix(vec3(0.0, 1.0, 0.0), vec3(0.0, 1.0, 1.0), (hue - 0.333) / 0.167);
else if(hue < 0.667) rgb = mix(vec3(0.0, 1.0, 1.0), vec3(0.0, 0.0, 1.0), (hue - 0.5) / 0.167);
else if(hue < 0.833) rgb = mix(vec3(0.0, 0.0, 1.0), vec3(1.0, 0.0, 1.0), (hue - 0.667) / 0.166);
else rgb = mix(vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), (hue - 0.833) / 0.167);
color = mix(color, vec4(rgb, color.a), 0.6);
}
gl_FragColor = color;
}
Пасхальная радуга (Мягкая):
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Мягкая радуга (пастельные цвета)
lowp float r = 0.5 + 0.5 * sin(var_texcoord0.x * 10.0);
lowp float g = 0.5 + 0.5 * sin(var_texcoord0.x * 10.0 + 2.1);
lowp float b = 0.5 + 0.5 * sin(var_texcoord0.x * 10.0 + 4.2);
lowp vec3 rainbow = vec3(r, g, b);
color = mix(color, vec4(rainbow, color.a), 0.5);
}
gl_FragColor = color;
}
Неоновая радуга:
varying mediump vec2 var_texcoord0;
uniform lowp sampler2D texture_sampler;
uniform lowp vec4 hit_effect;
void main()
{
lowp vec4 color = texture2D(texture_sampler, var_texcoord0.xy);
if(color.a > 0.0 && hit_effect.r > 0.5)
{
// Неоновая радуга (очень яркая)
lowp float x = var_texcoord0.x;
lowp vec3 rainbow = vec3(
0.5 + 0.5 * sin(x * 6.28 + 0.0),
0.5 + 0.5 * sin(x * 6.28 + 2.1),
0.5 + 0.5 * sin(x * 6.28 + 4.2)
);
color.rgb = rainbow;
}
gl_FragColor = color;
}
Установите значения константы hit_effect в начальное значение:
Я решил использовать шейдер в момент обработки сообщения:
elseif message_id == hash("set_damage") then
self.hp = self.hp - message.damage
go.set("#sprite", "hit_effect", vmath.vector4(1, 0, 0, 1))
if self.hp <= 0 then
print("Враг умер:", self.instance_id, "спавн:", self.spawn_id)
msg.post("/spawner", "killed_enemy", {
instance_id = self.instance_id,
spawn_id = self.spawn_id
})
GSFSM.set_exp_player(1)
msg.post("/gui", "pick_exp")
end
Вот эта строка применяет эффект:
go.set("#sprite", "hit_effect", vmath.vector4(1, 0, 0, 1))























